Module: sems
Branch: sayer/1.4-spce2.4
Commit: f569d0369a6d0215bed19f916bf0c19416626340
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=f569d0369a6d0215bed19f916bf0c19416626340

Author: Stefan Sayer <[email protected]>
Committer: Stefan Sayer <[email protected]>
Date:   Thu Mar  8 18:32:05 2012 +0100

sbc: tear down calls through RPC (DI, e.g. XMLRPC)

Conflicts:

        apps/sbc/SBC.cpp
        apps/sbc/SBC.h
        core/ampi/SBCCallControlAPI.h
        doc/Readme.sbc.txt

---

 apps/sbc/SBC.cpp                      |   57 ++++++++++++++++++++++++
 apps/sbc/SBC.h                        |    7 +++
 apps/sbc/tools/sems-sbc-teardown-call |   19 ++++++++
 core/ampi/SBCCallControlAPI.h         |   78 +++++++++++++++++++++++++++++++++
 doc/Readme.sbc.txt                    |   12 +++++
 5 files changed, 173 insertions(+), 0 deletions(-)

diff --git a/apps/sbc/SBC.cpp b/apps/sbc/SBC.cpp
index f429cb4..d6245a6 100644
--- a/apps/sbc/SBC.cpp
+++ b/apps/sbc/SBC.cpp
@@ -33,6 +33,7 @@ SBC - feature-wishlist
 - fallback profile
  */
 #include "SBC.h"
+#include "ampi/SBCCallControlAPI.h"
 
 #include "log.h"
 #include "AmUtils.h"
@@ -287,6 +288,9 @@ void SBCFactory::invoke(const string& method, const AmArg& 
args,
   } else if (method == "setRegexMap"){
     args.assertArrayFmt("u");
     setRegexMap(args,ret);
+  } else if (method == "postControlCmd"){
+    args.assertArrayFmt("ss"); // at least call-ltag, cmd
+    postControlCmd(args,ret);
   } else if(method == "_list"){ 
     ret.push(AmArg("listProfiles"));
     ret.push(AmArg("reloadProfiles"));
@@ -296,6 +300,7 @@ void SBCFactory::invoke(const string& method, const AmArg& 
args,
     ret.push(AmArg("setActiveProfile"));
     ret.push(AmArg("getRegexMapNames"));
     ret.push(AmArg("setRegexMap"));
+    ret.push(AmArg("postControlCmd"));
   }  else
     throw AmDynInvoke::NotImplemented(method);
 }
@@ -479,6 +484,22 @@ void SBCFactory::setRegexMap(const AmArg& args, AmArg& 
ret) {
   ret.push("OK");
 }
 
+void SBCFactory::postControlCmd(const AmArg& args, AmArg& ret) {
+  SBCControlEvent* evt;
+  if (args.size()<3) {
+    evt = new SBCControlEvent(args[1].asCStr());
+  } else {
+    evt = new SBCControlEvent(args[1].asCStr(), args[2]);
+  }
+  if (!AmSessionContainer::instance()->postEvent(args[0].asCStr(), evt)) {
+    ret.push(404);
+    ret.push("Not found");
+  } else {
+    ret.push(202);
+    ret.push("Accepted");
+  }
+}
+
 SBCDialog::SBCDialog(const SBCCallProfile& call_profile)
   : m_state(BB_Init),
     prepaid_acc(NULL),
@@ -745,9 +766,25 @@ void SBCDialog::process(AmEvent* ev)
     }
   }
 
+  SBCControlEvent* ctl_event;
+  if (ev->event_id == SBCControlEvent_ID &&
+      (ctl_event = dynamic_cast<SBCControlEvent*>(ev)) != NULL) {
+    onControlCmd(ctl_event->cmd, ctl_event->params);
+    return;
+  }
+
   AmB2BCallerSession::process(ev);
 }
 
