Browse code

sbc:ext-cc: possibility to add ext-cc interfaces from cc-interfaces' init function - possible in init and onInitialInvite - only call legs (SBCCallLeg), not supported in SimpleRelay (non-call messages)

Stefan Sayer authored on 02/12/2013 18:04:31
Showing 3 changed files
... ...
@@ -1,5 +1,5 @@
1 1
 /*
2
- * Copyright (C) 2010-2011 Stefan Sayer
2
+ * Copyright (C) 2010-2013 Stefan Sayer
3 3
  * Copyright (C) 2012-2013 FRAFOS GmbH
4 4
  *
5 5
  * This file is part of SEMS, a free SIP media server.
... ...
@@ -48,6 +48,7 @@
48 48
 #include "ParamReplacer.h"
49 49
 #include "SDPFilter.h"
50 50
 #include "SBCEventLog.h"
51
+#include "SBC.h"
51 52
 
52 53
 #include <algorithm>
53 54
 
... ...
@@ -187,7 +188,7 @@ SBCCallLeg::SBCCallLeg(SBCCallLeg* caller, AmSipDialog* p_dlg,
187 188
     throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
188 189
   }
189 190
 
190
-  if (!initCCExtModules()) {
191
+  if (!initCCExtModules(call_profile.cc_interfaces, cc_modules)) {
191 192
     ERROR("initializing extended call control modules\n");
192 193
     throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
193 194
   }
... ...
@@ -817,7 +818,7 @@ void SBCCallLeg::onInvite(const AmSipRequest& req)
817 818
     throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
818 819
   }
819 820
 
820
-  if (!initCCExtModules()) {
821
+  if (!initCCExtModules(call_profile.cc_interfaces, cc_modules)) {
821 822
     ERROR("initializing extended call control modules\n");
822 823
     throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);    
823 824
   }
... ...
@@ -907,6 +908,8 @@ void SBCCallLeg::onInvite(const AmSipRequest& req)
907 908
   InitialInviteHandlerParams params(to, ruri, from, &req, &invite_req);
908 909
   for (vector<ExtendedCCInterface*>::iterator i = cc_ext.begin(); i != cc_ext.end(); ++i) {
909 910
     (*i)->onInitialInvite(this, params);
911
+    // initialize possibily added modules
912
+    initPendingCCExtModules();
910 913
   }
911 914
 
912 915
   if (getCallStatus() == Disconnected) {
... ...
@@ -1548,15 +1551,19 @@ bool SBCCallLeg::reinvite(const AmSdp &sdp, unsigned &request_cseq)
1548 1551
   return true;
1549 1552
 }
1550 1553
 
1551
-bool SBCCallLeg::initCCExtModules()
1554
+/**
1555
+ * initialize modules from @arg cc_module_list with DI interface instances from @arg cc_module_di
1556
+ * add sucessfull ext-API call control instances to cc_ext
1557
+ * @return true on success (all modules properly initialized)
1558
+*/
1559
+bool SBCCallLeg::initCCExtModules(const CCInterfaceListT& cc_module_list, const vector<AmDynInvoke*>& cc_module_di)
1552 1560
 {
1553 1561
   // init extended call control modules
1554
-  vector<AmDynInvoke*>::iterator cc_mod = cc_modules.begin();
1555
-  for (CCInterfaceListIteratorT cc_it=call_profile.cc_interfaces.begin();
1556
-       cc_it != call_profile.cc_interfaces.end(); cc_it++)
1562
+  vector<AmDynInvoke*>::const_iterator cc_mod = cc_module_di.begin();
1563
+  for (CCInterfaceListConstIteratorT cc_it = cc_module_list.begin(); cc_it != cc_module_list.end(); cc_it++)
1557 1564
   {
1558
-    CCInterface& cc_if = *cc_it;
1559
-    string& cc_module = cc_it->cc_module;
1565
+    const CCInterface& cc_if = *cc_it;
1566
+    const string& cc_module = cc_it->cc_module;
1560 1567
 
1561 1568
     // get extended CC interface
1562 1569
     try {
... ...
@@ -1567,7 +1574,7 @@ bool SBCCallLeg::initCCExtModules()
1567 1574
         DBG("extended CC interface offered by cc_module '%s'\n", cc_module.c_str());
1568 1575
         // module initialization
1569 1576
         if (!iface->init(this, cc_if.cc_values)) {
1570
-	  ERROR("initializing extended call control interface\n");
1577
+	  ERROR("initializing extended call control interface '%s'\n", cc_module.c_str());
1571 1578
 	  return false;
1572 1579
 	}
1573 1580
 
... ...
@@ -1586,9 +1593,42 @@ bool SBCCallLeg::initCCExtModules()
1586 1593
 
1587 1594
     ++cc_mod;
1588 1595
   }
1596
+
1597
+  if (!initPendingCCExtModules()) {
1598
+    return false;
1599
+  }
1600
+
1589 1601
   return true; // success
1590 1602
 }
1591 1603
 
1604
+/** init pending modules until queue is empty */
1605
+bool SBCCallLeg::initPendingCCExtModules() {
1606
+  while (cc_module_queue.size()) {
1607
+    // local copy
1608
+    CCInterfaceListT _cc_mod_queue = cc_module_queue;
1609
+    cc_module_queue.clear();
1610
+    vector<AmDynInvoke*> _cc_mod_ifs;
1611
+
1612
+    // get corresponding DI interfaces
1613
+    if (!::getCCInterfaces(_cc_mod_queue, _cc_mod_ifs))
1614
+      return false;
1615
+
1616
+    // add to call leg
1617
+    if (!initCCExtModules(_cc_mod_queue, _cc_mod_ifs)) {
1618
+      return false;
1619
+    }
1620
+  }
1621
+  return true;
1622
+}
1623
+
1624
+void SBCCallLeg::addPendingCCExtModule(const string& cc_name, const string& cc_module, const map<string, string>& cc_values) {
1625
+  cc_module_queue.push_back(CCInterface(cc_name));
1626
+  cc_module_queue.back().cc_module = cc_module;
1627
+  cc_module_queue.back().cc_values = cc_values;
1628
+  DBG("added module '%s' from module '%s' to pending CC Ext modules\n",
1629
+      cc_name.c_str(), cc_module.c_str());
1630
+}
1631
+
1592 1632
 #define CALL_EXT_CC_MODULES(method) \
1593 1633
   do { \
1594 1634
     for (vector<ExtendedCCInterface*>::iterator i = cc_ext.begin(); i != cc_ext.end(); ++i) { \
... ...
@@ -60,6 +60,9 @@ class SBCCallLeg : public CallLeg, public CredentialHolder
60 60
   vector<AmDynInvoke*> cc_modules;
61 61
   vector<ExtendedCCInterface*> cc_ext;
62 62
 
63
+  // modules to initialize
64
+  CCInterfaceListT cc_module_queue;
65
+
63 66
   // current timer ID - cc module setting timer will use this
64 67
   int cc_timer_id;
65 68
   int ext_cc_timer_id; // for assigning IDs to timers through "extended CC interface"
... ...
@@ -153,7 +156,9 @@ class SBCCallLeg : public CallLeg, public CredentialHolder
153 156
   UACAuthCred* getCredentials();
154 157
 
155 158
   void setAuthHandler(AmSessionEventHandler* h) { auth = h; }
156
-  bool initCCExtModules();
159
+  bool initCCExtModules(const CCInterfaceListT& cc_module_list, const vector<AmDynInvoke*>& cc_module_di);
160
+  bool initPendingCCExtModules();
161
+  void addPendingCCExtModule(const string& cc_name, const string& cc_module, const map<string, string>& cc_values);
157 162
 
158 163
   /** save call timer; only effective before call is connected */
159 164
   void saveCallTimer(int timer, double timeout);
... ...
@@ -59,6 +59,7 @@ struct CCInterface {
59 59
 
60 60
 typedef std::list<CCInterface> CCInterfaceListT;
61 61
 typedef CCInterfaceListT::iterator CCInterfaceListIteratorT;
62
+typedef CCInterfaceListT::const_iterator CCInterfaceListConstIteratorT;
62 63
 
63 64
 template <class T>
64 65
 class ref_counted_ptr