From be85aa2c1922618aa83902bc9e82e0dbb17aa52b Mon Sep 17 00:00:00 2001 From: Stefan Sayer Date: Thu, 4 Mar 2010 16:36:23 +0000 Subject: [PATCH] fixes ACK handling in B2BUA, which was broken due to moving ACK handling on user layer (sems_trunk_fix_b2b.patch) also fixes a bug in SIP stack transaction update (to-tag) git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@1650 8eb893ce-cfd4-0310-b710-fb5ebe64c474 --- core/AmB2BSession.cpp | 33 +++++++++++++++++++++++----- core/AmSipDialog.cpp | 4 ++-- core/AmSipDialog.h | 2 +- core/plug-in/sipctrl/trans_layer.cpp | 7 ++---- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/core/AmB2BSession.cpp b/core/AmB2BSession.cpp index 0f0d721a..cf821912 100644 --- a/core/AmB2BSession.cpp +++ b/core/AmB2BSession.cpp @@ -167,11 +167,15 @@ void AmB2BSession::onSipReply(const AmSipReply& reply) AmSipReply n_reply = reply; n_reply.cseq = t->second.cseq; - dlg.updateStatus(reply); + dlg.updateStatus(reply, false); relayEvent(new B2BSipReplyEvent(n_reply,true)); - if(reply.code >= 200) - relayed_req.erase(t); + if(reply.code >= 200) { + if ((reply.code < 300) && (t->second.method == "INVITE")) { + DBG("not removing relayed INVITE transaction yet...\n"); + } else + relayed_req.erase(t); + } } else { AmSession::onSipReply(reply); relayEvent(new B2BSipReplyEvent(reply,false)); @@ -219,8 +223,27 @@ void AmB2BSession::terminateOtherLeg() void AmB2BSession::relaySip(const AmSipRequest& req) { - relayed_req[dlg.cseq] = AmSipTransaction(req.method,req.cseq); - dlg.sendRequest(req.method,"application/sdp",req.body,req.hdrs,SIP_FLAGS_VERBATIM); + if (req.method != "ACK") { + relayed_req[dlg.cseq] = AmSipTransaction(req.method,req.cseq); + dlg.sendRequest(req.method,"application/sdp",req.body,req.hdrs,SIP_FLAGS_VERBATIM); + } else { + // its a (200) ACK + TransMap::iterator t = relayed_req.begin(); + + while (t != relayed_req.end()) { + if (t->second.cseq == req.cseq) + break; + t++; + } + if (t == relayed_req.end()) { + ERROR("transaction for ACK not found in relayed requests\n"); + return; + } + DBG("sending relayed ACK\n"); + dlg.send_200_ack(AmSipTransaction(t->second.method, t->first), + req.content_type, req.body, req.hdrs, SIP_FLAGS_VERBATIM); + relayed_req.erase(t); + } } void AmB2BSession::relaySip(const AmSipRequest& orig, const AmSipReply& reply) diff --git a/core/AmSipDialog.cpp b/core/AmSipDialog.cpp index d31ba26d..c4049c2c 100644 --- a/core/AmSipDialog.cpp +++ b/core/AmSipDialog.cpp @@ -185,7 +185,7 @@ int AmSipDialog::updateStatusReply(const AmSipRequest& req, unsigned int code) return 0; } -void AmSipDialog::updateStatus(const AmSipReply& reply) +void AmSipDialog::updateStatus(const AmSipReply& reply, bool do_200_ack) { TransMap::iterator t_it = uac_trans.find(reply.cseq); if(t_it == uac_trans.end()){ @@ -264,7 +264,7 @@ void AmSipDialog::updateStatus(const AmSipReply& reply) // TODO: // - place this somewhere else. // (probably in AmSession...) - if((reply.code < 300) && (t.method == "INVITE")) { + if((reply.code < 300) && (t.method == "INVITE") && do_200_ack) { send_200_ack(t); } diff --git a/core/AmSipDialog.h b/core/AmSipDialog.h index ecd69436..5eb60e57 100644 --- a/core/AmSipDialog.h +++ b/core/AmSipDialog.h @@ -149,7 +149,7 @@ class AmSipDialog string getContactHdr(); void updateStatus(const AmSipRequest& req); - void updateStatus(const AmSipReply& reply); + void updateStatus(const AmSipReply& reply, bool do_200_ack=true); /** update Status from locally originated request (e.g. INVITE) */ void updateStatusFromLocalRequest(const AmSipRequest& req); diff --git a/core/plug-in/sipctrl/trans_layer.cpp b/core/plug-in/sipctrl/trans_layer.cpp index 3ec8a71b..e6a43405 100644 --- a/core/plug-in/sipctrl/trans_layer.cpp +++ b/core/plug-in/sipctrl/trans_layer.cpp @@ -1074,14 +1074,11 @@ int trans_layer::update_uac_reply(trans_bucket* bucket, sip_trans* t, sip_msg* m t->reset_timer(STIMER_L, L_TIMER, bucket->get_id()); - if (t->to_tag.len>0) { + if (t->to_tag.len==0) { t->to_tag.s = new char[to_tag.len]; t->to_tag.len = to_tag.len; memcpy((void*)t->to_tag.s,to_tag.s,to_tag.len); - } else { - t->to_tag.s = NULL; - t->to_tag.len = 0; - } + } goto pass_reply;