Author: sayer
Date: 2009-03-23 13:42:35 +0100 (Mon, 23 Mar 2009)
New Revision: 1323
Added:
trunk/apps/dsm/doc/examples/test_b2b.dsm
Modified:
trunk/apps/dsm/DSMCoreModule.cpp
trunk/apps/dsm/DSMCoreModule.h
trunk/apps/dsm/DSMDialog.cpp
trunk/apps/dsm/DSMDialog.h
trunk/apps/dsm/DSMSession.h
trunk/apps/dsm/DSMStateEngine.h
trunk/apps/dsm/doc/dsm_syntax.txt
Log:
B2BUA functions for DSM. See dsm_syntax.txt for the functions.
This work was kindly sponsored by Teltech Systems Inc.
Modified: trunk/apps/dsm/DSMCoreModule.cpp
===================================================================
--- trunk/apps/dsm/DSMCoreModule.cpp 2009-03-23 11:03:35 UTC (rev 1322)
+++ trunk/apps/dsm/DSMCoreModule.cpp 2009-03-23 12:42:35 UTC (rev 1323)
@@ -65,6 +65,9 @@
DEF_CMD("closePlaylist", SCClosePlaylistAction);
DEF_CMD("addSeparator", SCAddSeparatorAction);
DEF_CMD("connectMedia", SCConnectMediaAction);
+ DEF_CMD("disconnectMedia", SCDisconnectMediaAction);
+ DEF_CMD("mute", SCMuteAction);
+ DEF_CMD("unmute", SCUnmuteAction);
DEF_CMD("set", SCSetAction);
DEF_CMD("append", SCAppendAction);
@@ -89,6 +92,9 @@
return a;
}
+ DEF_CMD("B2B.connectCallee", SCB2BConnectCalleeAction);
+ DEF_CMD("B2B.terminateOtherLeg", SCB2BTerminateOtherLegAction);
+
ERROR("could not find action named '%s'\n", cmd.c_str());
return NULL;
}
@@ -133,6 +139,12 @@
if (cmd == "sessionStart")
return new TestDSMCondition(params, DSMCondition::SessionStart);
+ if (cmd == "B2B.otherReply")
+ return new TestDSMCondition(params, DSMCondition::B2BOtherReply);
+
+ if (cmd == "B2B.otherBye")
+ return new TestDSMCondition(params, DSMCondition::B2BOtherBye);
+
ERROR("could not find condition for '%s'\n", cmd.c_str());
return NULL;
}
@@ -198,6 +210,18 @@
sc_sess->connectMedia();
} EXEC_ACTION_END;
+EXEC_ACTION_START(SCDisconnectMediaAction) {
+ sc_sess->disconnectMedia();
+} EXEC_ACTION_END;
+
+EXEC_ACTION_START(SCMuteAction) {
+ sc_sess->mute();
+} EXEC_ACTION_END;
+
+EXEC_ACTION_START(SCUnmuteAction) {
+ sc_sess->unmute();
+} EXEC_ACTION_END;
+
EXEC_ACTION_START(SCStopAction) {
if (resolveVars(arg, sess, sc_sess, event_params) == "true") {
DBG("sending bye\n");
@@ -547,3 +571,13 @@
} EXEC_ACTION_END;
+CONST_ACTION_2P(SCB2BConnectCalleeAction,',', false);
+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);
+} EXEC_ACTION_END;
+
+EXEC_ACTION_START(SCB2BTerminateOtherLegAction) {
+ sc_sess->B2BterminateOtherLeg();
+} EXEC_ACTION_END;
Modified: trunk/apps/dsm/DSMCoreModule.h
===================================================================
--- trunk/apps/dsm/DSMCoreModule.h 2009-03-23 11:03:35 UTC (rev 1322)
+++ trunk/apps/dsm/DSMCoreModule.h 2009-03-23 12:42:35 UTC (rev 1323)
@@ -57,6 +57,10 @@
DEF_ACTION_1P(SCClosePlaylistAction);
DEF_ACTION_1P(SCStopAction);
DEF_ACTION_1P(SCConnectMediaAction);
+DEF_ACTION_1P(SCDisconnectMediaAction);
+DEF_ACTION_1P(SCMuteAction);
+DEF_ACTION_1P(SCUnmuteAction);
+
DEF_ACTION_1P(SCSetPromptsAction);
DEF_ACTION_1P(SCAddSeparatorAction);
@@ -74,6 +78,9 @@
DEF_ACTION_2P(SCPlayFileAction);
DEF_ACTION_2P(SCPostEventAction);
+DEF_ACTION_2P(SCB2BConnectCalleeAction);
+DEF_ACTION_1P(SCB2BTerminateOtherLegAction);
+
class SCDIAction
: public DSMAction {
vector<string> params;
@@ -107,4 +114,23 @@
};
+#define GET_SCSESSION() \
+ DSMSession* sc_sess = dynamic_cast<DSMSession*>(sess); \
+ if (!sc_sess) { \
+ ERROR("wrong session type\n"); \
+ return false; \
+ }
+
+
+#define EXEC_ACTION_START(act_name) \
+ bool act_name::execute(AmSession* sess, \
+ DSMCondition::EventType event, \
+ map<string,string>* event_params) { \
+ GET_SCSESSION();
+
+#define EXEC_ACTION_END \
+ return false; \
+ }
+
+
#endif
Modified: trunk/apps/dsm/DSMDialog.cpp
===================================================================
--- trunk/apps/dsm/DSMDialog.cpp 2009-03-23 11:03:35 UTC (rev 1322)
+++ trunk/apps/dsm/DSMDialog.cpp 2009-03-23 12:42:35 UTC (rev 1323)
@@ -39,6 +39,7 @@
rec_file(NULL)
{
diags.addToEngine(&engine);
+ set_sip_relay_only(false);
}
DSMDialog::~DSMDialog()
@@ -82,11 +83,12 @@
}
if (run_session_invite)
- AmSession::onInvite(req);
+ AmB2BCallerSession::onInvite(req);
}
void DSMDialog::onSessionStart(const AmSipRequest& req)
{
+ AmB2BCallerSession::onSessionStart(req);
DBG("DSMDialog::onSessionStart\n");
startSession();
}
@@ -94,6 +96,8 @@
void DSMDialog::onSessionStart(const AmSipReply& rep)
{
DBG("DSMDialog::onSessionStart (SEMS originator mode)\n");
+ invite_req.body = rep.body;
+
startSession();
}
@@ -118,7 +122,19 @@
AmMediaProcessor::instance()->addSession(this, callgroup);
}
+void DSMDialog::disconnectMedia() {
+ AmMediaProcessor::instance()->removeSession(this);
+}
+void DSMDialog::mute() {
+ setMute(true);
+}
+
+void DSMDialog::unmute() {
+ setMute(false);
+}
+
+
void DSMDialog::onDtmf(int event, int duration_msec) {
DBG("* Got DTMF key %d duration %d\n",
event, duration_msec);
@@ -172,7 +188,7 @@
engine.runEvent(this, DSMCondition::PlaylistSeparator, ¶ms);
}
- AmSession::process(event);
+ AmB2BCallerSession::process(event);
}
inline UACAuthCred* DSMDialog::getCredentials() {
@@ -305,3 +321,36 @@
void DSMDialog::transferOwnership(DSMDisposable* d) {
gc_trash.insert(d);
}
+
+// AmB2BSession methods
+void DSMDialog::onOtherBye(const AmSipRequest& req) {
+ DBG("* Got BYE from other leg\n");
+
+ map<string, string> params;
+ params["hdrs"] = req.hdrs; // todo: optimization - make this configurable
+ engine.runEvent(this, DSMCondition::B2BOtherBye, ¶ms);
+}
+
+bool DSMDialog::onOtherReply(const AmSipReply& reply) {
+ DBG("* Got reply from other leg: %u %s\n",
+ reply.code, reply.reason.c_str());
+
+ map<string, string> params;
+ params["code"] = int2str(reply.code);
+ params["reason"] = reply.reason;
+ params["hdrs"] = reply.hdrs; // todo: optimization - make this configurable
+
+ engine.runEvent(this, DSMCondition::B2BOtherReply, ¶ms);
+
+ return false;
+}
+
+void DSMDialog::B2BterminateOtherLeg() {
+ terminateOtherLeg();
+}
+
+void DSMDialog::B2BconnectCallee(const string& remote_party,
+ const string& remote_uri,
+ bool relayed_invite) {
+ connectCallee(remote_party, remote_uri, relayed_invite);
+}
Modified: trunk/apps/dsm/DSMDialog.h
===================================================================
--- trunk/apps/dsm/DSMDialog.h 2009-03-23 11:03:35 UTC (rev 1322)
+++ trunk/apps/dsm/DSMDialog.h 2009-03-23 12:42:35 UTC (rev 1323)
@@ -26,7 +26,7 @@
*/
#ifndef _DSM_DIALOG_H
#define _DSM_DIALOG_H
-#include "AmSession.h"
+#include "AmB2BSession.h"
#include "AmPromptCollection.h"
#include "ampi/UACAuthAPI.h"
@@ -36,8 +36,8 @@
#include "DSMStateDiagramCollection.h"
#include <set>
-
-class DSMDialog : public AmSession,
+/** implementation of the actual session in DSM */
+class DSMDialog : public AmB2BCallerSession,
public DSMSession,
public CredentialHolder
{
@@ -92,8 +92,21 @@
void setPromptSet(const string& name);
void addSeparator(const string& name);
void connectMedia();
+ void disconnectMedia();
+ void mute();
+ void unmute();
void transferOwnership(DSMDisposable* d);
+
+protected:
+ // AmB2BSession methods
+ void onOtherBye(const AmSipRequest& req);
+ bool onOtherReply(const AmSipReply& reply);
+public:
+ void B2BterminateOtherLeg();
+ void B2BconnectCallee(const string& remote_party,
+ const string& remote_uri,
+ bool relayed_invite = false);
};
#endif
Modified: trunk/apps/dsm/DSMSession.h
===================================================================
--- trunk/apps/dsm/DSMSession.h 2009-03-23 11:03:35 UTC (rev 1322)
+++ trunk/apps/dsm/DSMSession.h 2009-03-23 12:42:35 UTC (rev 1323)
@@ -71,7 +71,16 @@
virtual void setPromptSet(const string& name) = 0;
virtual void addSeparator(const string& name) = 0;
virtual void connectMedia() = 0;
+ virtual void disconnectMedia() = 0;
+ virtual void mute() = 0;
+ virtual void unmute() = 0;
+ /** B2BUA functions */
+ virtual void B2BconnectCallee(const string& remote_party,
+ const string& remote_uri,
+ bool relayed_invite = false) = 0;
+ virtual void B2BterminateOtherLeg() = 0;
+
/** transfer ownership of object to this session instance */
virtual void transferOwnership(DSMDisposable* d) = 0;
Modified: trunk/apps/dsm/DSMStateEngine.h
===================================================================
--- trunk/apps/dsm/DSMStateEngine.h 2009-03-23 11:03:35 UTC (rev 1322)
+++ trunk/apps/dsm/DSMStateEngine.h 2009-03-23 12:42:35 UTC (rev 1323)
@@ -70,7 +70,10 @@
XmlrpcResponse,
DSMEvent,
- PlaylistSeparator
+ PlaylistSeparator,
+
+ B2BOtherReply,
+ B2BOtherBye
};
bool invert;
Modified: trunk/apps/dsm/doc/dsm_syntax.txt
===================================================================
--- trunk/apps/dsm/doc/dsm_syntax.txt 2009-03-23 11:03:35 UTC (rev 1322)
+++ trunk/apps/dsm/doc/dsm_syntax.txt 2009-03-23 12:42:35 UTC (rev 1323)
@@ -48,11 +48,24 @@
addSeparator(id)
fires event when playlist hits it
connectMedia()
- set playlist as input and output of session
+ set playlist as input and output of session, and connect to mediaprocessor
+ disconnectMedia()
+ disconnect from mediaprocessor
+ mute()
+ set RTP stream to muted (don't send and receive RTP packets)
+ unmute()
+ set RTP stream to unmuted (send and receive RTP packets)
+
+ B2B.connectCallee(remote_party, remote_uri)
+ connect second leg of B2B session (see AmB2BSession)
+
+ B2B.terminateOtherLeg
+ disconnect second leg of B2B session (see AmB2BSession)
+
setPrompts(name)
- if more prompt sets are loaded
+ if more than one prompt sets are loaded
set($var=value)
e.g. set($var="text"); set($var=$var2); set($var=#key)
@@ -110,6 +123,16 @@
-- execution is start of session (with run_invite_event, otherwise its
always true):
sessionStart
+ B2B.otherReply
+ Reply on other leg received (see AmB2BSession)
+ #code - reply code
+ #reason - reply reason
+ #hdrs - headers
+
+ B2B.otherBye
+ BYE on other leg received
+ #hdrs - headers
+
=============================
@selects :
local_tag
Added: trunk/apps/dsm/doc/examples/test_b2b.dsm
===================================================================
--- trunk/apps/dsm/doc/examples/test_b2b.dsm 2009-03-23 11:03:35 UTC (rev
1322)
+++ trunk/apps/dsm/doc/examples/test_b2b.dsm 2009-03-23 12:42:35 UTC (rev
1323)
@@ -0,0 +1,47 @@
+import(mod_conference)
+
+initial state lobby
+ enter { playFile(wav/welcome.wav) };
+
+transition "bye in lobby recvd" lobby - hangup / stop(false) -> end;
+
+state room;
+
+transition "lobby to connect" lobby - noAudioTest / {
+ disconnectMedia();
+ mute();
+ B2B.connectCallee("sip:[email protected]", "sip:[email protected]")
+ } -> waitconnect;
+
+state waitconnect;
+
+transition "bye" waitconnect - hangup / {
+ log(1, bye while connecting);
+ B2B.terminateOtherLeg();
+ stop(false);
+} -> end;
+
+transition "prov reply" waitconnect - B2B.otherReply(#code < 200) / {
+ log(1, received provisional reply)
+ log(1, #code)
+ log(1, #reason)
+} -> waitconnect;
+
+transition "positive reply" waitconnect - B2B.otherReply(#code < 300) / {
+ log(1, received positive reply)
+ log(1, #code)
+ log(1, #reason)
+} -> conn;
+
+transition "negative reply" waitconnect - B2B.otherReply() / {
+ log(1, received negative reply)
+ log(1, #code)
+ log(1, #reason)
+ stop(true)
+} -> end;
+
+state conn;
+transition "bye recvd" conn - hangup / B2B.terminateOtherLeg(); stop(false) ->
end;
+transition "bye on other leg" conn - B2B.otherBye() / stop(true) -> end;
+
+state end;
\ No newline at end of file
_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev