Module: sems Branch: master Commit: 9f51ca50d4fd1b7410add424b158ae0f5415056d URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=9f51ca50d4fd1b7410add424b158ae0f5415056d
Author: Stefan Sayer <[email protected]> Committer: Stefan Sayer <[email protected]> Date: Tue Oct 4 15:41:35 2011 +0200 sbc:cc: trying to make juha happy allows to instantiate call control based on message parts, e.g. call_control=limit_from,$H(P-CallControl),limit_to limit_from_module=cc_pcalls limit_from_uuid=$fU limit_from_max_calls=2 limit_to_module=cc_pcalls limit_to_uuid=$tU limit_to_max_calls=3 and ... INVITE sip:foo@bar SIP/2.0 P-CallControl: cc_pcalls;uuid=$rU, cc_pcalls;uuid=4321 P-CallControl: cc_call_timer;timer=25 ... --- apps/sbc/SBC.cpp | 85 +++++++++++++++++++++++++++++++++++++------ apps/sbc/SBC.h | 2 + apps/sbc/SBCCallProfile.cpp | 9 +++-- apps/sbc/SBCCallProfile.h | 7 +++- 4 files changed, 87 insertions(+), 16 deletions(-) diff --git a/apps/sbc/SBC.cpp b/apps/sbc/SBC.cpp index dd39619..2166dab 100644 --- a/apps/sbc/SBC.cpp +++ b/apps/sbc/SBC.cpp @@ -557,11 +557,38 @@ UACAuthCred* SBCDialog::getCredentials() { return &call_profile.auth_aleg_credentials; } +void SBCDialog::fixupCCInterface(const string& val, CCInterface& cc_if) { + DBG("instantiating CC interface from '%s'\n", val.c_str()); + vector<string> cc_params = explode(val, ";"); + if (cc_params.size()) { + vector<string>::iterator it=cc_params.begin(); + cc_if.cc_module = *it; + DBG(" module='%s'\n", it->c_str()); + it++; + while (it != cc_params.end()) { + size_t epos = it->find('='); + string p, v; + if (epos != string::npos) { + p = it->substr(0, epos); + if (it->length()>epos+1) + v = it->substr(epos+1); + } else { + p = *it; + } + DBG(" '%s'='%s'\n", p.c_str(), v.c_str()); + cc_if.cc_values.insert(make_pair(p,v)); + it++; + } + } else { + cc_if.cc_module = ""; + } +} + void SBCDialog::onInvite(const AmSipRequest& req) { AmUriParser ruri_parser, from_parser, to_parser; - DBG("processing initial INVITE\n"); + DBG("processing initial INVITE %s\n", req.r_uri.c_str()); string app_param = getHeader(req.hdrs, PARAM_HDR, true); @@ -572,22 +599,58 @@ void SBCDialog::onInvite(const AmSipRequest& req) // process call control if (call_profile.cc_interfaces.size()) { - for (vector<CCInterface>::iterator cc_it=call_profile.cc_interfaces.begin(); + unsigned int cc_dynif_count = 0; + + // fix up replacements in cc list + CCInterfaceListIteratorT cc_rit = call_profile.cc_interfaces.begin(); + while (cc_rit != call_profile.cc_interfaces.end()) { + CCInterfaceListIteratorT curr_if = cc_rit; + cc_rit++; + // CCInterfaceListIteratorT next_cc = cc_rit+1; + if (curr_if->cc_name.find('$') != string::npos) { + vector<string> dyn_ccinterfaces = + explode(replaceParameters(curr_if->cc_name, "cc_interfaces", REPLACE_VALS), ","); + if (!dyn_ccinterfaces.size()) { + DBG("call_control '%s' did not produce any call control instances\n", + curr_if->cc_name.c_str()); + call_profile.cc_interfaces.erase(curr_if); + } else { + // fill first CC interface (replacement item) + vector<string>::iterator it=dyn_ccinterfaces.begin(); + curr_if->cc_name = "cc_dyn_"+int2str(cc_dynif_count++); + fixupCCInterface(trim(*it, " \t"), *curr_if); + it++; + + // insert other CC interfaces (in order!) + while (it != dyn_ccinterfaces.end()) { + CCInterfaceListIteratorT new_cc = + call_profile.cc_interfaces.insert(cc_rit, CCInterface()); + fixupCCInterface(trim(*it, " \t"), *new_cc); + new_cc->cc_name = "cc_dyn_"+int2str(cc_dynif_count++); + it++; + } + } + } + } + + // fix up module names + for (CCInterfaceListIteratorT cc_it=call_profile.cc_interfaces.begin(); cc_it != call_profile.cc_interfaces.end(); cc_it++) { - CCInterface& cc_if = *cc_it; - cc_if.cc_module = - replaceParameters(cc_if.cc_module, "cc_module", REPLACE_VALS); + cc_it->cc_module = + replaceParameters(cc_it->cc_module, "cc_module", REPLACE_VALS); } if (!getCCInterfaces()) { throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR); } - for (vector<CCInterface>::iterator cc_it=call_profile.cc_interfaces.begin(); + // fix up variables + for (CCInterfaceListIteratorT cc_it=call_profile.cc_interfaces.begin(); cc_it != call_profile.cc_interfaces.end(); cc_it++) { CCInterface& cc_if = *cc_it; - DBG("processing replacements for call control interface '%s'\n", cc_if.cc_name.c_str()); + DBG("processing replacements for call control interface '%s'\n", + cc_if.cc_name.c_str()); for (map<string, string>::iterator it = cc_if.cc_values.begin(); it != cc_if.cc_values.end(); it++) { @@ -787,7 +850,7 @@ void SBCDialog::onInvite(const AmSipRequest& req) } bool SBCDialog::getCCInterfaces() { - for (vector<CCInterface>::iterator cc_it=call_profile.cc_interfaces.begin(); + for (CCInterfaceListIteratorT cc_it=call_profile.cc_interfaces.begin(); cc_it != call_profile.cc_interfaces.end(); cc_it++) { string& cc_module = cc_it->cc_module; if (cc_module.empty()) { @@ -1079,7 +1142,7 @@ void SBCDialog::stopCallTimer() { bool SBCDialog::CCStart(const AmSipRequest& req) { vector<AmDynInvoke*>::iterator cc_mod=cc_modules.begin(); - for (vector<CCInterface>::iterator cc_it=call_profile.cc_interfaces.begin(); + for (CCInterfaceListIteratorT cc_it=call_profile.cc_interfaces.begin(); cc_it != call_profile.cc_interfaces.end(); cc_it++) { CCInterface& cc_if = *cc_it; @@ -1200,7 +1263,7 @@ bool SBCDialog::CCStart(const AmSipRequest& req) { void SBCDialog::CCConnect(const AmSipReply& reply) { vector<AmDynInvoke*>::iterator cc_mod=cc_modules.begin(); - for (vector<CCInterface>::iterator cc_it=call_profile.cc_interfaces.begin(); + for (CCInterfaceListIteratorT cc_it=call_profile.cc_interfaces.begin(); cc_it != call_profile.cc_interfaces.end(); cc_it++) { CCInterface& cc_if = *cc_it; @@ -1243,7 +1306,7 @@ void SBCDialog::CCConnect(const AmSipReply& reply) { void SBCDialog::CCEnd() { vector<AmDynInvoke*>::iterator cc_mod=cc_modules.begin(); - for (vector<CCInterface>::iterator cc_it=call_profile.cc_interfaces.begin(); + for (CCInterfaceListIteratorT cc_it=call_profile.cc_interfaces.begin(); cc_it != call_profile.cc_interfaces.end(); cc_it++) { CCInterface& cc_if = *cc_it; diff --git a/apps/sbc/SBC.h b/apps/sbc/SBC.h index 0830123..5979f84 100644 --- a/apps/sbc/SBC.h +++ b/apps/sbc/SBC.h @@ -121,6 +121,8 @@ class SBCDialog : public AmB2BCallerSession, public CredentialHolder SBCCallProfile call_profile; + void fixupCCInterface(const string& val, CCInterface& cc_if); + /** handler called when the second leg is connected */ void onCallConnected(const AmSipReply& reply); diff --git a/apps/sbc/SBCCallProfile.cpp b/apps/sbc/SBCCallProfile.cpp index 8a8638e..50d7e1c 100644 --- a/apps/sbc/SBCCallProfile.cpp +++ b/apps/sbc/SBCCallProfile.cpp @@ -170,7 +170,8 @@ bool SBCCallProfile::readFromConfiguration(const string& name, AmArg mandatory_values; // check if module is loaded and if, get mandatory config values - if (cc_if.cc_module.find('$') == string::npos) { + if (cc_if.cc_module.find('$') == string::npos && + cc_if.cc_name.find('$') == string::npos) { AmDynInvokeFactory* df = AmPlugIn::instance()->getFactory4Di(cc_if.cc_module); if (NULL == df) { ERROR("Call control module '%s' used in call profile " @@ -344,11 +345,11 @@ bool SBCCallProfile::readFromConfiguration(const string& name, if (cc_interfaces.size()) { string cc_if_names; - for ( vector<CCInterface>::iterator it = - cc_interfaces.begin(); it != cc_interfaces.end(); it++) { + for (CCInterfaceListIteratorT it = + cc_interfaces.begin(); it != cc_interfaces.end(); it++) { cc_if_names = it->cc_name+","; cc_if_names.erase(cc_if_names.size()-1,1); - INFO("SBC: Call Control interfaces: %s\n", cc_if_names.c_str()); + INFO("SBC: Call Control: %s\n", cc_if_names.c_str()); } } diff --git a/apps/sbc/SBCCallProfile.h b/apps/sbc/SBCCallProfile.h index a15c824..01479de 100644 --- a/apps/sbc/SBCCallProfile.h +++ b/apps/sbc/SBCCallProfile.h @@ -33,6 +33,7 @@ #include <set> #include <string> #include <map> +#include <list> using std::string; using std::map; @@ -48,8 +49,12 @@ struct CCInterface { CCInterface(string cc_name) : cc_name(cc_name) { } + CCInterface() { } }; +typedef std::list<CCInterface> CCInterfaceListT; +typedef CCInterfaceListT::iterator CCInterfaceListIteratorT; + struct SBCCallProfile : public ArgObject { string md5hash; @@ -91,7 +96,7 @@ struct SBCCallProfile bool auth_aleg_enabled; UACAuthCred auth_aleg_credentials; - vector<CCInterface> cc_interfaces; + CCInterfaceListT cc_interfaces; SBCVarMapT cc_vars; _______________________________________________ Semsdev mailing list [email protected] http://lists.iptel.org/mailman/listinfo/semsdev
