sbc: active profile reload; control scripts (py)

sayer/1.4-spce2.6
Stefan Sayer 16 years ago
parent 93a5978f38
commit 527d48f87e

@ -2,6 +2,10 @@ plug_in_name = sbc
module_ldflags =
module_cflags = -DMOD_NAME=\"$(plug_in_name)\"
extra_install = install_tools
COREPATH ?= ../../core
include $(COREPATH)/plug-in/Makefile.app_module
install_tools:
-@$(MAKE) -C tools/ install

@ -58,19 +58,42 @@ string SBCFactory::pwd;
AmConfigReader SBCFactory::cfg;
AmSessionEventHandlerFactory* SBCFactory::session_timer_fact = NULL;
EXPORT_SESSION_FACTORY(SBCFactory,MOD_NAME);
extern "C" void* plugin_class_create()
{
return SBCFactory::instance();
}
extern "C" void* session_factory_create()
{
return plugin_class_create();
}
SBCFactory* SBCFactory::_instance=0;
bool SBCFactory::loaded=false;
SBCFactory* SBCFactory::instance()
{
if(_instance == NULL)
_instance = new SBCFactory(MOD_NAME);
return _instance;
}
SBCFactory::SBCFactory(const string& _app_name)
: AmSessionFactory(_app_name)
: AmSessionFactory(_app_name), AmDynInvokeFactory(_app_name)
{
}
SBCFactory::~SBCFactory() {
}
int SBCFactory::onLoad()
{
if (loaded)
return 0;
loaded = true;
if(cfg.loadFile(AmConfig::ModConfigPath + string(MOD_NAME ".conf"))) {
ERROR("No configuration for sbc present (%s)\n",
(AmConfig::ModConfigPath + string(MOD_NAME ".conf")).c_str()
@ -109,6 +132,8 @@ int SBCFactory::onLoad()
AmSession* SBCFactory::onInvite(const AmSipRequest& req)
{
profiles_mut.lock();
string profile = active_profile;
if (profile == "$(paramhdr)") {
string app_param = getHeader(req.hdrs, PARAM_HDR, true);
@ -120,6 +145,7 @@ AmSession* SBCFactory::onInvite(const AmSipRequest& req)
map<string, SBCCallProfile>::iterator it=
call_profiles.find(profile);
if (it==call_profiles.end()) {
profiles_mut.unlock();
ERROR("could not find call profile '%s' (active_profile = %s)\n",
profile.c_str(), active_profile.c_str());
throw AmSession::Exception(500,"Server Internal Error");
@ -132,8 +158,10 @@ AmSession* SBCFactory::onInvite(const AmSipRequest& req)
if (call_profile.sst_enabled) {
DBG("Enabling SIP Session Timers\n");
if (!session_timer_fact->onInvite(req, sst_cfg))
if (!session_timer_fact->onInvite(req, sst_cfg)) {
profiles_mut.unlock();
return NULL;
}
}
SBCDialog* b2b_dlg = new SBCDialog(call_profile);
@ -141,6 +169,7 @@ AmSession* SBCFactory::onInvite(const AmSipRequest& req)
if (call_profile.sst_enabled) {
AmSessionEventHandler* h = session_timer_fact->getHandler(b2b_dlg);
if(!h) {
profiles_mut.unlock();
delete b2b_dlg;
ERROR("could not get a session timer event handler\n");
throw AmSession::Exception(500,"Server internal error");
@ -153,10 +182,182 @@ AmSession* SBCFactory::onInvite(const AmSipRequest& req)
b2b_dlg->addHandler(h);
}
}
profiles_mut.unlock();
return b2b_dlg;
}
void SBCFactory::invoke(const string& method, const AmArg& args,
AmArg& ret)
{
if (method == "listProfiles"){
listProfiles(args, ret);
} else if (method == "reloadProfiles"){
reloadProfiles(args,ret);
} else if (method == "loadProfile"){
args.assertArrayFmt("u");
loadProfile(args,ret);
} else if (method == "reloadProfile"){
args.assertArrayFmt("u");
reloadProfile(args,ret);
} else if (method == "getActiveProfile"){
getActiveProfile(args,ret);
} else if (method == "setActiveProfile"){
args.assertArrayFmt("u");
setActiveProfile(args,ret);
} else if(method == "_list"){
ret.push(AmArg("listProfiles"));
ret.push(AmArg("reloadProfiles"));
ret.push(AmArg("reloadProfile"));
ret.push(AmArg("loadProfile"));
ret.push(AmArg("getActiveProfile"));
ret.push(AmArg("setActiveProfile"));
} else
throw AmDynInvoke::NotImplemented(method);
}
void SBCFactory::listProfiles(const AmArg& args, AmArg& ret) {
profiles_mut.lock();
for (std::map<string, SBCCallProfile>::iterator it=
call_profiles.begin(); it != call_profiles.end(); it++) {
AmArg p;
p["name"] = it->first;
p["md5"] = it->second.md5hash;
p["path"] = it->second.profile_file;
ret.push((p));
}
profiles_mut.unlock();
}
void SBCFactory::reloadProfiles(const AmArg& args, AmArg& ret) {
std::map<string, SBCCallProfile> new_call_profiles;
bool failed = false;
string res = "OK";
AmArg profile_list;
profiles_mut.lock();
for (std::map<string, SBCCallProfile>::iterator it=
call_profiles.begin(); it != call_profiles.end(); it++) {
new_call_profiles[it->first] = SBCCallProfile();
if (!new_call_profiles[it->first].readFromConfiguration(it->first,
it->second.profile_file)) {
ERROR("reading call profile file '%s'\n", it->second.profile_file.c_str());
res = "Error reading call profile for "+it->first+" from "+it->second.profile_file+
+"; no profiles reloaded";
failed = true;
break;
}
AmArg p;
p["name"] = it->first;
p["md5"] = it->second.md5hash;
p["path"] = it->second.profile_file;
profile_list.push(p);
}
if (!failed) {
call_profiles = new_call_profiles;
ret.push(200);
} else {
ret.push(500);
}
ret.push(res);
ret.push(profile_list);
profiles_mut.unlock();
}
void SBCFactory::reloadProfile(const AmArg& args, AmArg& ret) {
bool failed = false;
string res = "OK";
AmArg p;
if (!args[0].hasMember("name")) {
ret.push(400);
ret.push("Parameters error: expected ['name': profile_name] ");
return;
}
profiles_mut.lock();
std::map<string, SBCCallProfile>::iterator it=
call_profiles.find(args[0]["name"].asCStr());
if (it == call_profiles.end()) {
res = "profile '"+string(args[0]["name"].asCStr())+"' not found";
failed = true;
} else {
SBCCallProfile new_cp;
if (!new_cp.readFromConfiguration(it->first, it->second.profile_file)) {
ERROR("reading call profile file '%s'\n", it->second.profile_file.c_str());
res = "Error reading call profile for "+it->first+" from "+it->second.profile_file;
failed = true;
} else {
it->second = new_cp;
p["name"] = it->first;
p["md5"] = it->second.md5hash;
p["path"] = it->second.profile_file;
}
}
profiles_mut.unlock();
if (!failed) {
ret.push(200);
ret.push(res);
ret.push(p);
} else {
ret.push(500);
ret.push(res);
}
}
void SBCFactory::loadProfile(const AmArg& args, AmArg& ret) {
if (!args[0].hasMember("name") || !args[0].hasMember("path")) {
ret.push(400);
ret.push("Parameters error: expected ['name': profile_name] "
"and ['path': profile_path]");
return;
}
SBCCallProfile cp;
if (!cp.readFromConfiguration(args[0]["name"].asCStr(), args[0]["path"].asCStr())) {
ret.push(500);
ret.push("Error reading sbc call profile for "+string(args[0]["name"].asCStr())+
" from file "+string(args[0]["path"].asCStr()));
return;
}
profiles_mut.lock();
call_profiles[args[0]["name"].asCStr()] = cp;
profiles_mut.unlock();
ret.push(200);
ret.push("OK");
AmArg p;
p["name"] = args[0]["name"];
p["md5"] = cp.md5hash;
p["path"] = args[0]["path"];
ret.push(p);
}
void SBCFactory::getActiveProfile(const AmArg& args, AmArg& ret) {
profiles_mut.lock();
AmArg p;
p["active_profile"] = active_profile;
profiles_mut.unlock();
ret.push(200);
ret.push("OK");
ret.push(p);
}
void SBCFactory::setActiveProfile(const AmArg& args, AmArg& ret) {
if (!args[0].hasMember("active_profile")) {
ret.push(400);
ret.push("Parameters error: expected ['active_profile': <active_profile>] ");
return;
}
profiles_mut.lock();
active_profile = args[0]["active_profile"].asCStr();
profiles_mut.unlock();
ret.push(200);
ret.push("OK");
AmArg p;
p["active_profile"] = args[0]["active_profile"];
ret.push(p);
}
SBCDialog::SBCDialog(const SBCCallProfile& call_profile)
: m_state(BB_Init),

@ -41,16 +41,31 @@ using std::string;
#define SBC_TIMER_ID_PREPAID_TIMEOUT 2
class SBCFactory: public AmSessionFactory
class SBCFactory: public AmSessionFactory,
public AmDynInvoke,
public AmDynInvokeFactory
{
std::map<string, SBCCallProfile> call_profiles;
std::map<string, AmConfigReader> call_profiles_configs;
std::map<string, SBCCallProfile> call_profiles;
string active_profile;
AmMutex profiles_mut;
static SBCFactory* _instance;
static bool loaded;
void listProfiles(const AmArg& args, AmArg& ret);
void reloadProfiles(const AmArg& args, AmArg& ret);
void reloadProfile(const AmArg& args, AmArg& ret);
void loadProfile(const AmArg& args, AmArg& ret);
void getActiveProfile(const AmArg& args, AmArg& ret);
void setActiveProfile(const AmArg& args, AmArg& ret);
public:
static SBCFactory* instance();
SBCFactory(const string& _app_name);
~SBCFactory();
int onLoad();
AmSession* onInvite(const AmSipRequest& req);
static string user;
@ -59,6 +74,14 @@ class SBCFactory: public AmSessionFactory
static AmConfigReader cfg;
static AmSessionEventHandlerFactory* session_timer_fact;
// DI
// DI factory
AmDynInvoke* getInstance() { return instance(); }
// DI API
void invoke(const string& method,
const AmArg& args, AmArg& ret);
};
class SBCDialog : public AmB2BCallerSession

@ -14,6 +14,8 @@ bool SBCCallProfile::readFromConfiguration(const string& name,
return false;
}
profile_file = profile_file_name;
ruri = cfg.getParameter("RURI");
from = cfg.getParameter("From");
to = cfg.getParameter("To");
@ -140,7 +142,12 @@ bool SBCCallProfile::readFromConfiguration(const string& name,
reply_translations[from_code] = make_pair(to_code, to_reply.substr(s_pos));
}
INFO("SBC: loaded SBC profile '%s':\n", name.c_str());
md5hash = "<unknown>";
if (!cfg.getMD5(profile_file_name, md5hash)){
ERROR("calculating MD5 of file %s\n", profile_file_name.c_str());
}
INFO("SBC: loaded SBC profile '%s' - MD5: %s\n", name.c_str(), md5hash.c_str());
INFO("SBC: RURI = '%s'\n", ruri.c_str());
INFO("SBC: From = '%s'\n", from.c_str());

@ -17,6 +17,8 @@ using std::set;
struct SBCCallProfile {
AmConfigReader cfg;
string md5hash;
string profile_file;
string ruri; /* updated if set */
string from; /* updated if set */

@ -0,0 +1,15 @@
COREPATH ?= ../../../core
include $(COREPATH)/../Makefile.defs
sbc_scripts = $(wildcard sems-sbc-*)
all: install_tools
install: install_tools
install_tools: $(DESTDIR)$(bin-prefix)/$(bin-dir)
-@for r in $(sbc_scripts) ; do \
$(INSTALL-TOUCH) $(DESTDIR)$(bin-prefix)/$(bin-dir)/$$r ; \
$(INSTALL-BIN) $$r $(DESTDIR)$(bin-prefix)/$(bin-dir) ; \
done

@ -0,0 +1,7 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
from xmlrpclib import *
s = ServerProxy('http://localhost:8090')
print "Active calls: %d" % s.calls()
print s.getActiveProfile()

@ -0,0 +1,7 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
from xmlrpclib import *
s = ServerProxy('http://localhost:8090')
print "Active calls: %d" % s.calls()
print s.listProfiles()

@ -0,0 +1,13 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from xmlrpclib import *
if len(sys.argv) != 3:
print "usage: %s <profile name> <full profile path>" % sys.argv[0]
sys.exit(1)
s = ServerProxy('http://localhost:8090')
print "Active calls: %d" % s.calls()
p ={ 'name' : sys.argv[1], 'path' : sys.argv[2] }
print s.loadProfile(p)

@ -0,0 +1,13 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from xmlrpclib import *
if len(sys.argv) != 2:
print "usage: %s <profile name>" % sys.argv[0]
sys.exit(1)
s = ServerProxy('http://localhost:8090')
print "Active calls: %d" % s.calls()
p ={ 'name' : sys.argv[1] }
print s.reloadProfile(p)

@ -0,0 +1,7 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
from xmlrpclib import *
s = ServerProxy('http://localhost:8090')
print s.calls()
print s.reloadProfiles()

@ -0,0 +1,12 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from xmlrpclib import *
if len(sys.argv) != 2:
print "usage: %s <profile name>" % sys.argv[0]
sys.exit(1)
s = ServerProxy('http://localhost:8090')
print "Active calls: %d" % s.calls()
print s.setActiveProfile(sys.argv[1])
Loading…
Cancel
Save