diff --git a/apps/dsm/DSMCall.cpp b/apps/dsm/DSMCall.cpp index 623e459a..7c4c73a7 100644 --- a/apps/dsm/DSMCall.cpp +++ b/apps/dsm/DSMCall.cpp @@ -440,3 +440,38 @@ void DSMCall::B2BaddReceivedRequest(const AmSipRequest& req) { req.method.c_str(), req.cseq); recvd_req.insert(std::make_pair(req.cseq, req)); } + +void DSMCall::B2BsetHeaders(const string& hdr, bool replaceCRLF) { + if (!replaceCRLF) { + invite_req.hdrs = hdr; + } else { + string hdr_crlf = hdr; + DBG("hdr_crlf is '%s'\n", hdr_crlf.c_str()); + + while (true) { + size_t p = hdr_crlf.find("\\r\\n"); + if (p==string::npos) + break; + hdr_crlf.replace(p, 4, "\r\n"); + } + DBG("-> hdr_crlf is '%s'\n", hdr_crlf.c_str()); + invite_req.hdrs += hdr_crlf; + } + // add \r\n if not in header + if (invite_req.hdrs.length()>2 && + invite_req.hdrs.substr(invite_req.hdrs.length()-2) != "\r\n") + invite_req.hdrs+="\r\n"; +} + +void DSMCall::B2BaddHeader(const string& hdr) { + invite_req.hdrs +=hdr; + // add \r\n if not in header + if (invite_req.hdrs.length()>2 && + invite_req.hdrs.substr(invite_req.hdrs.length()-2) != "\r\n") + invite_req.hdrs+="\r\n"; +} + +void DSMCall::B2BclearHeaders() { + invite_req.hdrs.clear(); +} + diff --git a/apps/dsm/DSMCall.h b/apps/dsm/DSMCall.h index 6363b559..de04cf91 100644 --- a/apps/dsm/DSMCall.h +++ b/apps/dsm/DSMCall.h @@ -117,6 +117,9 @@ public: bool relayed_invite = false); void B2BaddReceivedRequest(const AmSipRequest& req); + void B2BsetHeaders(const string& hdr, bool replaceCRLF); + void B2BclearHeaders(); + void B2BaddHeader(const string& hdr); }; #endif diff --git a/apps/dsm/DSMCoreModule.cpp b/apps/dsm/DSMCoreModule.cpp index 75de8f0b..dae04975 100644 --- a/apps/dsm/DSMCoreModule.cpp +++ b/apps/dsm/DSMCoreModule.cpp @@ -99,6 +99,9 @@ DSMAction* DSMCoreModule::getAction(const string& from_str) { DEF_CMD("B2B.connectCallee", SCB2BConnectCalleeAction); DEF_CMD("B2B.terminateOtherLeg", SCB2BTerminateOtherLegAction); DEF_CMD("B2B.sendReinvite", SCB2BReinviteAction); + DEF_CMD("B2B.addHeader", SCB2BAddHeaderAction); + DEF_CMD("B2B.clearHeaders", SCB2BClearHeadersAction); + DEF_CMD("B2B.setHeaders", SCB2BSetHeadersAction); return NULL; } @@ -828,3 +831,26 @@ EXEC_ACTION_START(SCB2BReinviteAction) { bool updateSDP = par1=="true"; sess->sendReinvite(updateSDP, par2); } EXEC_ACTION_END; + +EXEC_ACTION_START(SCB2BAddHeaderAction) { + string val = resolveVars(arg, sess, sc_sess, event_params); + DBG("adding B2B header '%s'\n", val.c_str()); + sc_sess->B2BaddHeader(val); +} EXEC_ACTION_END; + +CONST_ACTION_2P(SCB2BSetHeadersAction,',', true); +EXEC_ACTION_START(SCB2BSetHeadersAction) { + string val = resolveVars(par1, sess, sc_sess, event_params); + string repl = resolveVars(par2, sess, sc_sess, event_params); + bool replace_crlf = false; + if (repl == "true") + replace_crlf = true; + DBG("setting B2B headers to '%s' (%sreplacing CRLF)\n", + val.c_str(), replace_crlf?"":"not "); + sc_sess->B2BsetHeaders(val, replace_crlf); +} EXEC_ACTION_END; + +EXEC_ACTION_START(SCB2BClearHeadersAction) { + DBG("clearing B2B headers\n"); + sc_sess->B2BclearHeaders(); +} EXEC_ACTION_END; diff --git a/apps/dsm/DSMCoreModule.h b/apps/dsm/DSMCoreModule.h index 262e6eb5..5535a7c9 100644 --- a/apps/dsm/DSMCoreModule.h +++ b/apps/dsm/DSMCoreModule.h @@ -93,6 +93,10 @@ DEF_ACTION_2P(SCB2BConnectCalleeAction); DEF_ACTION_1P(SCB2BTerminateOtherLegAction); DEF_ACTION_2P(SCB2BReinviteAction); +DEF_ACTION_1P(SCB2BAddHeaderAction); +DEF_ACTION_1P(SCB2BClearHeadersAction); +DEF_ACTION_2P(SCB2BSetHeadersAction); + class SCDIAction : public DSMAction { vector params; diff --git a/apps/dsm/DSMSession.h b/apps/dsm/DSMSession.h index 38a1b09c..c7bbf10a 100644 --- a/apps/dsm/DSMSession.h +++ b/apps/dsm/DSMSession.h @@ -98,9 +98,18 @@ class DSMSession { bool relayed_invite = false) = 0; virtual void B2BterminateOtherLeg() = 0; - /** insert reqeust in list of received ones */ + /** insert request in list of received ones */ virtual void B2BaddReceivedRequest(const AmSipRequest& req) = 0; + /** set headers of outgoing INVITE */ + virtual void B2BsetHeaders(const string& hdr, bool replaceCRLF) = 0; + + /** set headers of outgoing INVITE */ + virtual void B2BclearHeaders() = 0; + + /** add a header to the headers of outgoing INVITE */ + virtual void B2BaddHeader(const string& hdr) = 0; + /** transfer ownership of object to this session instance */ virtual void transferOwnership(DSMDisposable* d) = 0; diff --git a/apps/dsm/doc/dsm_syntax.txt b/apps/dsm/doc/dsm_syntax.txt index 9ee35390..ae26c075 100644 --- a/apps/dsm/doc/dsm_syntax.txt +++ b/apps/dsm/doc/dsm_syntax.txt @@ -97,6 +97,18 @@ core actions: generate_sdp can be 'true' or 'false' (B2B.sendReinvite(true) recommended) + B2B.clearHeaders() + clear the headers used for outgoing INVITE on B leg + + B2B.addHeader(string header) + add a header for outgoing INVITE on B leg + + B2B.setHeaders(string headers [, replace_crlf=true|false]) + set headers for outgoing INVITE on B leg + replace_crlf=true for replacing \r\n with CRLF + e.g. + B2B.setHeaders("P-One: value\r\nP-Two: anothervalue", true) + setPrompts(name) if more than one prompt sets are loaded