Module: sems Branch: master Commit: 88789eb12461f0247754f0ef968e32f3b59175ce URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=88789eb12461f0247754f0ef968e32f3b59175ce
Author: Stefan Sayer <[email protected]> Committer: Stefan Sayer <[email protected]> Date: Mon Nov 22 13:26:05 2010 +0100 transparent 100rel mode for SBC app - add reliable_1xx REL100_IGNORED, where all rel100 stuff is ignored - set B2B sessions as reliable_1xx=REL100_IGNORED - translate RAck Cseq - for this: adds rack_method and rack_cseq to sip request (should possibly be reworked to use some dynamic field) - relay Rseq (if exist) --- apps/sbc/SBC.cpp | 7 ++++--- core/AmB2BSession.cpp | 36 ++++++++++++++++++++++++++++++++++-- core/AmSipDialog.cpp | 12 ++++++++++++ core/AmSipDialog.h | 2 ++ core/AmSipMsg.h | 3 +++ core/SipCtrlInterface.cpp | 5 ++++- doc/Readme.sbc.txt | 7 +++++++ 7 files changed, 66 insertions(+), 6 deletions(-) diff --git a/apps/sbc/SBC.cpp b/apps/sbc/SBC.cpp index 0c66bb4..5e87416 100644 --- a/apps/sbc/SBC.cpp +++ b/apps/sbc/SBC.cpp @@ -25,8 +25,6 @@ /* SBC - feature-wishlist - -- SDP filter (reconstructed SDP) - accounting (MySQL DB, cassandra DB) - RTP forwarding mode (bridging) - RTP transcoding mode (bridging) @@ -166,6 +164,7 @@ SBCDialog::SBCDialog(const SBCCallProfile& call_profile) // AmDynInvoke* user_ti call_profile(call_profile) { set_sip_relay_only(false); + dlg.reliable_1xx = REL100_IGNORED; } @@ -680,7 +679,9 @@ SBCCalleeSession::SBCCalleeSession(const AmB2BCallerSession* caller, const SBCCallProfile& call_profile) : auth(NULL), call_profile(call_profile), - AmB2BCalleeSession(caller) { + AmB2BCalleeSession(caller) +{ + dlg.reliable_1xx = REL100_IGNORED; } SBCCalleeSession::~SBCCalleeSession() { diff --git a/core/AmB2BSession.cpp b/core/AmB2BSession.cpp index ec23ac7..5dc926c 100644 --- a/core/AmB2BSession.cpp +++ b/core/AmB2BSession.cpp @@ -29,6 +29,7 @@ #include "AmConfig.h" #include "ampi/MonitoringAPI.h" #include "AmSipHeaders.h" +#include "AmUtils.h" #include <assert.h> @@ -381,7 +382,29 @@ void AmB2BSession::relaySip(const AmSipRequest& req) { if (req.method != "ACK") { relayed_req[dlg.cseq] = AmSipTransaction(req.method,req.cseq,req.tt); - dlg.sendRequest(req.method,req.content_type, req.body, req.hdrs, SIP_FLAGS_VERBATIM); + + const string* hdrs = &req.hdrs; + string m_hdrs; + + // translate RAck for PRACK + if (req.method == SIP_METH_PRACK && req.rseq) { + TransMap::iterator t; + for (t=relayed_req.begin(); t != relayed_req.end(); t++) { + if (t->second.cseq == req.rack_cseq) { + m_hdrs = req.hdrs + + SIP_HDR_COLSP(SIP_HDR_RACK) + int2str(req.rseq) + + " " + int2str(t->first) + " " + req.rack_method + CRLF; + hdrs = &m_hdrs; + break; + } + } + if (t==relayed_req.end()) { + WARN("Transaction with CSeq %d not found for translating RAck cseq\n", + req.rack_cseq); + } + } + + dlg.sendRequest(req.method, req.content_type, req.body, *hdrs, SIP_FLAGS_VERBATIM); // todo: relay error event back if sending fails if ((req.method == SIP_METH_INVITE || @@ -419,9 +442,18 @@ void AmB2BSession::relaySip(const AmSipRequest& req) void AmB2BSession::relaySip(const AmSipRequest& orig, const AmSipReply& reply) { + const string* hdrs = &reply.hdrs; + string m_hdrs; + + if (reply.rseq != 0) { + m_hdrs = reply.hdrs + + SIP_HDR_COLSP(SIP_HDR_RSEQ) + int2str(reply.rseq) + CRLF; + hdrs = &m_hdrs; + } + dlg.reply(orig,reply.code,reply.reason, reply.content_type, - reply.body,reply.hdrs,SIP_FLAGS_VERBATIM); + reply.body, *hdrs,SIP_FLAGS_VERBATIM); if ((orig.method == SIP_METH_INVITE || orig.method == SIP_METH_UPDATE) && diff --git a/core/AmSipDialog.cpp b/core/AmSipDialog.cpp index b0226b1..cf163c8 100644 --- a/core/AmSipDialog.cpp +++ b/core/AmSipDialog.cpp @@ -140,6 +140,9 @@ void AmSipDialog::updateStatus(const AmSipRequest& req) int AmSipDialog::rel100OnRequestIn(const AmSipRequest& req) { + if (reliable_1xx == REL100_IGNORED) + return 1; + /* activate the 100rel, if needed */ if (req.method == SIP_METH_INVITE) { switch(reliable_1xx) { @@ -373,6 +376,9 @@ void AmSipDialog::updateStatus(const AmSipReply& reply) int AmSipDialog::rel100OnReplyIn(const AmSipReply &reply) { + if (reliable_1xx == REL100_IGNORED) + return 1; + if (status!=Pending && status!=Connected) return 1; @@ -450,6 +456,9 @@ void AmSipDialog::uasTimeout(AmSipTimeoutEvent* to_ev) void AmSipDialog::rel100OnTimeout(const AmSipRequest &req, const AmSipReply &rpl) { + if (reliable_1xx == REL100_IGNORED) + return; + INFO("reply <%s> timed out (not PRACKed).\n", rpl.print().c_str()); if (100 < rpl.code && rpl.code < 200 && reliable_1xx == REL100_REQUIRE && rseq == rpl.rseq && rpl.method == SIP_METH_INVITE) { @@ -551,6 +560,9 @@ int AmSipDialog::reply(const AmSipRequest& req, void AmSipDialog::rel100OnReplyOut(const AmSipRequest &req, unsigned int code, string &hdrs) { + if (reliable_1xx == REL100_IGNORED) + return; + if (req.method == SIP_METH_INVITE) { if (100 < code && code < 200) { switch (reliable_1xx) { diff --git a/core/AmSipDialog.h b/core/AmSipDialog.h index db05754..c741f21 100644 --- a/core/AmSipDialog.h +++ b/core/AmSipDialog.h @@ -186,6 +186,8 @@ class AmSipDialog REL100_REQUIRE, //REL100_PREFERED, //TODO #define REL100_REQUIRE AmSipDialog::REL100_REQUIRE + REL100_IGNORED, +#define REL100_IGNORED AmSipDialog::REL100_IGNORED REL100_MAX #define REL100_MAX AmSipDialog::REL100_MAX }; diff --git a/core/AmSipMsg.h b/core/AmSipMsg.h index 95a9077..f1f8d80 100644 --- a/core/AmSipMsg.h +++ b/core/AmSipMsg.h @@ -70,6 +70,9 @@ class AmSipRequest : public _AmSipMsgInDlg string from_tag; string to_tag; + string rack_method; + unsigned int rack_cseq; + AmSipRequest() : _AmSipMsgInDlg() { } ~AmSipRequest() { } diff --git a/core/SipCtrlInterface.cpp b/core/SipCtrlInterface.cpp index c57a2c3..7f8e83c 100644 --- a/core/SipCtrlInterface.cpp +++ b/core/SipCtrlInterface.cpp @@ -436,8 +436,11 @@ inline void SipCtrlInterface::sip_msg2am_request(const sip_msg *msg, req.cseq = get_cseq(msg)->num; req.body = c2stlstr(msg->body); - if (msg->rack) + if (msg->rack) { req.rseq = get_rack(msg)->rseq; + req.rack_method = c2stlstr(get_rack(msg)->method_str); + req.rack_cseq = get_rack(msg)->cseq; + } if (msg->content_type) req.content_type = c2stlstr(msg->content_type->value); diff --git a/doc/Readme.sbc.txt b/doc/Readme.sbc.txt index 088790d..3183743 100644 --- a/doc/Readme.sbc.txt +++ b/doc/Readme.sbc.txt @@ -193,6 +193,12 @@ Warning: Changing response codes, especially between different response code classes, can seriously mess up everything. Use with caution and only if you know what you are doing! +Reliable 1xx (PRACK) +-------------------- + +Reliable 1xx (PRACK) extension (3262) is supported in a transparent mode, +i.e. the RSeq header is relayed and RAck CSeq is translated properly. + Session Timer configuration --------------------------- If SIP Session Timers are enabled for a profile, the session timers values @@ -283,3 +289,4 @@ x maximum call duration timer - fallback profile - add headers - bridging between interfaces +- rel1xx in non-transparent mode _______________________________________________ Semsdev mailing list [email protected] http://lists.iptel.org/mailman/listinfo/semsdev
