Author: sayer
Date: 2008-10-14 21:41:23 +0200 (Tue, 14 Oct 2008)
New Revision: 1113
Modified:
trunk/apps/dsm/DSM.cpp
trunk/apps/dsm/DSM.h
trunk/apps/dsm/DSMChartReader.cpp
trunk/apps/dsm/DSMChartReader.h
trunk/apps/dsm/DSMCoreModule.cpp
trunk/apps/dsm/DSMCoreModule.h
trunk/apps/dsm/DSMDialog.cpp
trunk/apps/dsm/DSMDialog.h
trunk/apps/dsm/DSMModule.h
trunk/apps/dsm/DSMSession.h
trunk/apps/dsm/DSMStateDiagramCollection.cpp
trunk/apps/dsm/DSMStateDiagramCollection.h
trunk/apps/dsm/DSMStateEngine.cpp
trunk/apps/dsm/DSMStateEngine.h
trunk/apps/dsm/doc/dsm_syntax.txt
trunk/apps/dsm/etc/dsm.conf
Log:
- session init function for modules (onInvite)
- module 'preload' function (preload_mods config parameter)
- selectable prompt sets (each from their config file)
Modified: trunk/apps/dsm/DSM.cpp
===================================================================
--- trunk/apps/dsm/DSM.cpp 2008-10-14 19:26:38 UTC (rev 1112)
+++ trunk/apps/dsm/DSM.cpp 2008-10-14 19:41:23 UTC (rev 1113)
@@ -31,6 +31,7 @@
#include "log.h"
#include "AmConfigReader.h"
#include "DSMDialog.h"
+#include "DSMChartReader.h"
#include <string>
#include <fstream>
@@ -54,6 +55,7 @@
string DSMFactory::InboundStartDiag;
string DSMFactory::OutboundStartDiag;
+map<string, string> DSMFactory::config;
DSMFactory::DSMFactory(const string& _app_name)
: AmSessionFactory(_app_name),
@@ -61,6 +63,12 @@
{
}
+DSMFactory::~DSMFactory() {
+ for (map<string, AmPromptCollection*>::iterator it=
+ prompt_sets.begin(); it != prompt_sets.end(); it++)
+ delete it->second;
+}
+
int DSMFactory::onLoad()
{
if (loaded)
@@ -95,12 +103,61 @@
}
}
+ string prompt_sets_path = cfg.getParameter("prompts_sets_path");
+
+ vector<string> prompt_sets_names =
+ explode(cfg.getParameter("load_prompts_sets"), ",");
+ for (vector<string>::iterator it=
+ prompt_sets_names.begin(); it != prompt_sets_names.end(); it++) {
+ string fname = prompt_sets_path.empty() ? "": prompt_sets_path + "/";
+ fname += *it;
+ DBG("loading prompts for '%s' (file '%s')\n", it->c_str(), fname.c_str());
+ std::ifstream ifs(fname.c_str());
+ string s;
+ if (!ifs.good()) {
+ WARN("prompts set file '%s' could not be read\n", fname.c_str());
+ }
+ AmPromptCollection* pc = new AmPromptCollection();
+ while (ifs.good() && !ifs.eof()) {
+ getline(ifs, s);
+ if (s.length() && s.find_first_not_of(" \t")!= string::npos &&
+ s[s.find_first_not_of(" \t")] != '#') {
+ vector<string> p=explode(s, "=");
+ if (p.size()==2) {
+ pc->setPrompt(p[0], p[1], MOD_NAME);
+ DBG("set '%s' added prompt '%s' as '%s'\n",
+ it->c_str(), p[0].c_str(), p[1].c_str());
+ }
+ }
+ }
+ prompt_sets[*it] = pc;
+ }
+
string DiagPath = cfg.getParameter("diag_path");
if (DiagPath.length() && DiagPath[DiagPath.length()-1] != '/')
DiagPath += '/';
string ModPath = cfg.getParameter("mod_path");
+ string preload_mods = cfg.getParameter("preload_mods");
+ vector<string> preload_names = explode(preload_mods, ",");
+ if (preload_names.size()) {
+ DSMChartReader reader;
+ for (vector<string>::iterator it=
+ preload_names.begin(); it != preload_names.end(); it++) {
+ DBG("preloading '%s'...\n");
+ if (!reader.importModule("import("+*it+")", ModPath)) {
+ ERROR("importing module '%s' for preload\n", it->c_str());
+ return -1;
+ }
+ DSMModule* last_loaded = reader.mods.back();
+ if (last_loaded) {
+ last_loaded->preload();
+ }
+ }
+ }
+ // TODO: pass preloaded mods to chart reader
+
string LoadDiags = cfg.getParameter("load_diags");
vector<string> diags_names = explode(LoadDiags, ",");
for (vector<string>::iterator it=
@@ -121,9 +178,19 @@
INFO("no 'outbound_start_diag' set in config. outbound calls disabled.\n");
}
+ for (std::map<string,string>::const_iterator it =
+ cfg.begin(); it != cfg.end(); it++)
+ config[it->first] = it->second;
+
return 0;
}
+void DSMFactory::prepareSession(DSMDialog* s) {
+ s->setPromptSets(prompt_sets);
+ for (map<string, string>::iterator it =
+ config.begin(); it != config.end(); it++)
+ s->var["config."+it->first] = it->second;
+}
AmSession* DSMFactory::onInvite(const AmSipRequest& req)
{
@@ -131,7 +198,9 @@
ERROR("no inbound calls allowed\n");
throw AmSession::Exception(488, "Not Acceptable Here");
}
- return new DSMDialog(prompts, diags, InboundStartDiag, NULL);
+ DSMDialog* s = new DSMDialog(prompts, diags, InboundStartDiag, NULL);
+ prepareSession(s);
+ return s;
}
AmSession* DSMFactory::onInvite(const AmSipRequest& req,
@@ -149,8 +218,9 @@
cred = dynamic_cast<UACAuthCred*>(cred_obj);
}
- AmSession* s = new DSMDialog(prompts, diags, OutboundStartDiag, cred);
-
+ DSMDialog* s = new DSMDialog(prompts, diags, OutboundStartDiag, cred);
+ prepareSession(s);
+
if (NULL == cred) {
WARN("discarding unknown session parameters.\n");
} else {
Modified: trunk/apps/dsm/DSM.h
===================================================================
--- trunk/apps/dsm/DSM.h 2008-10-14 19:26:38 UTC (rev 1112)
+++ trunk/apps/dsm/DSM.h 2008-10-14 19:41:23 UTC (rev 1113)
@@ -42,6 +42,8 @@
#include <memory>
+class DSMDialog;
+
/** \brief Factory for announcement sessions */
class DSMFactory
: public AmSessionFactory
@@ -54,10 +56,16 @@
static DSMFactory* _instance;
DSMFactory(const string& _app_name);
+ ~DSMFactory();
bool loaded;
+
+ map<string, AmPromptCollection*> prompt_sets;
+ void prepareSession(DSMDialog* s);
+
public:
static DSMFactory* instance();
+ static map<string, string> config;
int onLoad();
AmSession* onInvite(const AmSipRequest& req);
Modified: trunk/apps/dsm/DSMChartReader.cpp
===================================================================
--- trunk/apps/dsm/DSMChartReader.cpp 2008-10-14 19:26:38 UTC (rev 1112)
+++ trunk/apps/dsm/DSMChartReader.cpp 2008-10-14 19:41:23 UTC (rev 1113)
@@ -171,7 +171,8 @@
}
bool DSMChartReader::decode(DSMStateDiagram* e, const string& chart,
- const string& mod_path, DSMElemContainer* owner) {
+ const string& mod_path, DSMElemContainer* owner,
+ vector<DSMModule*>& out_mods) {
vector<DSMElement*> stack;
size_t pos = 0;
while (pos < chart.length()) {
@@ -389,6 +390,11 @@
continue;
}
}
+
+ for (vector<DSMModule*>::iterator it=
+ mods.begin(); it != mods.end(); it++)
+ out_mods.push_back(*it);
+
return true;
}
Modified: trunk/apps/dsm/DSMChartReader.h
===================================================================
--- trunk/apps/dsm/DSMChartReader.h 2008-10-14 19:26:38 UTC (rev 1112)
+++ trunk/apps/dsm/DSMChartReader.h 2008-10-14 19:41:23 UTC (rev 1113)
@@ -90,7 +90,10 @@
DSMChartReader();
~DSMChartReader();
bool decode(DSMStateDiagram* e, const string& chart,
- const string& mod_path, DSMElemContainer* owner);
+ const string& mod_path, DSMElemContainer* owner,
+ vector<DSMModule*>& out_mods);
+
+ friend class DSMFactory;
};
#endif
Modified: trunk/apps/dsm/DSMCoreModule.cpp
===================================================================
--- trunk/apps/dsm/DSMCoreModule.cpp 2008-10-14 19:26:38 UTC (rev 1112)
+++ trunk/apps/dsm/DSMCoreModule.cpp 2008-10-14 19:41:23 UTC (rev 1113)
@@ -73,6 +73,7 @@
DEF_CMD("stop", SCStopAction);
DEF_CMD("playPrompt", SCPlayPromptAction);
+ DEF_CMD("playPromptLooped", SCPlayPromptLoopedAction);
DEF_CMD("playFile", SCPlayFileAction);
DEF_CMD("recordFile", SCRecordFileAction);
DEF_CMD("stopRecord", SCStopRecordAction);
@@ -84,6 +85,8 @@
DEF_CMD("setTimer", SCSetTimerAction);
+ DEF_CMD("setPrompts", SCSetPromptsAction);
+
if (cmd == "DI") {
SCDIAction * a = new SCDIAction(params, false);
a->name = from_str;
@@ -184,6 +187,23 @@
return false;
}
+
+bool SCSetPromptsAction::execute(AmSession* sess,
+ DSMCondition::EventType event,
+ map<string,string>* event_params) {
+ GET_SCSESSION();
+ sc_sess->setPromptSet(resolveVars(arg, sess, sc_sess, event_params));
+ return false;
+}
+
+bool SCPlayPromptLoopedAction::execute(AmSession* sess,
+ DSMCondition::EventType event,
+ map<string,string>* event_params) {
+ GET_SCSESSION();
+ sc_sess->playPrompt(resolveVars(arg, sess, sc_sess, event_params), true);
+ return false;
+}
+
bool SCPlayFileAction::execute(AmSession* sess,
DSMCondition::EventType event,
map<string,string>* event_params) {
@@ -282,7 +302,7 @@
return false;
}
string l_line = resolveVars(par2, sess, sc_sess, event_params).c_str();
- _LOG((int)lvl, "FSM: %s %s\n", (par2 != l_line)?par2.c_str():"",
+ _LOG((int)lvl, "FSM: %s '%s'\n", (par2 != l_line)?par2.c_str():"",
l_line.c_str());
return false;
}
Modified: trunk/apps/dsm/DSMCoreModule.h
===================================================================
--- trunk/apps/dsm/DSMCoreModule.h 2008-10-14 19:26:38 UTC (rev 1112)
+++ trunk/apps/dsm/DSMCoreModule.h 2008-10-14 19:41:23 UTC (rev 1113)
@@ -50,10 +50,12 @@
};
DEF_SCStrArgAction(SCPlayPromptAction);
+DEF_SCStrArgAction(SCPlayPromptLoopedAction);
DEF_SCStrArgAction(SCRecordFileAction);
DEF_SCStrArgAction(SCStopRecordAction);
DEF_SCStrArgAction(SCClosePlaylistAction);
DEF_SCStrArgAction(SCStopAction);
+DEF_SCStrArgAction(SCSetPromptsAction);
DEF_SCModSEStrArgAction(SCRepostAction);
DEF_SCModSEStrArgAction(SCJumpFSMAction);
@@ -102,4 +104,6 @@
string resolveVars(const string s, AmSession* sess,
DSMSession* sc_sess, map<string,string>* event_params);
+string trim(string const& str,char const* sepSet);
+
#endif
Modified: trunk/apps/dsm/DSMDialog.cpp
===================================================================
--- trunk/apps/dsm/DSMDialog.cpp 2008-10-14 19:26:38 UTC (rev 1112)
+++ trunk/apps/dsm/DSMDialog.cpp 2008-10-14 19:41:23 UTC (rev 1113)
@@ -46,6 +46,11 @@
delete *it;
}
+void DSMDialog::onInvite(const AmSipRequest& req) {
+ engine.onInvite(req, this);
+ AmSession::onInvite(req);
+}
+
void DSMDialog::onSessionStart(const AmSipRequest& req)
{
DBG("DSMDialog::onSessionStart\n");
@@ -113,9 +118,9 @@
return cred.get();
}
-void DSMDialog::playPrompt(const string& name) {
+void DSMDialog::playPrompt(const string& name, bool loop) {
DBG("playing prompt '%s'\n", name.c_str());
- prompts.addToPlaylist(name, (long)this, playlist);
+ prompts.addToPlaylist(name, (long)this, playlist, /*front =*/ false, loop);
}
void DSMDialog::closePlaylist(bool notify) {
@@ -165,3 +170,32 @@
return;
}
}
+
+void DSMDialog::addPromptSet(const string& name,
+ AmPromptCollection* prompt_set) {
+ if (prompt_set) {
+ DBG("adding prompt set '%s'\n", name.c_str());
+ prompt_sets[name] = prompt_set;
+ } else {
+ ERROR("trying to add NULL prompt set\n");
+ }
+}
+
+void DSMDialog::setPromptSets(map<string, AmPromptCollection*>&
+ new_prompt_sets) {
+ prompt_sets = new_prompt_sets;
+}
+
+void DSMDialog::setPromptSet(const string& name) {
+ map<string, AmPromptCollection*>::iterator it =
+ prompt_sets.find(name);
+
+ if (it == prompt_sets.end()) {
+ ERROR("prompt set %s unknown\n", name.c_str());
+ return;
+ }
+
+ DBG("setting prompt set '%s'\n", name.c_str());
+ prompts = *it->second;
+}
+
Modified: trunk/apps/dsm/DSMDialog.h
===================================================================
--- trunk/apps/dsm/DSMDialog.h 2008-10-14 19:26:38 UTC (rev 1112)
+++ trunk/apps/dsm/DSMDialog.h 2008-10-14 19:41:23 UTC (rev 1113)
@@ -49,6 +49,7 @@
vector<AmAudioFile*> audiofiles;
AmAudioFile* rec_file;
+ map<string, AmPromptCollection*> prompt_sets;
public:
DSMDialog(AmPromptCollection& prompts,
@@ -57,6 +58,7 @@
UACAuthCred* credentials = NULL);
~DSMDialog();
+ void onInvite(const AmSipRequest& req);
void onSessionStart(const AmSipRequest& req);
void onSessionStart(const AmSipReply& rep);
void startSession();
@@ -67,11 +69,17 @@
UACAuthCred* getCredentials();
- void playPrompt(const string& name);
+ void addPromptSet(const string& name, AmPromptCollection* prompt_set);
+ void setPromptSets(map<string, AmPromptCollection*>& new_prompt_sets);
+
+ // DSMSession interface
+ void playPrompt(const string& name, bool loop = false);
void closePlaylist(bool notify);
void playFile(const string& name, bool loop);
void recordFile(const string& name);
void stopRecord();
+
+ void setPromptSet(const string& name);
};
#endif
Modified: trunk/apps/dsm/DSMModule.h
===================================================================
--- trunk/apps/dsm/DSMModule.h 2008-10-14 19:26:38 UTC (rev 1112)
+++ trunk/apps/dsm/DSMModule.h 2008-10-14 19:41:23 UTC (rev 1113)
@@ -27,6 +27,9 @@
#ifndef _DSM_MODULE_H
#define _DSM_MODULE_H
#include "DSMStateEngine.h"
+#include "AmSipMsg.h"
+#include "AmArg.h"
+class DSMSession;
#include <string>
using std::string;
@@ -41,6 +44,9 @@
virtual DSMAction* getAction(const string& from_str) = 0;
virtual DSMCondition* getCondition(const string& from_str) = 0;
+
+ virtual void preload() { }
+ virtual void onInvite(const AmSipRequest& req, DSMSession* sess) { }
};
typedef void* (*SCFactoryCreate)();
Modified: trunk/apps/dsm/DSMSession.h
===================================================================
--- trunk/apps/dsm/DSMSession.h 2008-10-14 19:26:38 UTC (rev 1112)
+++ trunk/apps/dsm/DSMSession.h 2008-10-14 19:41:23 UTC (rev 1113)
@@ -42,11 +42,12 @@
DSMSession();
virtual ~DSMSession();
- virtual void playPrompt(const string& name) = 0;
+ virtual void playPrompt(const string& name, bool loop = false) = 0;
virtual void playFile(const string& name, bool loop) = 0;
virtual void recordFile(const string& name) = 0;
virtual void stopRecord() = 0;
virtual void closePlaylist(bool notify) = 0;
+ virtual void setPromptSet(const string& name) = 0;
/* holds variables which are accessed by $varname */
map<string, string> var;
Modified: trunk/apps/dsm/DSMStateDiagramCollection.cpp
===================================================================
--- trunk/apps/dsm/DSMStateDiagramCollection.cpp 2008-10-14 19:26:38 UTC
(rev 1112)
+++ trunk/apps/dsm/DSMStateDiagramCollection.cpp 2008-10-14 19:41:23 UTC
(rev 1113)
@@ -62,7 +62,7 @@
s += r + "\n";
}
DBG("dsm text\n------------------\n%s\n------------------\n", s.c_str());
- if (!cr.decode(&diags.back(), s, mod_path, this)) {
+ if (!cr.decode(&diags.back(), s, mod_path, this, mods)) {
ERROR("DonkeySM decode script error!\n");
return false;
}
@@ -74,4 +74,6 @@
for (vector <DSMStateDiagram>::iterator it =
diags.begin(); it != diags.end(); it++)
e->addDiagram(&(*it));
+
+ e->addModules(mods);
}
Modified: trunk/apps/dsm/DSMStateDiagramCollection.h
===================================================================
--- trunk/apps/dsm/DSMStateDiagramCollection.h 2008-10-14 19:26:38 UTC (rev
1112)
+++ trunk/apps/dsm/DSMStateDiagramCollection.h 2008-10-14 19:41:23 UTC (rev
1113)
@@ -29,13 +29,15 @@
#include "DSMStateEngine.h"
#include <string>
+
using std::string;
+class DSMModule;
-
class DSMStateDiagramCollection
: public DSMElemContainer
{
- vector <DSMStateDiagram> diags;
+ vector<DSMStateDiagram> diags;
+ vector<DSMModule*> mods;
public:
DSMStateDiagramCollection();
Modified: trunk/apps/dsm/DSMStateEngine.cpp
===================================================================
--- trunk/apps/dsm/DSMStateEngine.cpp 2008-10-14 19:26:38 UTC (rev 1112)
+++ trunk/apps/dsm/DSMStateEngine.cpp 2008-10-14 19:41:23 UTC (rev 1113)
@@ -26,6 +26,8 @@
*/
#include "DSMStateEngine.h"
+#include "DSMModule.h"
+
#include "AmSession.h"
#include "log.h"
@@ -112,6 +114,12 @@
}
+void DSMStateEngine::onInvite(const AmSipRequest& req, DSMSession* sess) {
+ for (vector<DSMModule*>::iterator it =
+ mods.begin(); it != mods.end(); it++)
+ (*it)->onInvite(req, sess);
+}
+
bool DSMStateEngine::runactions(vector<DSMAction*>::iterator from,
vector<DSMAction*>::iterator to,
AmSession* sess, DSMCondition::EventType event,
@@ -153,6 +161,12 @@
diags.push_back(diag);
}
+void DSMStateEngine::addModules(vector<DSMModule*> modules) {
+ for (vector<DSMModule*>::iterator it=
+ modules.begin(); it != modules.end(); it++)
+ mods.push_back(*it);
+}
+
bool DSMStateEngine::init(AmSession* sess, const string& startDiagram) {
if (!jumpDiag(startDiagram, sess, DSMCondition::Any, NULL)) {
@@ -332,3 +346,4 @@
DSMTransition::~DSMTransition(){
}
+
Modified: trunk/apps/dsm/DSMStateEngine.h
===================================================================
--- trunk/apps/dsm/DSMStateEngine.h 2008-10-14 19:26:38 UTC (rev 1112)
+++ trunk/apps/dsm/DSMStateEngine.h 2008-10-14 19:41:23 UTC (rev 1113)
@@ -28,8 +28,11 @@
#define _STATE_ENGINE_H
#include "DSMElemContainer.h"
+#include "AmSipMsg.h"
class AmSession;
+class DSMSession;
+
#include <map>
using std::map;
#include <vector>
@@ -124,6 +127,8 @@
string to_state;
};
+class DSMModule;
+
class DSMStateDiagram {
vector<State> states;
string name;
@@ -157,16 +162,23 @@
vector<DSMAction*>::iterator to,
AmSession* sess, DSMCondition::EventType event,
map<string,string>* event_params, bool& is_consumed);
+
+ vector<DSMModule*> mods;
+
public:
DSMStateEngine();
~DSMStateEngine();
void addDiagram(DSMStateDiagram* diag);
+ void addModules(vector<DSMModule*> modules);
+
bool init(AmSession* sess, const string& startDiagram);
void runEvent(AmSession* sess,
DSMCondition::EventType event,
map<string,string>* event_params);
+
+ void onInvite(const AmSipRequest& req, DSMSession* sess);
};
Modified: trunk/apps/dsm/doc/dsm_syntax.txt
===================================================================
--- trunk/apps/dsm/doc/dsm_syntax.txt 2008-10-14 19:26:38 UTC (rev 1112)
+++ trunk/apps/dsm/doc/dsm_syntax.txt 2008-10-14 19:41:23 UTC (rev 1113)
@@ -36,8 +36,11 @@
playFile(filename)
recordFile(filename)
stopRecord()
- closePlaylist
+ closePlaylist()
+ setPromptSet()
+ if more prompt sets are loaded
+
set($var, value)
e.g. set($var, "text"); set($var, $var2); set($var, #key)
append($var, value)
Modified: trunk/apps/dsm/etc/dsm.conf
===================================================================
--- trunk/apps/dsm/etc/dsm.conf 2008-10-14 19:26:38 UTC (rev 1112)
+++ trunk/apps/dsm/etc/dsm.conf 2008-10-14 19:41:23 UTC (rev 1113)
@@ -6,9 +6,20 @@
# for import(mod_name)
mod_path=/usr/local/lib/sems/dsm/
+# preload modules which have a preload (init) function
+#preload_mods=uri
+
+
# DSM to start for in/outbound call
inbound_start_diag=inbound_call
outbound_start_diag=outbound_call
# prompts files (for prompt collection
load_prompts=/usr/local/etc/sems/etc/dsm_in_prompts.conf,/usr/local/etc/sems/etc/dsm_out_prompts.conf
+
+#load prompt sets config from this path
+#prompts_sets_path=/usr/local/etc/sems/etc/
+
+# load files with this name (+.conf), e.g. mydomain.conf
+#load_prompts_sets=mydomain
+
_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev