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
