implements DSM app configurations from conf.d dir. this make it e.g. possible to install DSM applications from separate packages

git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@1582 8eb893ce-cfd4-0310-b710-fb5ebe64c474
sayer/1.4-spce2.6
Stefan Sayer 17 years ago
parent 1fa81f84fc
commit 0481ed77e0

@ -41,6 +41,9 @@
#include <string>
#include <fstream>
#include <sys/types.h>
#include <dirent.h>
#define MOD_NAME "dsm"
extern "C" void* plugin_class_create()
@ -69,17 +72,13 @@ MonSelectType DSMFactory::MonSelectCaller;
MonSelectType DSMFactory::MonSelectCallee;
#endif // USE_MONITORING
map<string, string> DSMFactory::config;
bool DSMFactory::RunInviteEvent;
bool DSMFactory::SetParamVariables;
DSMFactory::DSMFactory(const string& _app_name)
: AmSessionFactory(_app_name),AmDynInvokeFactory(_app_name),
loaded(false)
{
AmEventDispatcher::instance()->addEventQueue("dsm", this);
diags = new DSMStateDiagramCollection();
MainScriptConfig.diags = new DSMStateDiagramCollection();
}
void DSMFactory::postEvent(AmEvent* e) {
@ -100,9 +99,11 @@ DSMFactory::~DSMFactory() {
prompt_sets.begin(); it != prompt_sets.end(); it++)
delete it->second;
for (vector<DSMStateDiagramCollection*>::iterator it=
for (std::set<DSMStateDiagramCollection*>::iterator it=
old_diags.begin(); it != old_diags.end(); it++)
delete *it;
delete MainScriptConfig.diags;
}
int DSMFactory::onLoad()
@ -117,7 +118,118 @@ int DSMFactory::onLoad()
// get application specific global parameters
configureModule(cfg);
DebugDSM = cfg.getParameter("debug_raw_dsm") == "yes";
if (!loadPrompts(cfg))
return -1;
if (!loadPromptSets(cfg))
return -1;
if (!loadDiags(cfg, MainScriptConfig.diags))
return -1;
vector<string> registered_apps;
if (!registerApps(cfg, MainScriptConfig.diags, registered_apps))
return -1;
InboundStartDiag = cfg.getParameter("inbound_start_diag");
if (InboundStartDiag.empty()) {
INFO("no 'inbound_start_diag' set in config. "
"inbound calls with application 'dsm' disabled.\n");
}
OutboundStartDiag = cfg.getParameter("outbound_start_diag");
if (OutboundStartDiag.empty()) {
INFO("no 'outbound_start_diag' set in config. "
"outbound calls with application 'dsm' disabled.\n");
}
if (!InboundStartDiag.empty())
AmPlugIn::instance()->registerFactory4App("dsm",this);
MainScriptConfig.config_vars.insert(cfg.begin(), cfg.end());
// for (std::map<string,string>::const_iterator it =
// cfg.begin(); it != cfg.end(); it++)
// MainScriptConfig.config_vars[it->first] = it->second;
MainScriptConfig.RunInviteEvent = cfg.getParameter("run_invite_event")=="yes";
MainScriptConfig.SetParamVariables = cfg.getParameter("set_param_variables")=="yes";
#ifdef USE_MONITORING
string monitoring_full_callgraph = cfg.getParameter("monitoring_full_stategraph");
MonitoringFullCallgraph = monitoring_full_callgraph == "yes";
DBG("%sogging full call graph (states) to monitoring.\n",
MonitoringFullCallgraph?"L":"Not l");
string monitoring_full_transitions = cfg.getParameter("monitoring_full_transitions");
MonitoringFullTransitions = monitoring_full_transitions == "yes";
DBG("%sogging full call graph (transitions) to monitoring.\n",
MonitoringFullTransitions?"L":"Not l");
string cfg_usecaller = cfg.getParameter("monitor_select_use_caller");
if (cfg_usecaller.empty() || cfg_usecaller=="from")
MonSelectCaller = MonSelect_FROM;
else if (cfg_usecaller=="no")
MonSelectCaller = MonSelect_NONE;
else if (cfg_usecaller=="pai")
MonSelectCaller = MonSelect_PAI;
else {
ERROR("monitor_select_use_caller value '%s' not understood\n",
cfg_usecaller.c_str());
}
string cfg_usecallee = cfg.getParameter("monitor_select_use_callee");
if (cfg_usecallee.empty() || cfg_usecallee=="ruri")
MonSelectCallee = MonSelect_RURI;
else if (cfg_usecallee=="no")
MonSelectCallee = MonSelect_NONE;
else if (cfg_usecallee=="from")
MonSelectCallee = MonSelect_FROM;
else {
ERROR("monitor_select_use_callee value '%s' not understood\n",
cfg_usecallee.c_str());
}
#endif
string conf_d_dir = cfg.getParameter("conf_dir");
if (!conf_d_dir.empty()) {
if (conf_d_dir[conf_d_dir.length()-1] != '/')
conf_d_dir += '/';
DBG("processing configurations in '%s'...\n", conf_d_dir.c_str());
int err=0;
struct dirent* entry;
DIR* dir = opendir(conf_d_dir.c_str());
if(!dir){
ERROR("config loader (%s): %s\n",
conf_d_dir.c_str(), strerror(errno));
return -1;
}
while( ((entry = readdir(dir)) != NULL) && (err == 0) ){
string conf_name = string(entry->d_name);
if(conf_name.find(".conf",conf_name.length()-5) == string::npos ){
continue;
}
string conf_file_name = conf_d_dir + conf_name;
DBG("loading %s ...\n",conf_file_name.c_str());
if (!loadConfig(conf_file_name, conf_name, false, NULL))
return -1;
}
}
return 0;
}
bool DSMFactory::loadPrompts(AmConfigReader& cfg) {
vector<string> prompts_files =
explode(cfg.getParameter("load_prompts"), ",");
for (vector<string>::iterator it=
@ -152,8 +264,12 @@ int DSMFactory::onLoad()
}
}
if (!has_all_prompts)
return -1;
return false;
return true;
}
bool DSMFactory::loadPromptSets(AmConfigReader& cfg) {
string prompt_sets_path = cfg.getParameter("prompts_sets_path");
vector<string> prompt_sets_names =
@ -183,9 +299,10 @@ int DSMFactory::onLoad()
}
prompt_sets[*it] = pc;
}
return true;
}
DebugDSM = cfg.getParameter("debug_raw_dsm") == "yes";
bool DSMFactory::loadDiags(AmConfigReader& cfg, DSMStateDiagramCollection* m_diags) {
string DiagPath = cfg.getParameter("diag_path");
if (DiagPath.length() && DiagPath[DiagPath.length()-1] != '/')
DiagPath += '/';
@ -196,7 +313,7 @@ int DSMFactory::onLoad()
int res = preloadModules(cfg, err, ModPath);
if (res<0) {
ERROR("%s\n", err.c_str());
return res;
return false;
}
// todo: pass preloaded mods to chart reader
@ -205,18 +322,23 @@ int DSMFactory::onLoad()
vector<string> diags_names = explode(LoadDiags, ",");
for (vector<string>::iterator it=
diags_names.begin(); it != diags_names.end(); it++) {
if (!diags->loadFile(DiagPath+*it+".dsm", *it, ModPath, DebugDSM)) {
if (!m_diags->loadFile(DiagPath+*it+".dsm", *it, ModPath, DebugDSM)) {
ERROR("loading %s from %s\n",
it->c_str(), (DiagPath+*it+".dsm").c_str());
return -1;
return false;
}
}
return true;
}
bool DSMFactory::registerApps(AmConfigReader& cfg, DSMStateDiagramCollection* m_diags,
vector<string>& register_names) {
string RegisterDiags = cfg.getParameter("register_apps");
vector<string> register_names = explode(RegisterDiags, ",");
register_names = explode(RegisterDiags, ",");
for (vector<string>::iterator it=
register_names.begin(); it != register_names.end(); it++) {
if (diags->hasDiagram(*it)) {
if (m_diags->hasDiagram(*it)) {
bool res = AmPlugIn::instance()->registerFactory4App(*it,this);
if(res)
INFO("DSM state machine registered: %s.\n",
@ -224,69 +346,101 @@ int DSMFactory::onLoad()
} else {
ERROR("trying to register application '%s' which is not loaded.\n",
it->c_str());
return -1;
return false;
}
}
return true;
}
InboundStartDiag = cfg.getParameter("inbound_start_diag");
if (InboundStartDiag.empty() && register_names.empty()) {
INFO("no 'inbound_start_diag' set in config. inbound calls with application 'dsm' disabled.\n");
}
OutboundStartDiag = cfg.getParameter("outbound_start_diag");
if (OutboundStartDiag.empty() && register_names.empty()) {
INFO("no 'outbound_start_diag' set in config. outbound calls with application 'dsm' disabled.\n");
// DI interface function
void DSMFactory::loadConfig(const AmArg& args, AmArg& ret) {
string file_name = args.get(0).asCStr();
string diag_name = args.get(1).asCStr();
if (loadConfig(file_name, diag_name, true, NULL)) {
ret.push(200);
ret.push("OK");
} else {
ret.push(500);
ret.push("reload config failed");
}
}
if (!InboundStartDiag.empty() || OutboundStartDiag.empty())
AmPlugIn::instance()->registerFactory4App("dsm",this);
bool DSMFactory::loadConfig(const string& conf_file_name, const string& conf_name,
bool live_reload, DSMStateDiagramCollection* m_diags) {
for (std::map<string,string>::const_iterator it =
cfg.begin(); it != cfg.end(); it++)
config[it->first] = it->second;
string script_name = conf_name.substr(0, conf_name.length()-5); // - .conf
DBG("loading %s from %s ...\n", script_name.c_str(), conf_file_name.c_str());
AmConfigReader cfg;
if(cfg.loadFile(conf_file_name))
return false;
RunInviteEvent = cfg.getParameter("run_invite_event")=="yes";
DSMScriptConfig script_config;
script_config.RunInviteEvent =
cfg.getParameter("run_invite_event")=="yes";
SetParamVariables = cfg.getParameter("set_param_variables")=="yes";
script_config.SetParamVariables =
cfg.getParameter("set_param_variables")=="yes";
#ifdef USE_MONITORING
string monitoring_full_callgraph = cfg.getParameter("monitoring_full_stategraph");
MonitoringFullCallgraph = monitoring_full_callgraph == "yes";
DBG("%sogging full call graph (states) to monitoring.\n",
MonitoringFullCallgraph?"L":"Not l");
script_config.config_vars.insert(cfg.begin(), cfg.end());
string monitoring_full_transitions = cfg.getParameter("monitoring_full_transitions");
MonitoringFullTransitions = monitoring_full_transitions == "yes";
DBG("%sogging full call graph (transitions) to monitoring.\n",
MonitoringFullTransitions?"L":"Not l");
if (live_reload) {
INFO("live DSM config reload does NOT reload prompts and prompt sets!\n");
INFO("(see http://tracker.iptel.org/browse/SEMS-67)\n");
} else {
if (!loadPrompts(cfg))
return false;
string cfg_usecaller = cfg.getParameter("monitor_select_use_caller");
if (cfg_usecaller.empty() || cfg_usecaller=="from")
MonSelectCaller = MonSelect_FROM;
else if (cfg_usecaller=="no")
MonSelectCaller = MonSelect_NONE;
else if (cfg_usecaller=="pai")
MonSelectCaller = MonSelect_PAI;
else {
ERROR("monitor_select_use_caller value '%s' not understood\n",
cfg_usecaller.c_str());
if (!loadPromptSets(cfg))
return false;
}
string cfg_usecallee = cfg.getParameter("monitor_select_use_callee");
if (cfg_usecallee.empty() || cfg_usecallee=="ruri")
MonSelectCallee = MonSelect_RURI;
else if (cfg_usecallee=="no")
MonSelectCallee = MonSelect_NONE;
else if (cfg_usecallee=="from")
MonSelectCallee = MonSelect_FROM;
DSMStateDiagramCollection* used_diags;
if (m_diags != NULL)
used_diags = m_diags; // got this from caller (main diags)
else {
ERROR("monitor_select_use_callee value '%s' not understood\n",
cfg_usecallee.c_str());
// create a new set of diags
used_diags = script_config.diags = new DSMStateDiagramCollection();
}
#endif
return 0;
if (!loadDiags(cfg, used_diags))
return false;
vector<string> registered_apps;
if (!registerApps(cfg, used_diags, registered_apps))
return false;
ScriptConfigs_mut.lock();
try {
// set ScriptConfig to this for all registered apps' names
for (vector<string>::iterator reg_app_it=
registered_apps.begin(); reg_app_it != registered_apps.end(); reg_app_it++) {
string& app_name = *reg_app_it;
// dispose of the old one, if it exists
map<string, DSMScriptConfig>::iterator it=ScriptConfigs.find(app_name);
if (it != ScriptConfigs.end()) {
// may be in use by active call - don't delete but save to
// old_diags for garbage collection (destructor)
if (it->second.diags != NULL)
old_diags.insert(it->second.diags);
}
// overwrite with new config
ScriptConfigs[app_name] = script_config;
DBG("-------------------------- inserting script config with diags [%p] for '%s'\n",
script_config.diags, app_name.c_str());
}
} catch(...) {
ScriptConfigs_mut.unlock();
throw;
}
ScriptConfigs_mut.unlock();
return true;
}
void DSMFactory::prepareSession(DSMCall* s) {
s->setPromptSets(prompt_sets);
}
@ -436,7 +590,8 @@ AmSession* DSMFactory::onInvite(const AmSipRequest& req)
vars["mon_session_record"] = session_id;
#else
ERROR("using $(mon_select) for dsm application, but compiled without monitoring support!\n");
ERROR("using $(mon_select) for dsm application, "
"but compiled without monitoring support!\n");
throw AmSession::Exception(488, "Not Acceptable Here");
#endif
} else {
@ -445,17 +600,29 @@ AmSession* DSMFactory::onInvite(const AmSipRequest& req)
} else {
start_diag = req.cmd;
}
diags_mut.lock();
DSMCall* s = new DSMCall(&prompts, *diags, start_diag, NULL);
diags_mut.unlock();
// determine run configuration for script
DSMScriptConfig call_config;
ScriptConfigs_mut.lock();
map<string, DSMScriptConfig>::iterator sc=ScriptConfigs.find(start_diag);
if (sc == ScriptConfigs.end())
call_config = MainScriptConfig;
else
call_config = sc->second;
DBG("-------------------------- using script config with diags [%p] for '%s'\n",
call_config.diags, start_diag.c_str());
DSMCall* s = new DSMCall(call_config, &prompts, *call_config.diags, start_diag, NULL);
ScriptConfigs_mut.unlock();
prepareSession(s);
addVariables(s, "config.", config);
addVariables(s, "config.", call_config.config_vars);
if (SetParamVariables)
if (call_config.SetParamVariables)
addParams(s, req.hdrs);
if (!vars.empty())
addVariables(s, "", vars);
@ -503,14 +670,25 @@ AmSession* DSMFactory::onInvite(const AmSipRequest& req,
AmArg2DSMStrMap(session_params, vars);
}
DSMCall* s = new DSMCall(&prompts, *diags, start_diag, cred);
DSMScriptConfig call_config;
ScriptConfigs_mut.lock();
map<string, DSMScriptConfig>::iterator sc=ScriptConfigs.find(start_diag);
if (sc == ScriptConfigs.end())
call_config = MainScriptConfig;
else
call_config = sc->second;
DSMCall* s = new DSMCall(call_config, &prompts, *call_config.diags, start_diag, cred);
ScriptConfigs_mut.unlock();
prepareSession(s);
addVariables(s, "config.", config);
addVariables(s, "config.", call_config.config_vars);
if (!vars.empty())
addVariables(s, "", vars);
if (SetParamVariables)
if (call_config.SetParamVariables)
addParams(s, req.hdrs);
if (NULL == cred) {
@ -560,10 +738,10 @@ void DSMFactory::reloadDSMs(const AmArg& args, AmArg& ret) {
return;
}
}
diags_mut.lock();
old_diags.push_back(diags);
diags = new_diags;
diags_mut.unlock();
ScriptConfigs_mut.lock();
old_diags.insert(MainScriptConfig.diags);
MainScriptConfig.diags = new_diags;
ScriptConfigs_mut.unlock();
ret.push(200);
ret.push("DSMs reloaded");
@ -638,19 +816,62 @@ void DSMFactory::preloadModule(const AmArg& args, AmArg& ret) {
}
void DSMFactory::listDSMs(const AmArg& args, AmArg& ret) {
diags_mut.lock();
vector<string> names = diags->getDiagramNames();
diags_mut.unlock();
vector<string> names;
ScriptConfigs_mut.lock();
try {
if (isArgUndef(args) || !args.size())
names = MainScriptConfig.diags->getDiagramNames();
else {
if (isArgCStr(args.get(0))) {
map<string, DSMScriptConfig>::iterator i=
ScriptConfigs.find(args.get(0).asCStr());
if (i!= ScriptConfigs.end())
names = i->second.diags->getDiagramNames();
}
}
} catch (...) {
ScriptConfigs_mut.unlock();
throw;
}
ScriptConfigs_mut.unlock();
for (vector<string>::iterator it=
names.begin(); it != names.end(); it++) {
ret.push(*it);
}
}
bool DSMFactory::hasDSM(const string& dsm_name, const string& conf_name) {
bool res = false;
if (conf_name.empty())
res = MainScriptConfig.diags->hasDiagram(dsm_name);
else {
map<string, DSMScriptConfig>::iterator i=
ScriptConfigs.find(conf_name);
if (i!= ScriptConfigs.end())
res = i->second.diags->hasDiagram(dsm_name);
}
return res;
}
void DSMFactory::hasDSM(const AmArg& args, AmArg& ret) {
diags_mut.lock();
bool res = diags->hasDiagram(args.get(0).asCStr());
diags_mut.unlock();
string conf_name;
if (args.size()>1 && isArgCStr(args.get(1)))
conf_name = args.get(1).asCStr();
bool res;
ScriptConfigs_mut.lock();
try {
res = hasDSM(args.get(0).asCStr(), conf_name);
} catch(...) {
ScriptConfigs_mut.unlock();
throw;
}
ScriptConfigs_mut.unlock();
if (res)
ret.push("1");
else
@ -659,9 +880,20 @@ void DSMFactory::hasDSM(const AmArg& args, AmArg& ret) {
void DSMFactory::registerApplication(const AmArg& args, AmArg& ret) {
string diag_name = args.get(0).asCStr();
diags_mut.lock();
bool has_diag = diags->hasDiagram(diag_name);
diags_mut.unlock();
string conf_name;
if (args.size()>1 && isArgCStr(args.get(1)))
conf_name = args.get(1).asCStr();
bool has_diag;
ScriptConfigs_mut.lock();
try {
has_diag = hasDSM(diag_name, conf_name);
} catch(...) {
ScriptConfigs_mut.unlock();
throw;
}
ScriptConfigs_mut.unlock();
if (!has_diag) {
ret.push(400);
ret.push("unknown application (DSM)");
@ -697,20 +929,26 @@ void DSMFactory::loadDSM(const AmArg& args, AmArg& ret) {
string dsm_file_name = DiagPath+dsm_name+".dsm";
string res = "OK";
diags_mut.lock();
if (diags->hasDiagram(dsm_name)) {
ret.push(400);
ret.push("DSM named '" + dsm_name + "' already loaded (use reloadDSMs to reload all)");
} else {
if (!diags->loadFile(dsm_file_name, dsm_name, ModPath, DebugDSM)) {
ret.push(500);
ret.push("error loading "+dsm_name+" from "+ dsm_file_name);
ScriptConfigs_mut.lock();
try {
if (MainScriptConfig.diags->hasDiagram(dsm_name)) {
ret.push(400);
ret.push("DSM named '" + dsm_name + "' already loaded (use reloadDSMs to reload all)");
} else {
ret.push(200);
ret.push("loaded "+dsm_name+" from "+ dsm_file_name);
if (!MainScriptConfig.diags->loadFile(dsm_file_name, dsm_name, ModPath, DebugDSM)) {
ret.push(500);
ret.push("error loading "+dsm_name+" from "+ dsm_file_name);
} else {
ret.push(200);
ret.push("loaded "+dsm_name+" from "+ dsm_file_name);
}
}
} catch(...) {
ScriptConfigs_mut.unlock();
throw;
}
diags_mut.unlock();
ScriptConfigs_mut.unlock();
}
void DSMFactory::loadDSMWithPaths(const AmArg& args, AmArg& ret) {
@ -719,20 +957,25 @@ void DSMFactory::loadDSMWithPaths(const AmArg& args, AmArg& ret) {
string mod_path = args.get(2).asCStr();
string res = "OK";
diags_mut.lock();
if (diags->hasDiagram(dsm_name)) {
ret.push(400);
ret.push("DSM named '" + dsm_name + "' already loaded (use reloadDSMs to reload all)");
} else {
if (!diags->loadFile(diag_path+dsm_name+".dsm", dsm_name, mod_path, DebugDSM)) {
ret.push(500);
ret.push("error loading "+dsm_name+" from "+ diag_path+dsm_name+".dsm");
ScriptConfigs_mut.lock();
try {
if (MainScriptConfig.diags->hasDiagram(dsm_name)) {
ret.push(400);
ret.push("DSM named '" + dsm_name + "' already loaded (use reloadDSMs to reload all)");
} else {
ret.push(200);
ret.push("loaded "+dsm_name+" from "+ diag_path+dsm_name+".dsm");
if (!MainScriptConfig.diags->loadFile(diag_path+dsm_name+".dsm", dsm_name, mod_path, DebugDSM)) {
ret.push(500);
ret.push("error loading "+dsm_name+" from "+ diag_path+dsm_name+".dsm");
} else {
ret.push(200);
ret.push("loaded "+dsm_name+" from "+ diag_path+dsm_name+".dsm");
}
}
} catch(...) {
ScriptConfigs_mut.unlock();
throw;
}
diags_mut.unlock();
ScriptConfigs_mut.unlock();
}
void DSMFactory::invoke(const string& method, const AmArg& args,
@ -773,6 +1016,9 @@ void DSMFactory::invoke(const string& method, const AmArg& args,
} else if (method == "registerApplication"){
args.assertArrayFmt("s");
registerApplication(args,ret);
} else if (method == "loadConfig"){
args.assertArrayFmt("ss");
loadConfig(args,ret);
} else if(method == "_list"){
ret.push(AmArg("postDSMEvent"));
ret.push(AmArg("reloadDSMs"));
@ -780,6 +1026,7 @@ void DSMFactory::invoke(const string& method, const AmArg& args,
ret.push(AmArg("loadDSMWithPaths"));
ret.push(AmArg("preloadModules"));
ret.push(AmArg("preloadModule"));
ret.push(AmArg("loadConfig"));
ret.push(AmArg("hasDSM"));
ret.push(AmArg("listDSMs"));
ret.push(AmArg("registerApplication"));

@ -42,6 +42,8 @@ using std::string;
#include <memory>
#include <set>
enum MonSelectType {
MonSelect_NONE,
MonSelect_RURI,
@ -60,16 +62,18 @@ class DSMFactory
public AmEventQueueInterface
{
AmPromptCollection prompts;
DSMStateDiagramCollection* diags;
AmMutex diags_mut;
AmMutex main_diags_mut;
vector<DSMStateDiagramCollection*> old_diags;
std::set<DSMStateDiagramCollection*> old_diags;
static bool DebugDSM;
static string InboundStartDiag;
static string OutboundStartDiag;
DSMScriptConfig MainScriptConfig;
map<string, DSMScriptConfig> ScriptConfigs;
AmMutex ScriptConfigs_mut;
#ifdef USE_MONITORING
static MonSelectType MonSelectCaller;
@ -81,6 +85,16 @@ class DSMFactory
~DSMFactory();
bool loaded;
int preloadModules(AmConfigReader& cfg, string& res, const string& ModPath);
bool loadConfig(const string& conf_file_name, const string& conf_name,
bool live_reload, DSMStateDiagramCollection* m_diags);
bool loadDiags(AmConfigReader& cfg, DSMStateDiagramCollection* m_diags);
bool registerApps(AmConfigReader& cfg, DSMStateDiagramCollection* m_diags,
vector<string>& register_names /* out */);
bool loadPromptSets(AmConfigReader& cfg);
bool loadPrompts(AmConfigReader& cfg);
bool hasDSM(const string& dsm_name, const string& conf_name);
map<string, AmPromptCollection*> prompt_sets;
void prepareSession(DSMCall* s);
void addVariables(DSMCall* s, const string& prefix,
@ -97,16 +111,11 @@ class DSMFactory
void loadDSM(const AmArg& args, AmArg& ret);
void loadDSMWithPaths(const AmArg& args, AmArg& ret);
void registerApplication(const AmArg& args, AmArg& ret);
int preloadModules(AmConfigReader& cfg, string& res, const string& ModPath);
void loadConfig(const AmArg& args, AmArg& ret);
public:
static DSMFactory* instance();
static map<string, string> config;
static bool RunInviteEvent;
static bool SetParamVariables;
#ifdef USE_MONITORING
static bool MonitoringFullCallgraph;
static bool MonitoringFullTransitions;

@ -30,14 +30,17 @@
#include "AmMediaProcessor.h"
#include "DSM.h"
DSMCall::DSMCall(AmPromptCollection* prompts,
DSMStateDiagramCollection& diags,
const string& startDiagName,
UACAuthCred* credentials)
: prompts(prompts), default_prompts(prompts), startDiagName(startDiagName),
playlist(this), cred(credentials),
rec_file(NULL),
process_invite(true), process_sessionstart(true)
DSMCall::DSMCall(const DSMScriptConfig& config,
AmPromptCollection* prompts,
DSMStateDiagramCollection& diags,
const string& startDiagName,
UACAuthCred* credentials)
:
run_invite_event(config.RunInviteEvent),
prompts(prompts), default_prompts(prompts), startDiagName(startDiagName),
playlist(this), cred(credentials),
rec_file(NULL),
process_invite(true), process_sessionstart(true)
{
diags.addToEngine(&engine);
set_sip_relay_only(false);
@ -81,7 +84,7 @@ void DSMCall::onInvite(const AmSipRequest& req) {
bool run_session_invite = engine.onInvite(req, this);
if (DSMFactory::RunInviteEvent) {
if (run_invite_event) {
if (!engine.init(this, startDiagName, DSMCondition::Invite))
run_session_invite =false;
@ -107,7 +110,7 @@ void DSMCall::onOutgoingInvite(const string& headers) {
req.hdrs = headers;
bool run_session_invite = engine.onInvite(req, this);
if (DSMFactory::RunInviteEvent) {
if (run_invite_event) {
if (!engine.init(this, startDiagName, DSMCondition::Invite))
run_session_invite =false;

@ -49,6 +49,8 @@ class DSMCall : public AmB2BCallerSession,
string startDiagName;
AmPlaylist playlist;
bool run_invite_event;
bool process_invite;
bool process_sessionstart;
@ -62,10 +64,11 @@ class DSMCall : public AmB2BCallerSession,
bool checkVar(const string& var_name, const string& var_val);
public:
DSMCall(AmPromptCollection* prompts,
DSMStateDiagramCollection& diags,
const string& startDiagName,
UACAuthCred* credentials = NULL);
DSMCall(const DSMScriptConfig& config,
AmPromptCollection* prompts,
DSMStateDiagramCollection& diags,
const string& startDiagName,
UACAuthCred* credentials = NULL);
~DSMCall();
void onInvite(const AmSipRequest& req);

@ -117,6 +117,15 @@ class DSMSession {
std::auto_ptr<AmSipRequest> last_req;
};
class DSMStateDiagramCollection;
struct DSMScriptConfig {
DSMStateDiagramCollection* diags;
map<string,string> config_vars;
bool RunInviteEvent;
bool SetParamVariables;
};
class DSMDisposable {
public:

@ -68,13 +68,16 @@ postDSMEvent(string call_id, [ [[param0,val0],[param1,val1],...] ]
reloadDSMs()
reload all DSMs from config file (load_diags)
reload all DSMs from config file (load_diags) from main config
- DSM is loaded with main config
loadDSM(string diag_name)
load DSM with name diag_name, paths are taken from config file
- DSM is loaded with main config
loadDSMWithPaths(string diag_name, string diag_path, string mod_path)
load DSM with specified paths
- DSM is loaded with main config
preloadModules()
preload all modules specified in config file (preload_mods)
@ -82,16 +85,24 @@ preloadModules()
preloadModule(string mod_name, string mod_path)
preload module from specific path
hasDSM(string diag_name)
hasDSM(string diag_name, [string config])
returns 1 if DSM with diag_name is loaded, 0 if not
if config empty or not given, DSM of main config will be listed
listDSMs()
listDSMs([string config])
return list of loaded DSMs
if config empty or not given, DSM of main config will be listed
registerApplication(string diag_name)
registerApplication(string diag_name, [string config])
register DSM with name diag_name as application in SEMS
(e.g. to be used with application=$(apphdr), $(ruri.param)
or $(ruri.user)
if config empty or not given, DSM is assumed to be in main config
loadConfig(string conf_file_name, string conf_name)
(re)load application configuration and script
like a file in conf_dir
More info
=========

@ -95,3 +95,17 @@ load_prompts=/usr/local/etc/sems/etc/dsm_in_prompts.conf,/usr/local/etc/sems/etc
#
#monitor_select_use_callee=no
# conf_dir=<path>
#
# <path> is scanned for *.conf files. Every .conf
# file is loaded, and in the .conf file, the following
# DSM config parameters are processed:
# diag_path=
# load_diags=
# register_apps=
# mod_path=
# preload_mods=
# run_invite_event=
#
#
#

Loading…
Cancel
Save