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, &params);
   }
 
-  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, &params);
+}
+
+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, &params);
+
+  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

Reply via email to