o generic event (DSMEvent) posting between sessions (eventTest(), postEvent())

o playlist separators support (addSeparator(), separatorTest())
o errno error reporting for use in state machine (var errno)



git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@1123 8eb893ce-cfd4-0310-b710-fb5ebe64c474
sayer/1.4-spce2.6
Stefan Sayer 18 years ago
parent 68b3dddad2
commit 43370354fe

@ -152,7 +152,10 @@ int DSMFactory::onLoad()
}
DSMModule* last_loaded = reader.mods.back();
if (last_loaded) {
last_loaded->preload();
if (last_loaded->preload()) {
DBG("Error while preloading '%s'\n", it->c_str());
return -1;
}
}
}
}

@ -43,7 +43,7 @@ using std::string;
#include <memory>
class DSMDialog;
class DSMModule;
/** \brief Factory for announcement sessions */
class DSMFactory
: public AmSessionFactory
@ -62,6 +62,7 @@ class DSMFactory
map<string, AmPromptCollection*> prompt_sets;
void prepareSession(DSMDialog* s);
vector<DSMModule*> preloaded_mods;
public:
static DSMFactory* instance();

@ -28,6 +28,7 @@
#include "DSMCoreModule.h"
#include "DSMSession.h"
#include "AmSession.h"
#include "AmSessionContainer.h"
#include "AmUtils.h"
DSMCoreModule::DSMCoreModule() {
@ -78,6 +79,8 @@ DSMAction* DSMCoreModule::getAction(const string& from_str) {
DEF_CMD("recordFile", SCRecordFileAction);
DEF_CMD("stopRecord", SCStopRecordAction);
DEF_CMD("closePlaylist", SCClosePlaylistAction);
DEF_CMD("addSeparator", SCAddSeparatorAction);
DEF_CMD("set", SCSetAction);
DEF_CMD("append", SCAppendAction);
@ -87,6 +90,8 @@ DSMAction* DSMCoreModule::getAction(const string& from_str) {
DEF_CMD("setPrompts", SCSetPromptsAction);
DEF_CMD("postEvent", SCPostEventAction);
if (cmd == "DI") {
SCDIAction * a = new SCDIAction(params, false);
a->name = from_str;
@ -128,9 +133,15 @@ DSMCondition* DSMCoreModule::getCondition(const string& from_str) {
if (cmd == "noAudioTest")
return new TestDSMCondition(params, DSMCondition::NoAudio);
if (cmd == "separatorTest")
return new TestDSMCondition(params, DSMCondition::PlaylistSeparator);
if (cmd == "hangup")
return new TestDSMCondition(params, DSMCondition::Hangup);
if (cmd == "eventTest")
return new TestDSMCondition(params, DSMCondition::DSMEvent);
ERROR("could not find condition for '%s'\n", cmd.c_str());
return NULL;
}
@ -196,6 +207,14 @@ bool SCSetPromptsAction::execute(AmSession* sess,
return false;
}
bool SCAddSeparatorAction::execute(AmSession* sess,
DSMCondition::EventType event,
map<string,string>* event_params) {
GET_SCSESSION();
sc_sess->addSeparator(resolveVars(arg, sess, sc_sess, event_params));
return false;
}
bool SCPlayPromptLoopedAction::execute(AmSession* sess,
DSMCondition::EventType event,
map<string,string>* event_params) {
@ -204,6 +223,32 @@ bool SCPlayPromptLoopedAction::execute(AmSession* sess,
return false;
}
CONST_TwoParAction(SCPostEventAction, ",", true);
bool SCPostEventAction::execute(AmSession* sess,
DSMCondition::EventType event,
map<string,string>* event_params) {
GET_SCSESSION();
string sess_id = resolveVars(par1, sess, sc_sess, event_params);
string var = resolveVars(par2, sess, sc_sess, event_params);
DSMEvent* ev = new DSMEvent();
if (!var.empty()) {
if (var == "var")
ev->params = sc_sess->var;
else
ev->params[var] = sc_sess->var[var];
}
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);
else
sc_sess->SET_ERRNO(DSM_ERRNO_OK);
return false;
}
bool SCPlayFileAction::execute(AmSession* sess,
DSMCondition::EventType event,
map<string,string>* event_params) {

@ -56,6 +56,7 @@ DEF_SCStrArgAction(SCStopRecordAction);
DEF_SCStrArgAction(SCClosePlaylistAction);
DEF_SCStrArgAction(SCStopAction);
DEF_SCStrArgAction(SCSetPromptsAction);
DEF_SCStrArgAction(SCAddSeparatorAction);
DEF_SCModSEStrArgAction(SCRepostAction);
DEF_SCModSEStrArgAction(SCJumpFSMAction);
@ -68,6 +69,7 @@ DEF_TwoParAction(SCAppendAction);
DEF_TwoParAction(SCSetTimerAction);
DEF_TwoParAction(SCLogAction);
DEF_TwoParAction(SCPlayFileAction);
DEF_TwoParAction(SCPostEventAction);
class SCDIAction
: public DSMAction {

@ -41,9 +41,14 @@ DSMDialog::DSMDialog(AmPromptCollection& prompts,
DSMDialog::~DSMDialog()
{
for (vector<AmAudioFile*>::iterator it=
for (vector<AmAudio*>::iterator it=
audiofiles.begin();it!=audiofiles.end();it++)
delete *it;
prompts.cleanup((long)this);
for (map<string, AmPromptCollection*>::iterator it=
prompt_sets.begin(); it != prompt_sets.end(); it++)
it->second->cleanup((long)this);
}
void DSMDialog::onInvite(const AmSipRequest& req) {
@ -93,13 +98,20 @@ void DSMDialog::onBye(const AmSipRequest& req)
void DSMDialog::process(AmEvent* event)
{
if (event->event_id == DSM_EVENT_ID) {
DSMEvent* dsm_event = dynamic_cast<DSMEvent*>(event);
if (dsm_event) {
engine.runEvent(this, DSMCondition::DSMEvent, &dsm_event->params);
return;
}
}
AmAudioEvent* audio_event = dynamic_cast<AmAudioEvent*>(event);
if(audio_event &&
((audio_event->event_id == AmAudioEvent::cleared) ||
(audio_event->event_id == AmAudioEvent::noAudio))){
// todo: run event
engine.runEvent(this, DSMCondition::NoAudio, NULL);
return;
}
@ -111,6 +123,13 @@ void DSMDialog::process(AmEvent* event)
engine.runEvent(this, DSMCondition::Timer, &params);
}
AmPlaylistSeparatorEvent* sep_ev = dynamic_cast<AmPlaylistSeparatorEvent*>(event);
if (sep_ev) {
map<string, string> params;
params["id"] = int2str(sep_ev->event_id);
engine.runEvent(this, DSMCondition::PlaylistSeparator, &params);
}
AmSession::process(event);
}
@ -120,7 +139,12 @@ inline UACAuthCred* DSMDialog::getCredentials() {
void DSMDialog::playPrompt(const string& name, bool loop) {
DBG("playing prompt '%s'\n", name.c_str());
prompts.addToPlaylist(name, (long)this, playlist, /*front =*/ false, loop);
if (prompts.addToPlaylist(name, (long)this, playlist,
/*front =*/ false, loop))
SET_ERRNO(DSM_ERRNO_UNKNOWN_ARG);
else
SET_ERRNO(DSM_ERRNO_OK);
}
void DSMDialog::closePlaylist(bool notify) {
@ -134,6 +158,7 @@ void DSMDialog::playFile(const string& name, bool loop) {
ERROR("audio file '%s' could not be opened for reading.\n",
name.c_str());
delete af;
SET_ERRNO(DSM_ERRNO_FILE);
return;
}
if (loop)
@ -141,6 +166,7 @@ void DSMDialog::playFile(const string& name, bool loop) {
playlist.addToPlaylist(new AmPlaylistItem(af, NULL));
audiofiles.push_back(af);
SET_ERRNO(DSM_ERRNO_OK);
}
void DSMDialog::recordFile(const string& name) {
@ -154,9 +180,11 @@ void DSMDialog::recordFile(const string& name) {
name.c_str());
delete rec_file;
rec_file = NULL;
SET_ERRNO(DSM_ERRNO_FILE);
return;
}
setInput(rec_file);
SET_ERRNO(DSM_ERRNO_OK);
}
void DSMDialog::stopRecord() {
@ -165,8 +193,10 @@ void DSMDialog::stopRecord() {
rec_file->close();
delete rec_file;
rec_file = NULL;
SET_ERRNO(DSM_ERRNO_OK);
} else {
WARN("stopRecord: we are not recording\n");
SET_ERRNO(DSM_ERRNO_FILE);
return;
}
}
@ -192,10 +222,26 @@ void DSMDialog::setPromptSet(const string& name) {
if (it == prompt_sets.end()) {
ERROR("prompt set %s unknown\n", name.c_str());
SET_ERRNO(DSM_ERRNO_UNKNOWN_ARG);
return;
}
DBG("setting prompt set '%s'\n", name.c_str());
prompts = *it->second;
SET_ERRNO(DSM_ERRNO_OK);
}
void DSMDialog::addSeparator(const string& name) {
unsigned int id = 0;
if (str2i(name, id)) {
SET_ERRNO(DSM_ERRNO_UNKNOWN_ARG);
return;
}
AmPlaylistSeparator* sep = new AmPlaylistSeparator(this, id);
playlist.addToPlaylist(new AmPlaylistItem(sep, sep));
// for garbage collector
audiofiles.push_back(sep);
SET_ERRNO(DSM_ERRNO_OK);
}

@ -47,7 +47,7 @@ class DSMDialog : public AmSession,
string startDiagName;
AmPlaylist playlist;
vector<AmAudioFile*> audiofiles;
vector<AmAudio*> audiofiles;
AmAudioFile* rec_file;
map<string, AmPromptCollection*> prompt_sets;
@ -80,6 +80,7 @@ public:
void stopRecord();
void setPromptSet(const string& name);
void addSeparator(const string& name);
};
#endif

@ -45,7 +45,7 @@ class DSMModule {
virtual DSMAction* getAction(const string& from_str) = 0;
virtual DSMCondition* getCondition(const string& from_str) = 0;
virtual void preload() { }
virtual int preload() { return 0; }
virtual void onInvite(const AmSipRequest& req, DSMSession* sess) { }
};

@ -27,7 +27,8 @@
#ifndef _DSM_SESSION_H
#define _DSM_SESSION_H
#include <AmArg.h>
#include "AmArg.h"
#include "AmEvent.h"
#include <string>
using std::string;
@ -36,6 +37,14 @@ using std::vector;
#include <map>
using std::map;
#define DSM_ERRNO_FILE "1"
#define DSM_ERRNO_UNKNOWN_ARG "2"
#define DSM_ERRNO_GENERAL "99"
#define DSM_ERRNO_OK ""
#define SET_ERRNO(new_errno) \
var["errno"] = new_errno
class DSMSession {
public:
@ -48,6 +57,7 @@ class DSMSession {
virtual void stopRecord() = 0;
virtual void closePlaylist(bool notify) = 0;
virtual void setPromptSet(const string& name) = 0;
virtual void addSeparator(const string& name) = 0;
/* holds variables which are accessed by $varname */
map<string, string> var;
@ -56,4 +66,14 @@ class DSMSession {
AmArg di_res;
};
#define DSM_EVENT_ID -10
/** generic event for passing events between DSM sessions */
struct DSMEvent : public AmEvent {
DSMEvent() : AmEvent(DSM_EVENT_ID) { }
~DSMEvent() { }
map<string, string> params;
};
#endif

@ -66,7 +66,9 @@ class DSMCondition
Hold,
UnHold,
XmlrpcResponse
XmlrpcResponse,
DSMEvent,
PlaylistSeparator
};
DSMCondition() { }

Loading…
Cancel
Save