Author: sayer
Date: 2009-10-21 22:32:58 +0200 (Wed, 21 Oct 2009)
New Revision: 1548

Modified:
   trunk/apps/dsm/doc/examples/test_conference.dsm
   trunk/apps/dsm/mods/mod_conference/ModConference.cpp
   trunk/apps/dsm/mods/mod_conference/ModConference.h
   trunk/apps/dsm/mods/mod_conference/Readme.mod_conference.txt
Log:
SEMS-63: mod_conferencing: remove current connection to conference when joining 
a new one

if one joins a conference with mod_conferencing, the current conference channel 
is not removed, which will lead to unnecessary processing and wrong numbers of 
participants in the rooms



Modified: trunk/apps/dsm/doc/examples/test_conference.dsm
===================================================================
--- trunk/apps/dsm/doc/examples/test_conference.dsm     2009-10-19 14:31:05 UTC 
(rev 1547)
+++ trunk/apps/dsm/doc/examples/test_conference.dsm     2009-10-21 20:32:58 UTC 
(rev 1548)
@@ -3,13 +3,54 @@
 initial state lobby 
   enter { playFile(wav/default_en.wav) };
 
+
 state room;
 
 transition "lobby to room" lobby - noAudioTest /  {
-   conference.setPlayoutType(adaptive)
-   conference.join(myroom) 
- } -> room;
+   conference.setPlayoutType(adaptive);
+   conference.join(myroom);
+} -> room;
 
-transition "bye recvd" (lobby, room) - hangup / stop(false) -> end;
 
