Author: sayer
Date: 2009-10-22 19:11:11 +0200 (Thu, 22 Oct 2009)
New Revision: 1561
Added:
trunk/apps/dsm/doc/examples/test_byehdr.dsm
Modified:
trunk/apps/dsm/DSMCall.cpp
trunk/apps/dsm/DSMCoreModule.cpp
trunk/apps/dsm/DSMSession.h
trunk/apps/dsm/DSMStateEngine.h
trunk/apps/dsm/doc/dsm_syntax.txt
trunk/apps/dsm/mods/mod_utils/Readme.mod_utils.txt
Log:
updated core module with exceptions instead of errno
Modified: trunk/apps/dsm/DSMCall.cpp
===================================================================
--- trunk/apps/dsm/DSMCall.cpp 2009-10-22 16:42:40 UTC (rev 1560)
+++ trunk/apps/dsm/DSMCall.cpp 2009-10-22 17:11:11 UTC (rev 1561)
@@ -57,10 +57,6 @@
for (set<AmPromptCollection*>::iterator it=
used_prompt_sets.begin(); it != used_prompt_sets.end(); it++)
(*it)->cleanup((long)this);
-
-// for (map<string, AmPromptCollection*>::iterator it=
-// prompt_sets.begin(); it != prompt_sets.end(); it++)
-// it->second->cleanup((long)this);
}
/** returns whether var exists && var==value*/
@@ -192,7 +188,10 @@
void DSMCall::onBye(const AmSipRequest& req)
{
DBG("onBye\n");
- engine.runEvent(this, DSMCondition::Hangup, NULL);
+ map<string, string> params;
+ params["headers"] = req.hdrs;
+
+ engine.runEvent(this, DSMCondition::Hangup, ¶ms);
}
void DSMCall::process(AmEvent* event)
@@ -246,14 +245,14 @@
if ((var["prompts.default_fallback"] != "yes") ||
default_prompts->addToPlaylist(name, (long)this, playlist,
/*front =*/ false, loop)) {
- DBG("checked [%p]\n", default_prompts);
- SET_ERRNO(DSM_ERRNO_UNKNOWN_ARG);
+ DBG("checked [%p]\n", default_prompts);
+ throw DSMException("prompt", "name", name);
} else {
used_prompt_sets.insert(default_prompts);
- SET_ERRNO(DSM_ERRNO_OK);
+ SET_RES(DSM_RES_OK);
}
} else {
- SET_ERRNO(DSM_ERRNO_OK);
+ SET_RES(DSM_RES_OK);
}
}
@@ -273,7 +272,9 @@
ERROR("audio file '%s' could not be opened for reading.\n",
name.c_str());
delete af;
- SET_ERRNO(DSM_ERRNO_FILE);
+
+ throw DSMException("file", "path", name);
+
return;
}
if (loop)
@@ -285,7 +286,7 @@
playlist.addToPlaylist(new AmPlaylistItem(af, NULL));
audiofiles.push_back(af);
- SET_ERRNO(DSM_ERRNO_OK);
+ SET_RES(DSM_RES_OK);
}
void DSMCall::recordFile(const string& name) {
@@ -299,28 +300,28 @@
name.c_str());
delete rec_file;
rec_file = NULL;
- SET_ERRNO(DSM_ERRNO_FILE);
+ throw DSMException("file", "path", name);
return;
}
setInput(rec_file);
- SET_ERRNO(DSM_ERRNO_OK);
+ SET_RES(DSM_RES_OK);
}
unsigned int DSMCall::getRecordLength() {
if (!rec_file) {
- SET_ERRNO(DSM_ERRNO_FILE);
+ SET_RES(DSM_RES_SCRIPT);
return 0;
}
- SET_ERRNO(DSM_ERRNO_OK);
+ SET_RES(DSM_RES_OK);
return rec_file->getLength();
}
unsigned int DSMCall::getRecordDataSize() {
if (!rec_file) {
- SET_ERRNO(DSM_ERRNO_FILE);
+ SET_RES(DSM_RES_SCRIPT);
return 0;
}
- SET_ERRNO(DSM_ERRNO_OK);
+ SET_RES(DSM_RES_OK);
return rec_file->getDataSize();
}
@@ -330,10 +331,10 @@
rec_file->close();
delete rec_file;
rec_file = NULL;
- SET_ERRNO(DSM_ERRNO_OK);
+ SET_RES(DSM_RES_OK);
} else {
WARN("stopRecord: we are not recording\n");
- SET_ERRNO(DSM_ERRNO_FILE);
+ SET_RES(DSM_RES_SCRIPT);
return;
}
}
@@ -343,8 +344,10 @@
if (prompt_set) {
DBG("adding prompt set '%s'\n", name.c_str());
prompt_sets[name] = prompt_set;
+ SET_RES(DSM_RES_OK);
} else {
ERROR("trying to add NULL prompt set\n");
+ SET_RES(DSM_RES_INTERNAL);
}
}
@@ -359,21 +362,21 @@
if (it == prompt_sets.end()) {
ERROR("prompt set %s unknown\n", name.c_str());
- SET_ERRNO(DSM_ERRNO_UNKNOWN_ARG);
+ throw DSMException("prompt", "name", name);
return;
}
DBG("setting prompt set '%s'\n", name.c_str());
used_prompt_sets.insert(prompts);
prompts = it->second;
- SET_ERRNO(DSM_ERRNO_OK);
+ SET_RES(DSM_RES_OK);
}
void DSMCall::addSeparator(const string& name, bool front) {
unsigned int id = 0;
if (str2i(name, id)) {
- SET_ERRNO(DSM_ERRNO_UNKNOWN_ARG);
+ SET_RES(DSM_RES_UNKNOWN_ARG);
return;
}
@@ -384,7 +387,7 @@
playlist.addToPlaylist(new AmPlaylistItem(sep, sep));
// for garbage collector
audiofiles.push_back(sep);
- SET_ERRNO(DSM_ERRNO_OK);
+ SET_RES(DSM_RES_OK);
}
void DSMCall::transferOwnership(DSMDisposable* d) {
Modified: trunk/apps/dsm/DSMCoreModule.cpp
===================================================================
--- trunk/apps/dsm/DSMCoreModule.cpp 2009-10-22 16:42:40 UTC (rev 1560)
+++ trunk/apps/dsm/DSMCoreModule.cpp 2009-10-22 17:11:11 UTC (rev 1561)
@@ -183,9 +183,9 @@
DBG("posting event to session '%s'\n", sess_id.c_str());
if (!AmSessionContainer::instance()->postEvent(sess_id, ev))
- sc_sess->SET_ERRNO(DSM_ERRNO_UNKNOWN_ARG);
+ sc_sess->SET_RES(DSM_RES_UNKNOWN_ARG);
else
- sc_sess->SET_ERRNO(DSM_ERRNO_OK);
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
CONST_ACTION_2P(SCPlayFileAction, ',', true);
@@ -219,6 +219,7 @@
if (varname.empty())
varname = "record_length";
sc_sess->var[varname]=int2str(sc_sess->getRecordLength());
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
EXEC_ACTION_START(SCGetRecordDataSizeAction) {
@@ -232,31 +233,38 @@
bool notify =
resolveVars(arg, sess, sc_sess, event_params) == "true";
sc_sess->closePlaylist(notify);
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
EXEC_ACTION_START(SCConnectMediaAction) {
sc_sess->connectMedia();
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
EXEC_ACTION_START(SCDisconnectMediaAction) {
sc_sess->disconnectMedia();
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
EXEC_ACTION_START(SCMuteAction) {
sc_sess->mute();
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
EXEC_ACTION_START(SCUnmuteAction) {
sc_sess->unmute();
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
EXEC_ACTION_START(SCEnableDTMFDetection) {
sess->setDtmfDetectionEnabled(true);
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
EXEC_ACTION_START(SCDisableDTMFDetection) {
sess->setDtmfDetectionEnabled(false);
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
CONST_ACTION_2P(SCThrowAction, ',', true);
@@ -328,11 +336,13 @@
unsigned int lvl;
if (str2i(resolveVars(par1, sess, sc_sess, event_params), lvl)) {
ERROR("unknown log level '%s'\n", par1.c_str());
+ sc_sess->SET_RES(DSM_RES_UNKNOWN_ARG);
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():"",
l_line.c_str());
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
EXEC_ACTION_START(SCLogVarsAction) {
@@ -348,6 +358,7 @@
_LOG((int)lvl, "FSM: $%s='%s'\n", it->first.c_str(), it->second.c_str());
}
_LOG((int)lvl, "FSM: variables end ---\n");
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
CONST_ACTION_2P(SCSetAction,'=', false);
@@ -358,6 +369,7 @@
sc_sess->var[var_name] = resolveVars(par2, sess, sc_sess, event_params);
DBG("set $%s='%s'\n",
var_name.c_str(), sc_sess->var[var_name].c_str());
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
CONST_ACTION_2P(SCSetVarAction,'=', false);
@@ -366,6 +378,7 @@
sc_sess->var[var_name] = resolveVars(par2, sess, sc_sess, event_params);
DBG("set $%s='%s'\n",
var_name.c_str(), sc_sess->var[var_name].c_str());
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
@@ -386,6 +399,7 @@
arg.substr(1) : arg;
DBG("clear variable '%s'\n", var_name.c_str());
sc_sess->var.erase(var_name);
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
@@ -398,6 +412,7 @@
DBG("$%s now '%s'\n",
var_name.c_str(), sc_sess->var[var_name].c_str());
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
CONST_ACTION_2P(SCSubStrAction,',', false);
@@ -408,19 +423,20 @@
if (str2i(resolveVars(par2, sess, sc_sess, event_params), pos)) {
ERROR("substr length '%s'\n",
resolveVars(par2, sess, sc_sess, event_params).c_str());
- sc_sess->SET_ERRNO(DSM_ERRNO_UNKNOWN_ARG);
+ sc_sess->SET_RES(DSM_RES_UNKNOWN_ARG);
return false;
}
try {
sc_sess->var[var_name] = sc_sess->var[var_name].substr(pos);
} catch(...) {
ERROR("in substr\n");
- sc_sess->SET_ERRNO(DSM_ERRNO_UNKNOWN_ARG);
+ sc_sess->SET_RES(DSM_RES_UNKNOWN_ARG);
return false;
}
DBG("$%s now '%s'\n",
var_name.c_str(), sc_sess->var[var_name].c_str());
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
EXEC_ACTION_START(SCIncAction) {
@@ -432,6 +448,8 @@
DBG("inc: $%s now '%s'\n",
var_name.c_str(), sc_sess->var[var_name].c_str());
+
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
CONST_ACTION_2P(SCSetTimerAction,',', false);
@@ -441,6 +459,7 @@
if (str2i(resolveVars(par1, sess, sc_sess, event_params), timerid)) {
ERROR("timer id '%s' not decipherable\n",
resolveVars(par1, sess, sc_sess, event_params).c_str());
+ sc_sess->SET_RES(DSM_RES_UNKNOWN_ARG);
return false;
}
@@ -448,6 +467,7 @@
if (str2i(resolveVars(par2, sess, sc_sess, event_params), timeout)) {
ERROR("timeout value '%s' not decipherable\n",
resolveVars(par2, sess, sc_sess, event_params).c_str());
+ sc_sess->SET_RES(DSM_RES_UNKNOWN_ARG);
return false;
}
@@ -457,11 +477,13 @@
if(!user_timer_fact) {
ERROR("load sess_timer module for timers.\n");
+ sc_sess->SET_RES(DSM_RES_ADMIN);
return false;
}
AmDynInvoke* user_timer = user_timer_fact->getInstance();
if(!user_timer) {
ERROR("load sess_timer module for timers.\n");
+ sc_sess->SET_RES(DSM_RES_ADMIN);
return false;
}
@@ -471,6 +493,7 @@
di_args.push(sess->getLocalTag().c_str());
user_timer->invoke("setTimer", di_args, ret);
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
@@ -480,6 +503,7 @@
if (str2i(resolveVars(arg, sess, sc_sess, event_params), timerid)) {
ERROR("timer id '%s' not decipherable\n",
resolveVars(arg, sess, sc_sess, event_params).c_str());
+ sc_sess->SET_RES(DSM_RES_ADMIN);
return false;
}
@@ -488,11 +512,13 @@
AmPlugIn::instance()->getFactory4Di("user_timer");
if(!user_timer_fact) {
+ sc_sess->SET_RES(DSM_RES_ADMIN);
ERROR("load sess_timer module for timers.\n");
return false;
}
AmDynInvoke* user_timer = user_timer_fact->getInstance();
if(!user_timer) {
+ sc_sess->SET_RES(DSM_RES_ADMIN);
ERROR("load sess_timer module for timers.\n");
return false;
}
@@ -502,6 +528,7 @@
di_args.push(sess->getLocalTag().c_str());
user_timer->invoke("removeTimer", di_args, ret);
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
EXEC_ACTION_START(SCRemoveTimersAction) {
@@ -513,11 +540,13 @@
if(!user_timer_fact) {
ERROR("load sess_timer module for timers.\n");
+ sc_sess->SET_RES(DSM_RES_ADMIN);
return false;
}
AmDynInvoke* user_timer = user_timer_fact->getInstance();
if(!user_timer) {
ERROR("load sess_timer module for timers.\n");
+ sc_sess->SET_RES(DSM_RES_ADMIN);
return false;
}
@@ -525,6 +554,7 @@
di_args.push(sess->getLocalTag().c_str());
user_timer->invoke("removeUserTimers", di_args, ret);
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
@@ -648,6 +678,7 @@
if (params.size() < 2) {
ERROR("DI needs at least: mod_name, "
"function_name (in '%s'\n", name.c_str());
+ sc_sess->SET_RES(DSM_RES_UNKNOWN_ARG);
return false;
}
@@ -658,11 +689,13 @@
if(!fact) {
ERROR("load module for factory '%s'.\n", fact_name.c_str());
+ sc_sess->SET_RES(DSM_RES_ADMIN);
return false;
}
AmDynInvoke* di_inst = fact->getInstance();
if(!di_inst) {
ERROR("load module for factory '%s'\n", fact_name.c_str());
+ sc_sess->SET_RES(DSM_RES_ADMIN);
return false;
}
p_it++;
@@ -686,6 +719,7 @@
} else {
ERROR("converting value '%s' to int\n",
p.c_str());
+ sc_sess->SET_RES(DSM_RES_UNKNOWN_ARG);
return false;
}
} else {
@@ -701,21 +735,26 @@
} catch (const AmDynInvoke::NotImplemented& ni) {
ERROR("not implemented DI function '%s'\n",
ni.what.c_str());
+ sc_sess->SET_RES(DSM_RES_UNKNOWN_ARG);
return false;
} catch (const AmArg::OutOfBoundsException& oob) {
ERROR("out of bounds in DI call '%s'\n",
name.c_str());
+ sc_sess->SET_RES(DSM_RES_UNKNOWN_ARG);
return false;
} catch (const AmArg::TypeMismatchException& oob) {
ERROR("type mismatch in DI call '%s'\n",
name.c_str());
+ sc_sess->SET_RES(DSM_RES_UNKNOWN_ARG);
return false;
} catch (...) {
ERROR("unexpected Exception in DI call '%s'\n",
name.c_str());
+ sc_sess->SET_RES(DSM_RES_UNKNOWN);
return false;
}
+ bool flag_error = false;
if (get_res) {
// rudimentary variables conversion...
if (isArgCStr(sc_sess->di_res))
@@ -736,13 +775,21 @@
} break;
default: {
ERROR("unsupported AmArg return type!");
+ flag_error = true;
+ sc_sess->SET_RES(DSM_RES_UNKNOWN);
}
}
}
} else {
ERROR("unsupported AmArg return type!");
+ flag_error = true;
+ sc_sess->SET_RES(DSM_RES_UNKNOWN);
}
}
+ if (!flag_error) {
+ sc_sess->SET_RES(DSM_RES_OK);
+ }
+
} EXEC_ACTION_END;
@@ -751,14 +798,17 @@
string remote_party = resolveVars(par1, sess, sc_sess, event_params);
string remote_uri = resolveVars(par2, sess, sc_sess, event_params);
sc_sess->B2BconnectCallee(remote_party, remote_uri);
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
EXEC_ACTION_START(SCB2BTerminateOtherLegAction) {
sc_sess->B2BterminateOtherLeg();
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
CONST_ACTION_2P(SCB2BReinviteAction,',', true);
EXEC_ACTION_START(SCB2BReinviteAction) {
bool updateSDP = par1=="true";
sess->sendReinvite(updateSDP, par2);
+ sc_sess->SET_RES(DSM_RES_OK);
} EXEC_ACTION_END;
Modified: trunk/apps/dsm/DSMSession.h
===================================================================
--- trunk/apps/dsm/DSMSession.h 2009-10-22 16:42:40 UTC (rev 1560)
+++ trunk/apps/dsm/DSMSession.h 2009-10-22 17:11:11 UTC (rev 1561)
@@ -54,6 +54,17 @@
#define SET_ERRNO(new_errno) \
var["errno"] = new_errno
+#define DSM_RES_OK ""
+#define DSM_RES_UNKNOWN "1" // unknown error
+#define DSM_RES_UNKNOWN_ARG "2" // unknown argument/argument error
+#define DSM_RES_ADMIN "3" // configuration error
+#define DSM_RES_SCRIPT "4" // DSM script error
+#define DSM_RES_INTERNAL "5" // internal error
+
+#define SET_RES(new_res) \
+ var["res"] = new_res
+
+
class DSMDisposable;
class AmPlaylistItem;
Modified: trunk/apps/dsm/DSMStateEngine.h
===================================================================
--- trunk/apps/dsm/DSMStateEngine.h 2009-10-22 16:42:40 UTC (rev 1560)
+++ trunk/apps/dsm/DSMStateEngine.h 2009-10-22 17:11:11 UTC (rev 1561)
@@ -167,6 +167,18 @@
DSMException(const string& e_type)
{ params["type"] = e_type; }
+ DSMException(const string& e_type,
+ const string& key1, const string& val1)
+ { params["type"] = e_type;
+ params[key1] = val1; }
+
+ DSMException(const string& e_type,
+ const string& key1, const string& val1,
+ const string& key2, const string& val2)
+ { params["type"] = e_type;
+ params[key1] = val1;
+ params[key2] = val2; }
+
DSMException(map<string, string>& params)
: params(params) { }
Modified: trunk/apps/dsm/doc/dsm_syntax.txt
===================================================================
--- trunk/apps/dsm/doc/dsm_syntax.txt 2009-10-22 16:42:40 UTC (rev 1560)
+++ trunk/apps/dsm/doc/dsm_syntax.txt 2009-10-22 17:11:11 UTC (rev 1561)
@@ -40,14 +40,23 @@
from promptCollection, e.g. playPrompt("hello");
if $prompts.default_fallback=yes, default prompt set is tried if
prompt not found in current prompt set
+ Throws "prompt" exeption with #name if prompt not found.
+
playPromptLooped(param)
setPromptSet(name)
- if more prompt sets are loaded
+ select active prompt set if more prompt sets are loaded
+ Throws "prompt" exeption with #name if prompt set not found
playFile(filename)
+ Throws "file" exeption with #path if file can not be opened
+
playFileFront(filename)
+ Throws "file" exeption with #path if file can not be opened
+
recordFile(filename)
+ Throws "file" exeption with #path if file can not be opened for recording
+
stopRecord()
getRecordLength([dst_varname]) -- only while recording! default dst var:
record_length
getRecordDataSize([dst_varname]) -- only while recording! default dst var:
record_data_size
Added: trunk/apps/dsm/doc/examples/test_byehdr.dsm
===================================================================
--- trunk/apps/dsm/doc/examples/test_byehdr.dsm 2009-10-22 16:42:40 UTC (rev
1560)
+++ trunk/apps/dsm/doc/examples/test_byehdr.dsm 2009-10-22 17:11:11 UTC (rev
1561)
@@ -0,0 +1,7 @@
+
+initial state START
+ enter {
+ playFile(wav/default_en.wav);
+ };
+transition "got bye" START - hangup / log(1, #headers) -> end;
+state end;
\ No newline at end of file
Modified: trunk/apps/dsm/mods/mod_utils/Readme.mod_utils.txt
===================================================================
--- trunk/apps/dsm/mods/mod_utils/Readme.mod_utils.txt 2009-10-22 16:42:40 UTC
(rev 1560)
+++ trunk/apps/dsm/mods/mod_utils/Readme.mod_utils.txt 2009-10-22 17:11:11 UTC
(rev 1561)
@@ -3,13 +3,23 @@
utils.playCountRight(int cnt [, string basedir])
play count for laguages that have single digits after the 10s (like
english)
+ Throws "file" exeption with #path if file can not be opened
utils.playCountLeft(int cnt [, string basedir])
play count for laguages that have single digits befire the 10s (like
german)
+ Throws "file" exeption with #path if file can not be opened
utils.spell(string word[, string basedir])
plays each character in the word (e.g. utils.spell(321,wav/digits/) plays
wav/digits/3.wav, wav/digits/2.wav, wav/digits/1.wav
- like SayDigits
+ (like SayDigits from *)
+ Throws "file" exeption with #path if file can not be opened
+
+ utils.rand(string varname [, int modulo])
+ generates random number: $varname=rand()%modulo or $varname = rand()
+
+ utils.srand()
+ seed the RNG with time().
+
Conditions:
_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev