[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