+transition "key 1 pressed" room - keyPress(1); test($is_spkonly == "") / {
+ set($is_spkonly=1);
+ closePlaylist(false);
+ conference.rejoin(myroom, speakonly);
+} -> room;
+
+transition "key 1 pressed - spkonly" room - keyPress(1); test($is_spkonly == 
"1") / {
+ set($is_spkonly="");
+ closePlaylist(false);
+ conference.rejoin(myroom);
+} -> room;
+
+transition "key 2 pressed" room - keyPress(2); test($is_listenonly == "") / {
+ set($is_listenonly=1);
+ closePlaylist(false);
+ conference.rejoin(myroom, listenonly);
+} -> room;
+
+transition "key 2 pressed - listenonly" room - keyPress(2); 
test($is_listenonly == "1") / {
+ set($is_listenonly="");
+ closePlaylist(false);
+ conference.join(myroom);
+} -> room;
+
+transition "kick event" room - eventTest(#action==kick) / 
closePlaylist(false); conference.leave(); stop(true) -> end;
+
+transition "leave event" room - eventTest(#action==leave) /  {
+   closePlaylist(false); 
+  conference.leave() 
+} -> outside;
+
+state outside
+   enter { 
+     log(2, now outside); 
+   };
+transition "join event" outside - eventTest(#action==join) / 
conference.join(myroom) -> room;
+transition "join event" outside - eventTest(#action==joinroom) / 
conference.join(#room) -> room;
+
+
+transition "bye recvd" (lobby, room) - hangup / closePlaylist(false); 
conference.leave();  stop(false); -> end;
+
 state end;
\ No newline at end of file

Modified: trunk/apps/dsm/mods/mod_conference/ModConference.cpp
===================================================================
--- trunk/apps/dsm/mods/mod_conference/ModConference.cpp        2009-10-19 
14:31:05 UTC (rev 1547)
+++ trunk/apps/dsm/mods/mod_conference/ModConference.cpp        2009-10-21 
20:32:58 UTC (rev 1548)
@@ -39,6 +39,8 @@
 MOD_ACTIONEXPORT_BEGIN(MOD_CLS_NAME) {
 
   DEF_CMD("conference.join", ConfJoinAction);
+  DEF_CMD("conference.leave", ConfLeaveAction);
+  DEF_CMD("conference.rejoin", ConfRejoinAction);
   DEF_CMD("conference.postEvent", ConfPostEventAction);
   DEF_CMD("conference.setPlayoutType", ConfSetPlayoutTypeAction);
 
@@ -46,6 +48,15 @@
 
 MOD_CONDITIONEXPORT_NONE(MOD_CLS_NAME);
 
+
+void DSMConfChannel::release() {
+  chan.release();
+}
+
+void DSMConfChannel::reset(AmConferenceChannel* channel) {
+  chan.reset(channel);
+}
+
 CONST_ACTION_2P(ConfPostEventAction, ',', true);
 EXEC_ACTION_START(ConfPostEventAction) {
   string channel_id = resolveVars(par1, sess, sc_sess, event_params);
@@ -60,33 +71,37 @@
   AmConferenceStatus::postConferenceEvent(channel_id, ev, sess->getLocalTag());
 } EXEC_ACTION_END;
 
-
-CONST_ACTION_2P(ConfJoinAction, ',', true);
-EXEC_ACTION_START(ConfJoinAction) {
-  string channel_id = resolveVars(par1, sess, sc_sess, event_params);
-  string mode = resolveVars(par2, sess, sc_sess, event_params);
-
+static bool ConferenceJoinChannel(DSMConfChannel** dsm_chan, 
+                                 AmSession* sess,
+                                 DSMSession* sc_sess,
+                                 const string& channel_id, 
+                                 const string& mode) {
   bool connect_play = false;
   bool connect_record = false;
   if (mode.empty()) {
     connect_play = true;
     connect_record = true;
   } else if (mode == "speakonly") {
+    connect_record = true;
+  } else if (mode == "listenonly") {
     connect_play = true;
-  } else if (mode == "listenonly") {
-    connect_record = true;
   } 
   DBG("connect_play = %s, connect_rec = %s\n", 
       connect_play?"true":"false", 
       connect_record?"true":"false");
   
-  AmConferenceChannel* chan = AmConferenceStatus::getChannel(channel_id, 
sess->getLocalTag());
+  AmConferenceChannel* chan = AmConferenceStatus::getChannel(channel_id, 
+                                                            
sess->getLocalTag());
   if (NULL == chan) {
     ERROR("obtaining conference channel\n");
     return false;
   }
+  if (NULL != *dsm_chan) {
+    (*dsm_chan)->reset(chan);
+  } else {
+    *dsm_chan = new DSMConfChannel(chan);
+  }
 
-  DSMConfChannel* dsm_chan = new DSMConfChannel(chan);
   AmAudio* play_item = NULL;
   AmAudio* rec_item = NULL;
   if (connect_play)
@@ -96,10 +111,80 @@
 
   sc_sess->addToPlaylist(new AmPlaylistItem(play_item, rec_item));
 
-  sc_sess->transferOwnership(dsm_chan);
+  return true;
+}
+
+CONST_ACTION_2P(ConfJoinAction, ',', true);
+EXEC_ACTION_START(ConfJoinAction) {
+  string channel_id = resolveVars(par1, sess, sc_sess, event_params);
+  string mode = resolveVars(par2, sess, sc_sess, event_params);
+
+  DSMConfChannel* dsm_chan = NULL;
+
+  if (ConferenceJoinChannel(&dsm_chan, sess, sc_sess, channel_id, mode)) {
+      // save channel for later use
+      AmArg c_arg;
+      c_arg.setBorrowedPointer(dsm_chan);
+      sc_sess->avar[CONF_AKEY_CHANNEL] = c_arg;
+      
+      // add to garbage collector
+      sc_sess->transferOwnership(dsm_chan);
+
+      sc_sess->SET_ERRNO(DSM_ERRNO_OK);
+  } else {
+    sc_sess->SET_ERRNO(DSM_ERRNO_UNKNOWN_ARG);
+  }
 } EXEC_ACTION_END;
 
+static DSMConfChannel* getDSMConfChannel(DSMSession* sc_sess) {
+  if (sc_sess->avar.find(CONF_AKEY_CHANNEL) == sc_sess->avar.end()) {
+    return NULL;
+  }
+  ArgObject* ao = NULL; DSMConfChannel* res = NULL;
+  try {
+    if (!isArgAObject(sc_sess->avar[CONF_AKEY_CHANNEL])) {
+      return NULL;
+    }
+    ao = sc_sess->avar[CONF_AKEY_CHANNEL].asObject();
+  } catch (...){
+    return NULL;
+  }
 
+  if (NULL == ao || NULL == (res = dynamic_cast<DSMConfChannel*>(ao))) {
+    return NULL;
+  }
+  return res;
+}
+
+EXEC_ACTION_START(ConfLeaveAction) {
+  DSMConfChannel* chan = getDSMConfChannel(sc_sess);
+  if (NULL == chan) {
+    WARN("app error: trying to leave conference, but channel not found\n");
+    sc_sess->SET_ERRNO(DSM_ERRNO_UNKNOWN_ARG);
+    return false;
+  }
+  chan->release();
+} EXEC_ACTION_END;
+
+CONST_ACTION_2P(ConfRejoinAction, ',', true);
+EXEC_ACTION_START(ConfRejoinAction) {
+  string channel_id = resolveVars(par1, sess, sc_sess, event_params);
+  string mode = resolveVars(par2, sess, sc_sess, event_params);
+
+  DSMConfChannel* chan = getDSMConfChannel(sc_sess);
+  if (NULL == chan) {
+    WARN("app error: trying to rejoin conference, but channel not found\n");
+  } else {
+    chan->release();
+  }
+
+  if (ConferenceJoinChannel(&chan, sess, sc_sess, channel_id, mode)) {
+      sc_sess->SET_ERRNO(DSM_ERRNO_OK);
+  } else {
+    sc_sess->SET_ERRNO(DSM_ERRNO_UNKNOWN_ARG);
+  }
+} EXEC_ACTION_END;
+
 EXEC_ACTION_START(ConfSetPlayoutTypeAction) {
   string playout_type = resolveVars(arg, sess, sc_sess, event_params);
   if (playout_type == "adaptive")

Modified: trunk/apps/dsm/mods/mod_conference/ModConference.h
===================================================================
--- trunk/apps/dsm/mods/mod_conference/ModConference.h  2009-10-19 14:31:05 UTC 
(rev 1547)
+++ trunk/apps/dsm/mods/mod_conference/ModConference.h  2009-10-21 20:32:58 UTC 
(rev 1548)
@@ -35,15 +35,24 @@
 
 DECLARE_MODULE(MOD_CLS_NAME);
 
-class DSMConfChannel : public DSMDisposable {
+#define CONF_AKEY_CHANNEL "conf.chan" 
+
+class DSMConfChannel 
+: public DSMDisposable,
+  public ArgObject {
   std::auto_ptr<AmConferenceChannel> chan;
 
  public:
  DSMConfChannel(AmConferenceChannel* channel) : chan(channel) { }
   ~DSMConfChannel() { }
+  void release();
+  void reset(AmConferenceChannel* channel);
+
 };
 
 DEF_ACTION_2P(ConfJoinAction);
+DEF_ACTION_1P(ConfLeaveAction);
+DEF_ACTION_2P(ConfRejoinAction); 
 DEF_ACTION_2P(ConfPostEventAction);
 DEF_ACTION_1P(ConfSetPlayoutTypeAction);
 

Modified: trunk/apps/dsm/mods/mod_conference/Readme.mod_conference.txt
===================================================================
--- trunk/apps/dsm/mods/mod_conference/Readme.mod_conference.txt        
2009-10-19 14:31:05 UTC (rev 1547)
+++ trunk/apps/dsm/mods/mod_conference/Readme.mod_conference.txt        
2009-10-21 20:32:58 UTC (rev 1548)
@@ -2,6 +2,12 @@
  conference.join(string roomname [, string mode])
    mode = "" | speakonly | listenonly
 
+ conference.leave()
+   destroy conference channel. Close playlist first!!!!!
+
+ conference.rejoin(string roomname [, string mode])
+   mode = "" | speakonly | listenonly
+
  conference.postEvent(string roomname, int event_id)
 
  conference.setPlayoutType(string type)

_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to