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
sayer/1.4-spce2.6
Stefan Sayer 15 years ago
parent bfb07e77f1
commit f569d0369a

@ -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

@ -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; }

@ -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)

@ -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

@ -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

Loading…
Cancel
Save