[Freeswitch-svn] [commit] r3281 - freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference
Freeswitch SVN
knhor at freeswitch.org
Wed Nov 8 00:51:04 EST 2006
Author: knhor
Date: Wed Nov 8 00:51:04 2006
New Revision: 3281
Modified:
freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c
Log:
do clean up. add comments
Modified: freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c
==============================================================================
--- freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c (original)
+++ freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c Wed Nov 8 00:51:04 2006
@@ -206,7 +206,6 @@
typedef struct api_command {
char *pname;
void *pfnapicmd;
-// int (*pfnapicmd)();
int fntype;
char *psyntax;
} api_command_t;
@@ -225,7 +224,7 @@
static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin);
static switch_status_t conference_say(conference_obj_t *conference, char *text, uint32_t leadin);
static void conference_list(conference_obj_t *conference, switch_stream_handle_t *stream, char *delim);
-static switch_status_t conf_function(char *buf, switch_core_session_t *session, switch_stream_handle_t *stream);
+static switch_status_t conf_api_main(char *buf, switch_core_session_t *session, switch_stream_handle_t *stream);
static switch_status_t audio_bridge_on_ring(switch_core_session_t *session);
static switch_status_t conference_outcall(conference_obj_t *conference,
switch_core_session_t *session,
@@ -254,16 +253,16 @@
switch_stream_handle_t *stream,
conf_api_member_cmd_t pfncallback,
void *data);
-static int conference_function_api_mute(conference_member_t *member,
+static int conf_api_sub_mute(conference_member_t *member,
switch_stream_handle_t *stream,
void *data);
-static int conference_function_api_unmute(conference_member_t *member,
+static int conf_api_sub_unmute(conference_member_t *member,
switch_stream_handle_t *stream,
void *data);
-static int conference_function_api_deaf(conference_member_t *member,
+static int conf_api_sub_deaf(conference_member_t *member,
switch_stream_handle_t *stream,
void *data);
-static int conference_function_api_undeaf(conference_member_t *member,
+static int conf_api_sub_undeaf(conference_member_t *member,
switch_stream_handle_t *stream,
void *data);
@@ -312,12 +311,12 @@
return rel;
}
+// traverse the conference member list for the specified member id and return it's pointer
static conference_member_t *conference_member_get(conference_obj_t *conference, uint32_t id)
{
conference_member_t *member = NULL;
for(member = conference->members; member; member = member->next) {
-
if (switch_test_flag(member, MFLAG_NOCHANNEL)) {
continue;
}
@@ -330,6 +329,7 @@
return member;
}
+// stop the specified recording
static int conference_record_stop(conference_obj_t *conference, char *path)
{
conference_member_t *member = NULL;
@@ -403,7 +403,6 @@
member->energy_level = conference->energy_level;
conference->members = member;
-
if (!switch_test_flag(member, MFLAG_NOCHANNEL)) {
conference->count++;
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
@@ -415,7 +414,6 @@
switch_event_fire(&event);
}
-
if (conference->enter_sound) {
conference_play_file(conference, conference->enter_sound, CONF_DEFAULT_LEADIN);
}
@@ -471,7 +469,6 @@
last = imember;
}
-
member->conference = NULL;
if (!switch_test_flag(member, MFLAG_NOCHANNEL)) {
@@ -512,10 +509,7 @@
switch_mutex_unlock(member->audio_in_mutex);
switch_mutex_unlock(conference->member_mutex);
switch_mutex_unlock(conference->mutex);
-
-
switch_thread_rwlock_unlock(conference->rwlock);
-
}
/* Main monitor thread (1 per distinct conference room) */
@@ -777,54 +771,22 @@
static void conference_loop_fn_mute_toggle(conference_member_t *member)
{
- char msg[512];
-
if (switch_test_flag(member, MFLAG_CAN_SPEAK)) {
-// switch_clear_flag_locked(member, MFLAG_CAN_SPEAK | MFLAG_CAN_HEAR);
- conference_function_api_mute(member, NULL, NULL);
- conference_function_api_deaf(member, NULL, NULL);
- if (member->conference->muted_sound) {
- conference_member_play_file(member, member->conference->muted_sound, 0);
- } else {
- snprintf(msg, sizeof(msg), "Muted");
- conference_member_say(member->conference, member, msg, 0);
- }
+ conf_api_sub_mute(member, NULL, NULL);
+ conf_api_sub_deaf(member, NULL, NULL);
} else {
-// switch_set_flag_locked(member, MFLAG_CAN_SPEAK);
- conference_function_api_unmute(member, NULL, NULL);
- if (member->conference->unmuted_sound) {
- conference_member_play_file(member, member->conference->unmuted_sound, 0);
- } else {
- snprintf(msg, sizeof(msg), "Un-Muted");
- conference_member_say(member->conference, member, msg, 0);
- }
+ conf_api_sub_unmute(member, NULL, NULL);
}
}
static void conference_loop_fn_deafmute_toggle(conference_member_t *member)
{
- char msg[512];
-
if (switch_test_flag(member, MFLAG_CAN_SPEAK)) {
-// switch_clear_flag_locked(member, MFLAG_CAN_SPEAK|MFLAG_CAN_HEAR);
- conference_function_api_mute(member, NULL, NULL);
- conference_function_api_deaf(member, NULL, NULL);
- if (member->conference->muted_sound) {
- conference_member_play_file(member, member->conference->muted_sound, 0);
- } else {
- snprintf(msg, sizeof(msg), "Muted");
- conference_member_say(member->conference, member, msg, 0);
- }
+ conf_api_sub_mute(member, NULL, NULL);
+ conf_api_sub_deaf(member, NULL, NULL);
} else {
-// switch_set_flag_locked(member, MFLAG_CAN_SPEAK|MFLAG_CAN_HEAR);
- conference_function_api_unmute(member, NULL, NULL);
- conference_function_api_undeaf(member, NULL, NULL);
- if (member->conference->unmuted_sound) {
- conference_member_play_file(member, member->conference->unmuted_sound, 0);
- } else {
- snprintf(msg, sizeof(msg), "UN-Muted");
- conference_member_say(member->conference, member, msg, 0);
- }
+ conf_api_sub_unmute(member, NULL, NULL);
+ conf_api_sub_undeaf(member, NULL, NULL);
}
}
@@ -942,6 +904,19 @@
switch_clear_flag_locked(member, MFLAG_RUNNING);
}
+/* Create a thread for the conference and launch it */
+static void launch_input_thread(conference_member_t *member, switch_memory_pool_t *pool)
+{
+ switch_thread_t *thread;
+ switch_threadattr_t *thd_attr = NULL;
+
+ switch_threadattr_create(&thd_attr, pool);
+ switch_threadattr_detach_set(thd_attr, 1);
+ switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+ switch_set_flag_locked(member, MFLAG_ITHREAD);
+ switch_thread_create(&thread, thd_attr, input_thread_run, member, pool);
+}
+
/* Sub-Routine called by a channel inside a conference */
static void conference_loop(conference_member_t *member)
{
@@ -1010,7 +985,6 @@
}
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
- // test to see if outbound channel has answered
if (switch_channel_test_flag(channel, CF_ANSWERED) && !switch_test_flag(member->conference, CFLAG_ANSWERED)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Outbound conference channel answered, setting CFLAG_ANSWERED");
switch_set_flag(member->conference, CFLAG_ANSWERED);
@@ -1032,7 +1006,7 @@
// determines the operation that is being requested
// To disable the function for the user, make the control
// string digit something that can't be dialed... ie. a space
- // The control string should have at least 12 characters in it
+ // The control string MUST have 12 characters in it
pcontroldigit = strchr(member->conference->caller_dtmf_control,*digit);
if(pcontroldigit != NULL) {
@@ -1144,7 +1118,6 @@
} else {
switch_buffer_t *use_buffer = NULL;
uint32_t mux_used = (uint32_t)switch_buffer_inuse(member->mux_buffer);
- //uint32_t res_used = member->mux_resampler ? switch_buffer_inuse(member->resample_buffer) : 0;
if (mux_used) {
/* Flush the output buffer and write all the data (presumably muxed) back to the channel */
@@ -1648,35 +1621,8 @@
switch_mutex_unlock(conference->member_mutex);
}
-static void conference_list_pretty(conference_obj_t *conference, switch_stream_handle_t *stream)
+static int conf_api_sub_mute(conference_member_t *member, switch_stream_handle_t *stream, void *data)
{
- conference_member_t *member = NULL;
-
- switch_mutex_lock(conference->member_mutex);
- stream->write_function(stream, "<pre>Current Callers:\n");
-
- for (member = conference->members; member; member = member->next) {
- switch_channel_t *channel;
- switch_caller_profile_t *profile;
-
- if (switch_test_flag(member, MFLAG_NOCHANNEL)) {
- continue;
- }
- channel = switch_core_session_get_channel(member->session);
- profile = switch_channel_get_caller_profile(channel);
-
-
- stream->write_function(stream, "*) %s (%s)\n",
- profile->caller_id_name,
- profile->caller_id_number
- );
-
- }
- switch_mutex_unlock(conference->member_mutex);
-}
-
-static int conference_function_api_mute(conference_member_t *member, switch_stream_handle_t *stream, void *data)
-{
int err = 0;
if (member != NULL) {
@@ -1685,6 +1631,11 @@
switch_clear_flag_locked(member, MFLAG_CAN_SPEAK);
if (member->conference->muted_sound) {
conference_member_play_file(member, member->conference->muted_sound, 0);
+ } else {
+ char msg[512];
+
+ snprintf(msg, sizeof(msg), "Muted");
+ conference_member_say(member->conference, member, msg, 0);
}
if(stream != NULL) {
stream->write_function(stream, "OK mute %u\n", member->id);
@@ -1705,7 +1656,7 @@
return err;
}
-static int conference_function_api_unmute(conference_member_t *member, switch_stream_handle_t *stream, void *data)
+static int conf_api_sub_unmute(conference_member_t *member, switch_stream_handle_t *stream, void *data)
{
int err = 0;
@@ -1718,6 +1669,11 @@
}
if (member->conference->unmuted_sound) {
conference_member_play_file(member, member->conference->unmuted_sound, 0);
+ } else {
+ char msg[512];
+
+ snprintf(msg, sizeof(msg), "Un-Muted");
+ conference_member_say(member->conference, member, msg, 0);
}
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
switch_channel_t *channel = switch_core_session_get_channel(member->session);
@@ -1735,7 +1691,7 @@
return err;
}
-static int conference_function_api_deaf(conference_member_t *member, switch_stream_handle_t *stream, void *data)
+static int conf_api_sub_deaf(conference_member_t *member, switch_stream_handle_t *stream, void *data)
{
int err = 0;
@@ -1762,7 +1718,7 @@
return err;
}
-static int conference_function_api_undeaf(conference_member_t *member, switch_stream_handle_t *stream, void *data)
+static int conf_api_sub_undeaf(conference_member_t *member, switch_stream_handle_t *stream, void *data)
{
int err = 0;
@@ -1789,7 +1745,7 @@
return err;
}
-static int conference_function_api_kick(conference_member_t *member, switch_stream_handle_t *stream, void *data)
+static int conf_api_sub_kick(conference_member_t *member, switch_stream_handle_t *stream, void *data)
{
int err = 0;
@@ -1821,7 +1777,7 @@
return err;
}
-static int conference_function_api_energy(conference_member_t *member, switch_stream_handle_t *stream, void *data)
+static int conf_api_sub_energy(conference_member_t *member, switch_stream_handle_t *stream, void *data)
{
int err = 0;
@@ -1858,7 +1814,7 @@
return err;
}
-static int conference_function_api_volume_in(conference_member_t *member, switch_stream_handle_t *stream, void *data)
+static int conf_api_sub_volume_in(conference_member_t *member, switch_stream_handle_t *stream, void *data)
{
int err = 0;
@@ -1895,7 +1851,7 @@
return err;
}
-static int conference_function_api_volume_out(conference_member_t *member, switch_stream_handle_t *stream, void *data)
+static int conf_api_sub_volume_out(conference_member_t *member, switch_stream_handle_t *stream, void *data)
{
int err = 0;
@@ -1933,9 +1889,8 @@
return err;
}
-static int conference_function_api_list(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
+static int conf_api_sub_list(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
{
-//static void conference_list(conference_obj_t *conference, switch_stream_handle_t *stream, char *delim)
switch_hash_index_t *hi;
void *val;
char *d = ";";
@@ -1963,13 +1918,12 @@
stream->write_function(stream, "Conference %s (%u members)\n", conference->name, conference->count);
conference_list(conference, stream, d);
-// stream->write_function(stream, "\n");
}
return 0;
}
-static int conference_function_api_play(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
+static int conf_api_sub_play(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
{
switch_event_t *event;
@@ -2010,7 +1964,7 @@
return 0;
}
-static int conference_function_api_say(conference_obj_t *conference, switch_stream_handle_t *stream, char *text)
+static int conf_api_sub_say(conference_obj_t *conference, switch_stream_handle_t *stream, char *text)
{
int err = 0;
@@ -2036,7 +1990,7 @@
return err;
}
-static int conference_function_api_saymember(conference_obj_t *conference, switch_stream_handle_t *stream, char *text)
+static int conf_api_sub_saymember(conference_obj_t *conference, switch_stream_handle_t *stream, char *text)
{
int err = 0;
@@ -2080,7 +2034,7 @@
return err;
}
-static int conference_function_api_stop(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
+static int conf_api_sub_stop(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
{
uint8_t current = 0, all = 0;
int err = 0;
@@ -2112,11 +2066,10 @@
return err;
}
-static int conference_function_api_relate(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
+static int conf_api_sub_relate(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
{
int err = 0;
- char *relate_usage = "Usage relate <id> <id> [nospeak|nohear|clear]\n";
if (argc > 4) {
uint8_t nospeak = 0, nohear = 0, clear = 0;
nospeak = strstr(argv[4], "nospeak") ? 1 : 0;
@@ -2127,7 +2080,7 @@
}
if (!(clear || nospeak || nohear)) {
- stream->write_function(stream, relate_usage);
+ err = 1;
goto done;
}
@@ -2181,16 +2134,15 @@
switch_mutex_unlock(conference->mutex);
}
-
} else {
- stream->write_function(stream, relate_usage);
+ err = 1;
}
done:
return err;
}
-static int conference_function_api_lock(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
+static int conf_api_sub_lock(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
{
switch_event_t *event;
@@ -2205,7 +2157,7 @@
return 0;
}
-static int conference_function_api_unlock(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
+static int conf_api_sub_unlock(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
{
switch_event_t *event;
@@ -2220,7 +2172,7 @@
return 0;
}
-static int conference_function_api_dial(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
+static int conf_api_sub_dial(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
{
int err = 0;
@@ -2234,7 +2186,7 @@
return err;
}
-static int conference_function_api_transfer(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
+static int conf_api_sub_transfer(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
{
int err = 0;
@@ -2254,6 +2206,7 @@
channel = switch_core_session_get_channel(member->session);
+ // build a new conference if it doesn't exist
if (!(new_conference = (conference_obj_t *) switch_core_hash_find(globals.conference_hash, argv[3]))) {
switch_memory_pool_t *pool;
char *conf_name;
@@ -2280,7 +2233,6 @@
}
}
-
// Release the config registry handle
if (cxml) {
switch_xml_free(cxml);
@@ -2290,7 +2242,6 @@
// Create the conference object.
new_conference = conference_new(conf_name, profile, pool);
-
if (!new_conference) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
goto done;
@@ -2306,10 +2257,13 @@
launch_conference_thread(new_conference);
}
+ // move the member from the old conference to the new one
conference_del_member(member->last_conference, member);
conference_add_member(new_conference, member);
+
stream->write_function(stream, "OK Member %u sent to conference %s.\n", id, argv[3]);
+ // tell them what happened
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, event);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id);
@@ -2318,7 +2272,6 @@
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "transfer");
switch_event_fire(&event);
}
-
} else {
err = 1;
}
@@ -2326,19 +2279,23 @@
return err;
}
-static int conference_function_api_record(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
+static int conf_api_sub_record(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
{
+ int err = 0;
+
if (argc > 2) {
launch_conference_record_thread(conference, argv[2]);
} else {
- stream->write_function(stream, "usage record <filename>\n");
+ err = 1;
}
- return 0;
+ return err;
}
-static int conference_function_api_norecord(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
+static int conf_api_sub_norecord(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char**argv)
{
+ int err = 0;
+
if (argc > 2) {
int all = (strcasecmp(argv[2], "all") == 0 );
@@ -2346,40 +2303,40 @@
stream->write_function(stream, "non-existant recording '%s'\n", argv[2]);
}
} else {
- stream->write_function(stream, "usage norecord <[filename | all]>\n");
+ err = 1;
}
- return 0;
+ return err;
}
/* API Interface Function sub-commands */
-static api_command_t conf_function_api_commands[] = {
- {"list", &conference_function_api_list, 0, "<confname> list [delim <string>]"},
- {"energy", &conference_function_api_energy, 1, "<confname> energy <member_id|all> [<newval>]"},
- {"volume in", &conference_function_api_volume_in, 1, "<confname> volume_in <member_id|all> [<newval>]"},
- {"volume out", &conference_function_api_volume_out, 1, "<confname> volume_out <member_id|all> [<newval>]"},
- {"play", &conference_function_api_play, 0, "<confname> play <file_path> [<member_id>]"},
- {"say", &conference_function_api_say, 2, "<confname> say <text>"},
- {"saymember", &conference_function_api_saymember, 2, "<confname> saymember <member_id><text>"},
- {"stop", &conference_function_api_stop, 1, "<confname> stop <[current|all]> [<member_id>]"},
- {"kick", &conference_function_api_kick, 1, "<confname> kick <[member_id|all]>"},
- {"mute", &conference_function_api_mute, 1, "<confname> mute <[member_id|all]>"},
- {"unmute", &conference_function_api_unmute, 1, "<confname> unmute <[member_id|all]>"},
- {"deaf", &conference_function_api_deaf, 1, "<confname> deaf <[member_id|all]>"},
- {"undeaf", &conference_function_api_undeaf, 1, "<confname> undef <[member_id|all]>"},
- {"relate", &conference_function_api_relate, 0, "<confname> relate <member_id> <other_member_id> [nospeak|nohear|clear]"},
- {"lock", &conference_function_api_lock, 0, "<confname> lock"},
- {"unlock", &conference_function_api_unlock, 0, "<confname> unlock"},
- {"dial", &conference_function_api_dial, 0, "<confname> dial <endpoint_module_name>/<destination>"},
- {"transfer", &conference_function_api_transfer, 0, "<confname> transfer <member_id> <conference_name>"},
- {"record", &conference_function_api_record, 0, "<confname> record <filename>"},
- {"norecord", &conference_function_api_norecord, 0, "<confname> norecord <[filename|all]>"},
+static api_command_t conf_api_sub_commands[] = {
+ {"list", &conf_api_sub_list, 0, "<confname> list [delim <string>]"},
+ {"energy", &conf_api_sub_energy, 1, "<confname> energy <member_id|all> [<newval>]"},
+ {"volume in", &conf_api_sub_volume_in, 1, "<confname> volume_in <member_id|all> [<newval>]"},
+ {"volume out", &conf_api_sub_volume_out, 1, "<confname> volume_out <member_id|all> [<newval>]"},
+ {"play", &conf_api_sub_play, 0, "<confname> play <file_path> [<member_id>]"},
+ {"say", &conf_api_sub_say, 2, "<confname> say <text>"},
+ {"saymember", &conf_api_sub_saymember, 2, "<confname> saymember <member_id><text>"},
+ {"stop", &conf_api_sub_stop, 1, "<confname> stop <[current|all]> [<member_id>]"},
+ {"kick", &conf_api_sub_kick, 1, "<confname> kick <[member_id|all]>"},
+ {"mute", &conf_api_sub_mute, 1, "<confname> mute <[member_id|all]>"},
+ {"unmute", &conf_api_sub_unmute, 1, "<confname> unmute <[member_id|all]>"},
+ {"deaf", &conf_api_sub_deaf, 1, "<confname> deaf <[member_id|all]>"},
+ {"undeaf", &conf_api_sub_undeaf, 1, "<confname> undef <[member_id|all]>"},
+ {"relate", &conf_api_sub_relate, 0, "<confname> relate <member_id> <other_member_id> [nospeak|nohear|clear]"},
+ {"lock", &conf_api_sub_lock, 0, "<confname> lock"},
+ {"unlock", &conf_api_sub_unlock, 0, "<confname> unlock"},
+ {"dial", &conf_api_sub_dial, 0, "<confname> dial <endpoint_module_name>/<destination>"},
+ {"transfer", &conf_api_sub_transfer, 0, "<confname> transfer <member_id> <conference_name>"},
+ {"record", &conf_api_sub_record, 0, "<confname> record <filename>"},
+ {"norecord", &conf_api_sub_norecord, 0, "<confname> norecord <[filename|all]>"},
};
-#define CONFFUNCAPISIZE (sizeof(conf_function_api_commands)/sizeof(conf_function_api_commands[0]))
+#define CONFFUNCAPISIZE (sizeof(conf_api_sub_commands)/sizeof(conf_api_sub_commands[0]))
/* API Interface Function */
-static switch_status_t conf_function(char *buf, switch_core_session_t *session, switch_stream_handle_t *stream)
+static switch_status_t conf_api_main(char *buf, switch_core_session_t *session, switch_stream_handle_t *stream)
{
char *lbuf = NULL;
switch_status_t status = SWITCH_STATUS_SUCCESS;
@@ -2405,7 +2362,7 @@
memset(argv,0,sizeof(argv));
argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
- // find a command to execute
+ // try to find a command to execute
if (argc) {
int i,found=0;
uint32_t cnum = atoi(argv[0]);
@@ -2414,16 +2371,17 @@
if(cnum == 0 || (cnum != 0 && conference != NULL)) {
int argn = (cnum != 0 ? 1 : 0);
+ // loop through the command table to find a match
for (i=0; i<CONFFUNCAPISIZE && !found; i++) {
- if (strcasecmp(argv[argn],conf_function_api_commands[i].pname) == 0) {
+ if (strcasecmp(argv[argn],conf_api_sub_commands[i].pname) == 0) {
found = 1;
- switch(conf_function_api_commands[i].fntype) {
+ switch(conf_api_sub_commands[i].fntype) {
case 0: // commands that we've broken the command line into arguments for
- { conf_api_args_cmd_t pfn = (conf_api_args_cmd_t)conf_function_api_commands[i].pfnapicmd;
+ { conf_api_args_cmd_t pfn = (conf_api_args_cmd_t)conf_api_sub_commands[i].pfnapicmd;
if (pfn(conference, stream, argc, &argv[0]) != 0) {
// command returned error, so show syntax usage
- stream->write_function(stream,conf_function_api_commands[i].psyntax);
+ stream->write_function(stream,conf_api_sub_commands[i].psyntax);
}
}
break;
@@ -2433,16 +2391,16 @@
int all = ( id == 0 && strcasecmp(argv[argn+1], "all") == 0 );
if(all) {
- conference_member_itterator(conference, stream, conf_function_api_commands[i].pfnapicmd, argv[argn+2]);
+ conference_member_itterator(conference, stream, conf_api_sub_commands[i].pfnapicmd, argv[argn+2]);
} else {
- conf_api_member_cmd_t pfn = (conf_api_member_cmd_t)conf_function_api_commands[i].pfnapicmd;
+ conf_api_member_cmd_t pfn = (conf_api_member_cmd_t)conf_api_sub_commands[i].pfnapicmd;
conference_member_t *member = conference_member_get(conference, id);
if (member != NULL) {
pfn(conference_member_get(conference, id), stream, argv[argn+2]);
} else {
if (id == 0) {
- stream->write_function(stream,conf_function_api_commands[i].psyntax);
+ stream->write_function(stream,conf_api_sub_commands[i].psyntax);
} else {
stream->write_function(stream, "Non-Existant ID %u\n", id);
}
@@ -2451,26 +2409,27 @@
}
break;
case 2: // commands that deals with all text after command
- { conf_api_text_cmd_t pfn = (conf_api_text_cmd_t)conf_function_api_commands[i].pfnapicmd;
- char *pstr = lbuf+strlen(conf_function_api_commands[i].pname)+1;
+ { conf_api_text_cmd_t pfn = (conf_api_text_cmd_t)conf_api_sub_commands[i].pfnapicmd;
+ char *pstr = lbuf+strlen(conf_api_sub_commands[i].pname)+1;
// advance past all leading white space after command
while(*pstr == ' ' || *pstr == '\t') {
pstr++;
}
+ // call the command handler
if (pfn(conference, stream, pstr) != 0) {
// command returned error, so show syntax usage
- stream->write_function(stream,conf_function_api_commands[i].psyntax);
+ stream->write_function(stream,conf_api_sub_commands[i].psyntax);
}
}
break;
}
}
}
+ // no command found
if(!found) {
stream->write_function(stream, "Confernece command '%s' not found.\nTry 'help conference'\n", argv[argn]);
-// stream->write_function(stream,(char *)conf_api_interface.syntax);
}
} else {
stream->write_function(stream,"No Conference called %s found.\n",argv[0]);
@@ -2478,7 +2437,6 @@
} else {
stream->write_function(stream, "Command not specified.\nTry 'help conference'\n");
-// stream->write_function(stream,(char *)conf_api_interface.syntax);
}
}
@@ -2487,9 +2445,9 @@
}
return status;
-
}
+// outbound call bridge progress call state callback handler
static switch_status_t audio_bridge_on_ring(switch_core_session_t *session)
{
switch_channel_t *channel = NULL;
@@ -2501,6 +2459,7 @@
/* put the channel in a passive state so we can loop audio to it */
switch_channel_set_state(channel, CS_TRANSMIT);
+
return SWITCH_STATUS_FALSE;
}
@@ -2514,6 +2473,7 @@
/*.on_hold */ NULL,
};
+// generate an outbound call from the conference
static switch_status_t conference_outcall(conference_obj_t *conference,
switch_core_session_t *session,
char *bridgeto,
@@ -2540,6 +2500,7 @@
}
+ // establish an outbound call leg
if (switch_ivr_originate(session,
&peer_session,
&cause,
@@ -2557,10 +2518,10 @@
goto done;
}
-
peer_channel = switch_core_session_get_channel(peer_session);
assert(peer_channel != NULL);
+ // make sure the conference still exists
if (!switch_test_flag(conference, CFLAG_RUNNING)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Conference is gone now, nevermind..\n");
if (caller_channel) {
@@ -2574,13 +2535,17 @@
switch_channel_answer(caller_channel);
}
+ // if the outbound call leg is ready
if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
switch_caller_extension_t *extension = NULL;
+
+ // build an extension name object
if ((extension = switch_caller_extension_new(peer_session, conference->name, conference->name)) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "memory error!\n");
status = SWITCH_STATUS_MEMERR;
goto done;
}
+
/* add them to the conference */
if (flags) {
snprintf(appdata, sizeof(appdata), "%s +flags{%s}", conference->name, flags);
@@ -2591,7 +2556,6 @@
switch_channel_set_caller_extension(peer_channel, extension);
switch_channel_set_state(peer_channel, CS_EXECUTE);
-
} else {
switch_channel_hangup(peer_channel, SWITCH_CAUSE_NO_ANSWER);
status = SWITCH_STATUS_FALSE;
@@ -2609,6 +2573,7 @@
uint32_t x = 0;
switch_status_t status = SWITCH_STATUS_SUCCESS;
+ // generate some space infront of the file to be played
for (x = 0; x < leadin; x++) {
switch_frame_t *read_frame;
switch_status_t status = switch_core_session_read_frame(session, &read_frame, 1000, 0);
@@ -2618,6 +2583,7 @@
}
}
+ // if all is well, really play the file
if (status == SWITCH_STATUS_SUCCESS) {
status = switch_ivr_play_file(session, NULL, path, NULL, NULL, NULL, 0);
}
@@ -2661,7 +2627,7 @@
return;
}
-
+ // Start the conference muted or deaf ?
if ((flags_str=strstr(mydata, flags_prefix))) {
char *p;
@@ -2678,6 +2644,7 @@
}
}
+ // is this a bridging conference ?
if (!strncasecmp(mydata, bridge_prefix, strlen(bridge_prefix))) {
isbr = 1;
mydata += strlen(bridge_prefix);
@@ -2709,6 +2676,8 @@
}
}
+ // if this is a bridging call, and it's not a duplicate, build a
+ // conference object, and skip pin handling, and locked checking
if (isbr) {
char *uuid = switch_core_session_get_uuid(session);
@@ -2743,14 +2712,13 @@
launch_conference_thread(conference);
} else {
- /* Figure out what conference to call. */
+ // if the conference exists, get the pointer to it
if ((conference = (conference_obj_t *) switch_core_hash_find(globals.conference_hash, conf_name))) {
freepool = pool;
+ // couldn't find the conference, create one
} else {
- /* Create the conference object. */
conference = conference_new(conf_name, profile, pool);
-
if (!conference) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
goto done;
@@ -2768,9 +2736,9 @@
/* Start the conference thread for this conference */
launch_conference_thread(conference);
-
}
+ // deal with conference pins
if (conference->pin) {
char term = '\0';
char pin[80] = "";
@@ -2800,6 +2768,7 @@
}
}
+ // don't allow more callers if the conference is locked
if (switch_test_flag(conference, CFLAG_LOCKED)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Conference %s is locked.\n", conf_name);
if (conference->locked_sound) {
@@ -2817,6 +2786,7 @@
cxml = NULL;
}
+ // if we're using "bridge:" make an outbound call and bridge it in
if (!switch_strlen_zero(bridgeto) && strcasecmp(bridgeto, "none")) {
if (conference_outcall(conference, session, bridgeto, 60, NULL, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
goto done;
@@ -2903,8 +2873,6 @@
goto codec_done1;
}
-
-
/* Prepare MUTEXS */
member.id = next_member_id();
member.pool = pool;
@@ -3054,6 +3022,8 @@
energy_level = member->energy_level;
+ // if the member can speak, compute the audio energy level and
+ // generate events when the level crosses the threshold
if (switch_test_flag(member, MFLAG_CAN_SPEAK) && energy_level) {
uint32_t energy = 0, i = 0, samples = 0, j = 0, score = 0;
int16_t *data;
@@ -3143,19 +3113,6 @@
return NULL;
}
-/* Create a thread for the conference and launch it */
-static void launch_input_thread(conference_member_t *member, switch_memory_pool_t *pool)
-{
- switch_thread_t *thread;
- switch_threadattr_t *thd_attr = NULL;
-
- switch_threadattr_create(&thd_attr, pool);
- switch_threadattr_detach_set(thd_attr, 1);
- switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
- switch_set_flag_locked(member, MFLAG_ITHREAD);
- switch_thread_create(&thread, thd_attr, input_thread_run, member, pool);
-}
-
static const switch_application_interface_t conference_application_interface = {
/*.interface_name */ global_app_name,
/*.application_function */ conference_function,
@@ -3166,11 +3123,38 @@
static switch_api_interface_t conf_api_interface = {
/*.interface_name */ "conference",
/*.desc */ "Conference module commands",
- /*.function */ conf_function,
+ /*.function */ conf_api_main,
/*.syntax */ // see switch_module_load
/*.next */
};
+static void chat_list_pretty(conference_obj_t *conference, switch_stream_handle_t *stream)
+{
+ conference_member_t *member = NULL;
+
+ switch_mutex_lock(conference->member_mutex);
+ stream->write_function(stream, "<pre>Current Callers:\n");
+
+ for (member = conference->members; member; member = member->next) {
+ switch_channel_t *channel;
+ switch_caller_profile_t *profile;
+
+ if (switch_test_flag(member, MFLAG_NOCHANNEL)) {
+ continue;
+ }
+ channel = switch_core_session_get_channel(member->session);
+ profile = switch_channel_get_caller_profile(channel);
+
+
+ stream->write_function(stream, "*) %s (%s)\n",
+ profile->caller_id_name,
+ profile->caller_id_number
+ );
+
+ }
+ switch_mutex_unlock(conference->member_mutex);
+}
+
static switch_status_t chat_send(char *proto, char *from, char *to, char *subject, char *body, char *hint)
{
char name[512] = "", *p;
@@ -3190,7 +3174,6 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invaid Chat Interface [%s]!\n", proto);
}
-
if ((p = strchr(to, '@'))) {
switch_copy_string(name, to, ++p-to);
} else {
@@ -3205,7 +3188,7 @@
SWITCH_STANDARD_STREAM(stream);
if (strstr(body, "list")) {
- conference_list_pretty(conference, &stream);
+ chat_list_pretty(conference, &stream);
} else {
stream.write_function(&stream, "The only command we have so far is 'list'.\nGet coding or go press PayPal!!\n");
}
@@ -3213,15 +3196,12 @@
ci->chat_send(CONF_CHAT_PROTO, to, from, "", stream.data, NULL);
switch_safe_free(stream.data);
-
-
return SWITCH_STATUS_SUCCESS;
}
static const switch_chat_interface_t conference_chat_interface = {
/*.name */ CONF_CHAT_PROTO,
/*.chat_send */ chat_send,
-
};
static switch_loadable_module_interface_t conference_module_interface = {
@@ -3268,12 +3248,13 @@
uint32_t rate = 8000, interval = 20;
switch_status_t status;
- /* Conference Name */
+ // Validate the conference name
if (switch_strlen_zero(name)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Record! no name.\n");
return NULL;
}
+ // parse the profile tree for config values
for (param = switch_xml_child(profile, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
@@ -3386,7 +3367,7 @@
return NULL;
}
- /* Initilize the object with some settings */
+ // initialize the conference object with settings from the specified profile
conference->pool = pool;
conference->timer_name = switch_core_strdup(conference->pool, timer_name);
conference->tts_engine = switch_core_strdup(conference->pool, tts_engine);
@@ -3399,7 +3380,7 @@
// determines the operation that is being requested
// To disable the function for the user, make the control
// string digit something that can't be dialed... ie. a space
- // The control string should have at least 12 characters in it
+ // The control string MUST have 12 characters in it
if(strlen(caller_dtmf_control) < 12) {
char dbuf[13];
@@ -3497,13 +3478,13 @@
// build api interface help ".syntax" field string
p=strdup("list\n");
for (i=0; i<CONFFUNCAPISIZE; i++) {
- nl=strlen(conf_function_api_commands[i].psyntax)+4;
+ nl=strlen(conf_api_sub_commands[i].psyntax)+4;
if(p != NULL)
ol = strlen(p);
p = realloc(p,ol+nl);
if(p != NULL) {
strcat(p,"\t\t");
- strcat(p,conf_function_api_commands[i].psyntax);
+ strcat(p,conf_api_sub_commands[i].psyntax);
if(i<CONFFUNCAPISIZE-1)
strcat(p,"\n");
}
@@ -3516,6 +3497,7 @@
/* Connect my internal structure to the blank pointer passed to me */
*module_interface = &conference_module_interface;
+ // create/register custom event message type
if (switch_event_reserve_subclass(CONF_EVENT_MAINT) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!", CONF_EVENT_MAINT);
return SWITCH_STATUS_TERM;
@@ -3543,7 +3525,9 @@
if (globals.running) {
+ // signal all threads to shutdown
globals.running = 0;
+ // wait for all threads
while (globals.threads) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for %d threads\n", globals.threads);
switch_yield(100000);
More information about the Freeswitch-svn
mailing list