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

Reply via email to