updated core module with exceptions instead of errno

git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@1561 8eb893ce-cfd4-0310-b710-fb5ebe64c474
sayer/1.4-spce2.6
Stefan Sayer 17 years ago
parent 808ec8e9ce
commit 2bc644353d

@ -57,10 +57,6 @@ DSMCall::~DSMCall()
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::onDtmf(int event, int duration_msec) {
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, &params);
}
void DSMCall::process(AmEvent* event)
@ -246,14 +245,14 @@ void DSMCall::playPrompt(const string& name, bool loop) {
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 @@ void DSMCall::playFile(const string& name, bool loop, bool front) {
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 @@ void DSMCall::playFile(const string& name, bool loop, bool front) {
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 @@ void DSMCall::recordFile(const string& name) {
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 @@ void DSMCall::stopRecord() {
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 @@ void DSMCall::addPromptSet(const string& name,
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 @@ void DSMCall::setPromptSet(const string& name) {
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 @@ void DSMCall::addSeparator(const string& name, bool front) {
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) {

@ -183,9 +183,9 @@ EXEC_ACTION_START(SCPostEventAction){
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 @@ EXEC_ACTION_START(SCGetRecordLengthAction) {
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 @@ EXEC_ACTION_START(SCClosePlaylistAction) {
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 @@ EXEC_ACTION_START(SCLogAction) {
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 @@ EXEC_ACTION_START(SCLogVarsAction) {
_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 @@ EXEC_ACTION_START(SCSetAction) {
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 @@ EXEC_ACTION_START(SCSetVarAction) {
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 @@ EXEC_ACTION_START(SCClearAction) {
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 @@ EXEC_ACTION_START(SCAppendAction) {
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 @@ EXEC_ACTION_START(SCSubStrAction) {
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 @@ EXEC_ACTION_START(SCIncAction) {
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 @@ EXEC_ACTION_START(SCSetTimerAction) {
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 @@ EXEC_ACTION_START(SCSetTimerAction) {
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 @@ EXEC_ACTION_START(SCSetTimerAction) {
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 @@ EXEC_ACTION_START(SCSetTimerAction) {
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 @@ EXEC_ACTION_START(SCRemoveTimerAction) {
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 @@ EXEC_ACTION_START(SCRemoveTimerAction) {
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 @@ EXEC_ACTION_START(SCRemoveTimerAction) {
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 @@ EXEC_ACTION_START(SCRemoveTimersAction) {
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 @@ EXEC_ACTION_START(SCRemoveTimersAction) {
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 @@ EXEC_ACTION_START(SCDIAction) {
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 @@ EXEC_ACTION_START(SCDIAction) {
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 @@ EXEC_ACTION_START(SCDIAction) {
} 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 @@ EXEC_ACTION_START(SCDIAction) {
} 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 @@ EXEC_ACTION_START(SCDIAction) {
} 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 @@ EXEC_ACTION_START(SCB2BConnectCalleeAction) {
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;

@ -54,6 +54,17 @@ using std::map;
#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;

@ -167,6 +167,18 @@ class DSMException {
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) { }

@ -40,14 +40,23 @@ actions:
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

@ -0,0 +1,7 @@
initial state START
enter {
playFile(wav/default_en.wav);
};
transition "got bye" START - hangup / log(1, #headers) -> end;
state end;

@ -3,13 +3,23 @@ Actions:
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:

Loading…
Cancel
Save