+void SBCDialog::onControlCmd(string& cmd, AmArg& params) {
+  if (cmd == "teardown") {
+    DBG("teardown requested from control cmd\n");
+    stopCall();
+    return;
+  }
+  DBG("ignoring unknown control cmd : '%s'\n", cmd.c_str());
+}
+
 int SBCDialog::relayEvent(AmEvent* ev) {
   if ((call_profile.headerfilter != Transparent) &&
       (ev->event_id == B2BSipRequest)) {
@@ -1150,6 +1187,17 @@ int SBCCalleeSession::relayEvent(AmEvent* ev) {
   return AmB2BCalleeSession::relayEvent(ev);
 }
 
+void SBCCalleeSession::process(AmEvent* ev) {
+  SBCControlEvent* ctl_event;
+  if (ev->event_id == SBCControlEvent_ID &&
+      (ctl_event = dynamic_cast<SBCControlEvent*>(ev)) != NULL) {
+    onControlCmd(ctl_event->cmd, ctl_event->params);
+    return;
+  }
+
+  AmB2BCalleeSession::process(ev);
+}
+
 void SBCCalleeSession::onSipRequest(const AmSipRequest& req) {
   // AmB2BSession does not call AmSession::onSipRequest for 
   // forwarded requests - so lets call event handlers here
@@ -1223,6 +1271,15 @@ void SBCCalleeSession::onSendRequest(const string& 
method, const string& content
                                     body, hdrs, flags, cseq);
 }
 
+void SBCCalleeSession::onControlCmd(string& cmd, AmArg& params) {
+  if (cmd == "teardown") {
+    DBG("relaying teardown control cmd to A leg\n");
+    relayEvent(new SBCControlEvent(cmd, params));
+    return;
+  }
+  DBG("ignoring unknown control cmd : '%s'\n", cmd.c_str());
+}
+
 int SBCCalleeSession::filterBody(AmSdp& sdp, bool is_a2b) {
   if (call_profile.sdpfilter_enabled) {
     // normalize SDP
diff --git a/apps/sbc/SBC.h b/apps/sbc/SBC.h
index 9892758..01c1ab1 100644
--- a/apps/sbc/SBC.h
+++ b/apps/sbc/SBC.h
@@ -60,6 +60,7 @@ class SBCFactory: public AmSessionFactory,
   void setActiveProfile(const AmArg& args, AmArg& ret);
   void getRegexMapNames(const AmArg& args, AmArg& ret);
   void setRegexMap(const AmArg& args, AmArg& ret);
+  void postControlCmd(const AmArg& args, AmArg& ret);
 
   string getActiveProfileMatch(string& profile_rule, const AmSipRequest& req,
                               const string& app_param, AmUriParser& 
ruri_parser,
@@ -144,6 +145,8 @@ class SBCDialog : public AmB2BCallerSession
   bool onOtherReply(const AmSipReply& reply);
   void onOtherBye(const AmSipRequest& req);
 
+  void onControlCmd(string& cmd, AmArg& params);
+
   int filterBody(AmSdp& sdp, bool is_a2b);
 
   void createCalleeSession();
@@ -166,6 +169,8 @@ class SBCCalleeSession
 
   /* bool onOtherReply(const AmSipReply& reply); */
 
+  void onControlCmd(string& cmd, AmArg& params);
+
   int filterBody(AmSdp& sdp, bool is_a2b);
 
  public:
@@ -173,6 +178,8 @@ class SBCCalleeSession
                   const SBCCallProfile& call_profile); 
   ~SBCCalleeSession();
 
+  void process(AmEvent* ev);
+
   inline UACAuthCred* getCredentials();
   
   void setAuthHandler(AmSessionEventHandler* h) { auth = h; }
diff --git a/apps/sbc/tools/sems-sbc-teardown-call 
b/apps/sbc/tools/sems-sbc-teardown-call
new file mode 100755
index 0000000..d89e0d2
--- /dev/null
+++ b/apps/sbc/tools/sems-sbc-teardown-call
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+import sys
+from xmlrpclib import *
+
+if len(sys.argv) != 2:
+       print "usage: %s <ltag/ID of call to tear down>" % sys.argv[0]
+       sys.exit(1)
+
+s = ServerProxy('http://localhost:8090')
+print "Active calls: %d" % s.calls()
+res = s.di('sbc', 'postControlCmd', sys.argv[1], "teardown")
+
+if res[0] >= 200 and res[0] < 300:
+  print "OK"
+  sys.exit(0)
+else:
+  print "Error: %s" % str(res)
+  sys.exit(2)
diff --git a/core/ampi/SBCCallControlAPI.h b/core/ampi/SBCCallControlAPI.h
new file mode 100644
index 0000000..bcf7aec
--- /dev/null
+++ b/core/ampi/SBCCallControlAPI.h
@@ -0,0 +1,78 @@
+#ifndef _SBCCallControlAPI_h_
+#define _SBCCallControlAPI_h_
+
+#define CC_INTERFACE_MAND_VALUES_METHOD "getMandatoryValues"
+
+
+#define CC_API_PARAMS_CC_NAMESPACE      0
+#define CC_API_PARAMS_LTAG              1
+#define CC_API_PARAMS_CALL_PROFILE      2
+#define CC_API_PARAMS_TIMESTAMPS        3
+
+#define CC_API_PARAMS_CFGVALUES         4
+#define CC_API_PARAMS_TIMERID           5
+
+#define CC_API_PARAMS_OTHERID           4
+
+#define CC_API_TS_START_SEC             0
+#define CC_API_TS_START_USEC            1
+#define CC_API_TS_CONNECT_SEC           2
+#define CC_API_TS_CONNECT_USEC          3
+#define CC_API_TS_END_SEC               4
+#define CC_API_TS_END_USEC              5
+
+#define SBC_CC_DROP_ACTION              0
+#define SBC_CC_REFUSE_ACTION            1
+#define SBC_CC_SET_CALL_TIMER_ACTION    2
+
+#define SBC_CC_REPL_SET_GLOBAL_ACTION        10
+#define SBC_CC_REPL_REMOVE_GLOBAL_ACTION     11
+
+// index in action parameter:
+#define SBC_CC_ACTION              0
+
+//    refuse with
+#define SBC_CC_REFUSE_CODE         1
+#define SBC_CC_REFUSE_REASON       2
+#define SBC_CC_REFUSE_HEADERS      3
+
+//     set timer
+#define SBC_CC_TIMER_TIMEOUT       1
+
+//     set/remove globals
+#define SBC_CC_REPL_SET_GLOBAL_SCOPE 1
+#define SBC_CC_REPL_SET_GLOBAL_NAME  2
+#define SBC_CC_REPL_SET_GLOBAL_VALUE 3
+
+/** post an SBCCallTimerEvent to an SBC call in order to set or reset call 
timer */
+#define SBCCallTimerEvent_ID -563
+struct SBCCallTimerEvent : public AmEvent {
+  enum TimerAction {
+    Remove = 0,
+    Set,
+    Reset
+  };
+
+  TimerAction timer_action;
+  double timeout;
+  int timer_id;
+
+ SBCCallTimerEvent(TimerAction timer_action, int timer_id, double timeout = 0)
+    : AmEvent(SBCCallTimerEvent_ID),
+    timer_id(timer_id), timer_action(timer_action), timeout(timeout) { }
+};
+
+#define SBCControlEvent_ID -564
+struct SBCControlEvent : public AmEvent {
+  string cmd;
+  AmArg params;
+
+  SBCControlEvent(const string& cmd, const AmArg& params)
+    : AmEvent(SBCControlEvent_ID), cmd(cmd), params(params) { }
+
+  SBCControlEvent(const string& cmd)
+    : AmEvent(SBCControlEvent_ID), cmd(cmd) { }
+
+};
+
+#endif
diff --git a/doc/Readme.sbc.txt b/doc/Readme.sbc.txt
index 4b03751..e0c86be 100644
--- a/doc/Readme.sbc.txt
+++ b/doc/Readme.sbc.txt
@@ -24,7 +24,12 @@ Features
  o SIP Session Timers
  o call timer
  o prepaid accounting
+<<<<<<< HEAD
 
+=======
+ o CDR generation
+ o call teardown from external control through RPC
+>>>>>>> 3af5aa5... sbc: tear down calls through RPC (DI, e.g. XMLRPC)
 
 SBC Profiles
 ------------
@@ -85,7 +90,14 @@ is provided and installed to trigger the reload (through 
XMLRPC):
   sems-sbc-get-activeprofile                    get active_profile
   sems-sbc-set-activeprofile <active_profile>   set active_profile
 
+<<<<<<< HEAD
 The xmlrpc2di module must be loaded and XMLRPC control server bound to port 
8090 for
+=======
+  sems-sbc-teardown-call <call_ltag>            tear down call (use e.g. 
monitoring's
+                                                sems-list-active-calls to get 
the ltag)
+
+The xmlrpc2di module must be loaded and the XMLRPC control server bound to 
port 8090 for
+>>>>>>> 3af5aa5... sbc: tear down calls through RPC (DI, e.g. XMLRPC)
 the scripts to work.
 
 For tracking file revisions and changes, the MD5 hash sum is printed on 
profile load and

_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to