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