[Freeswitch-svn] [commit] r3450 - freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference

Freeswitch SVN knhor at freeswitch.org
Thu Nov 23 20:01:37 EST 2006


Author: knhor
Date: Thu Nov 23 20:01:35 2006
New Revision: 3450

Modified:
   freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c

Log:
add ability to pass caller control args from xml to callback handler. add dialout from caller control fn.

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	Thu Nov 23 20:01:35 2006
@@ -82,6 +82,7 @@
 	CALLER_CONTROL_VOL_LISTEN_DN,
 	CALLER_CONTROL_HANGUP,
 	CALLER_CONTROL_MENU,
+	CALLER_CONTROL_DIAL,
 } caller_control_t;
 
 // forward declaration for conference_obj and caller_control
@@ -948,6 +949,53 @@
 	}
 }
 
+static void conference_loop_fn_dial(conference_member_t *member, void *data)
+{
+	if (member != NULL && data != NULL) {
+		char *lbuf = strdup(data);
+		char *argv[4];
+		int argc = 0;
+
+		if (lbuf != NULL) {
+			memset(argv,0,sizeof(argv));
+			argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dial argc %u 1 '%s' 2 '%s' 3 '%s' 4 '%s'\n",
+				argc,argv[0],argv[1],argv[2],argv[3]);
+			if (argc >= 4) {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "executing conference outcall\n");
+				conference_outcall(member->conference, NULL, argv[0], atoi(argv[1]), NULL, argv[3], argv[2]);
+			} else {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "conference outcall not executed\n");
+			}
+
+			free(lbuf);
+		}
+	}
+}
+
+static struct caller_control_fn_table {
+	char *key;
+	char *digits;
+	caller_control_t action;
+	void (*handler)(conference_member_t *, void *);
+} ccfntbl[] = {
+	{"mute",		"0",	CALLER_CONTROL_MUTE,		conference_loop_fn_mute_toggle},
+	{"deaf mute",		"*",	CALLER_CONTROL_DEAF_MUTE,	conference_loop_fn_deafmute_toggle},
+	{"energy up",		"9",	CALLER_CONTROL_ENERGY_UP,	conference_loop_fn_energy_up},
+	{"energy equ",		"8",	CALLER_CONTROL_ENERGY_EQU_CONF,	conference_loop_fn_energy_equ_conf},
+	{"energy dn",		"7",	CALLER_CONTROL_ENERGEY_DN,	conference_loop_fn_energy_dn},
+	{"vol talk up",		"3",	CALLER_CONTROL_VOL_TALK_UP,	conference_loop_fn_volume_talk_up},
+	{"vol talk zero",	"2",	CALLER_CONTROL_VOL_TALK_ZERO,	conference_loop_fn_volume_talk_zero},
+	{"vol talk dn",		"1",	CALLER_CONTROL_VOL_TALK_DN,	conference_loop_fn_volume_talk_dn},
+	{"vol listen up",	"6",	CALLER_CONTROL_VOL_LISTEN_UP,	conference_loop_fn_volume_listen_up},
+	{"vol listen zero",	"5",	CALLER_CONTROL_VOL_LISTEN_ZERO,	conference_loop_fn_volume_listen_zero},
+	{"vol listen dn",	"4",	CALLER_CONTROL_VOL_LISTEN_DN,	conference_loop_fn_volume_listen_dn},
+	{"hangup",		"#",	CALLER_CONTROL_HANGUP,		conference_loop_fn_hangup},
+	{"menu",		NULL,	CALLER_CONTROL_MENU,		conference_loop_fn_menu},
+	{"dial",		NULL,	CALLER_CONTROL_DIAL,		conference_loop_fn_dial},
+};
+#define CCFNTBL_QTY (sizeof(ccfntbl)/sizeof(ccfntbl[0]))
+
 /* Create a thread for the conference and launch it */
 static void launch_input_thread(conference_member_t *member, switch_memory_pool_t *pool)
 {
@@ -1048,8 +1096,17 @@
 
 				for (digit = dtmf; *digit; digit++) {
 					action = (caller_control_action_t *)switch_ivr_digit_stream_parser_feed(member->conference->dtmf_parser, *digit);
-				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "digit_stream_parser_feed result != NULL %u\n",action != NULL);
+//				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "digit_stream_parser_feed result != NULL %u\n",action != NULL);
 					if (action != NULL && action->handler != NULL) {
+						int i,found=0;
+
+						for(i=0; i<CCFNTBL_QTY; i++) {
+							if (action->handler == ccfntbl[i].handler) {
+								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "excuting caller control '%s' param '%s'\n",ccfntbl[i].key,(ccfntbl[i].action != CALLER_CONTROL_MENU ? action->data : ""));
+								found = 1;
+							}
+						}
+
 						action->handler(member,action->data);
 					}
 				}
@@ -2181,7 +2238,7 @@
 	int err = 0;
 
 	if (argc > 2) {
-		conference_outcall(conference, NULL, argv[2], 60, argv[3], argv[4], argv[5]);
+		conference_outcall(conference, NULL, argv[2], 60, NULL, argv[4], argv[3]);
 		stream->write_function(stream, "OK\n");
 	} else {
 		err = 1;
@@ -2331,7 +2388,7 @@
 	{"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>"},
+	{"dial",	&conf_api_sub_dial,		0, "<confname> dial <endpoint_module_name>/<destination> <callerid number> <callerid name>"},
 	{"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]>"},
@@ -3222,28 +3279,6 @@
 	/*.chat_interface */ &conference_chat_interface
 };
 
-static struct caller_control_fn_table {
-	char *key;
-	char *digits;
-	caller_control_t action;
-	void (*handler)(conference_member_t *, void *);
-} ccfntbl[] = {
-	{"mute",		"0",	CALLER_CONTROL_MUTE,		conference_loop_fn_mute_toggle},
-	{"deaf mute",		"*",	CALLER_CONTROL_DEAF_MUTE,	conference_loop_fn_deafmute_toggle},
-	{"energy up",		"9",	CALLER_CONTROL_ENERGY_UP,	conference_loop_fn_energy_up},
-	{"energy equ",		"8",	CALLER_CONTROL_ENERGY_EQU_CONF,	conference_loop_fn_energy_equ_conf},
-	{"energy dn",		"7",	CALLER_CONTROL_ENERGEY_DN,	conference_loop_fn_energy_dn},
-	{"vol talk up",		"3",	CALLER_CONTROL_VOL_TALK_UP,	conference_loop_fn_volume_talk_up},
-	{"vol talk zero",	"2",	CALLER_CONTROL_VOL_TALK_ZERO,	conference_loop_fn_volume_talk_zero},
-	{"vol talk dn",		"1",	CALLER_CONTROL_VOL_TALK_DN,	conference_loop_fn_volume_talk_dn},
-	{"vol listen up",	"6",	CALLER_CONTROL_VOL_LISTEN_UP,	conference_loop_fn_volume_listen_up},
-	{"vol listen zero",	"5",	CALLER_CONTROL_VOL_LISTEN_ZERO,	conference_loop_fn_volume_listen_zero},
-	{"vol listen dn",	"4",	CALLER_CONTROL_VOL_LISTEN_DN,	conference_loop_fn_volume_listen_dn},
-	{"hangup",		"#",	CALLER_CONTROL_HANGUP,		conference_loop_fn_hangup},
-	{"menu",		NULL,	CALLER_CONTROL_MENU,		conference_loop_fn_menu},
-};
-#define CCFNTBL_QTY (sizeof(ccfntbl)/sizeof(ccfntbl[0]))
-
 static switch_ivr_action_t conference_caller_control_menu_handler(switch_ivr_menu_t *menu, char *param, char *buf, size_t buflen, void *obj)
 {
 	switch_ivr_action_t action = SWITCH_IVR_ACTION_NOOP;
@@ -3251,16 +3286,33 @@
 	if (!switch_strlen_zero(param)) {
 		if (obj != NULL) {
 			int i,found;
+			char *action_name = strdup(param);
 
-			for(i=0,found=0; !found && i<CCFNTBL_QTY; i++) {
-				found = (ccfntbl[i].action != CALLER_CONTROL_MENU && strcasecmp(ccfntbl[i].key,param) == 0);
-				if (found) {
-					if (obj != NULL) {
-						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "invoking caller control menu action '%s'\n",param);
-						ccfntbl[i].handler((conference_member_t *)obj,NULL);
+			if (action_name != NULL) {
+				char *sep = (action_name != NULL ? strchr(action_name,' ') : NULL);
+
+				// split the action from any parameters
+				if (sep != NULL) {
+					*sep ='\0';
+				}
+
+				// find and execute the caller control handler
+				for(i=0,found=0; !found && i<CCFNTBL_QTY; i++) {
+					found = (ccfntbl[i].action != CALLER_CONTROL_MENU && strcasecmp(ccfntbl[i].key,action_name) == 0);
+					if (found) {
+						if (obj != NULL) {
+							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "invoking caller control menu action '%s'\n",ccfntbl[i].key);
+							ccfntbl[i].handler((conference_member_t *)obj, (sep != NULL ? sep+1 : NULL));
+							if (ccfntbl[i].action == CALLER_CONTROL_HANGUP) {
+								action = SWITCH_IVR_ACTION_DIE;
+							}
+						}
 					}
 				}
+
+				free(action_name);
 			}
+
 			if (!found) {
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unknown caller control menu action '%s'\n",param);
 			}
@@ -3554,25 +3606,19 @@
 				caller_control_action_t *action;
 
 				for(i=0,status=SWITCH_STATUS_SUCCESS; status == SWITCH_STATUS_SUCCESS && i<CCFNTBL_QTY; i++) {
-					switch(ccfntbl[i].action)
-					{
-						case CALLER_CONTROL_MENU:
-							// default caller control, has no menu specification
-							break;
-						default:
-							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Installing default caller control action '%s' bound to '%s'.\n",
-														ccfntbl[i].key,
-														ccfntbl[i].digits);
-							action = (caller_control_action_t *)switch_core_alloc(conference->pool,sizeof(caller_control_action_t));
-							if (action != NULL) {
-								action->handler = ccfntbl[i].handler;
-								action->data = NULL;
-								status = switch_ivr_digit_stream_parser_set_event(conference->dtmf_parser,ccfntbl[i].digits,action);
-							} else {
-								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to alloc memory for caller control binding '%s' to '%s'\n",ccfntbl[i].key,ccfntbl[i].digits);
-								status = SWITCH_STATUS_MEMERR;
-							}
-							break;
+					if (!switch_strlen_zero(ccfntbl[i].digits)) {
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Installing default caller control action '%s' bound to '%s'.\n",
+													ccfntbl[i].key,
+													ccfntbl[i].digits);
+						action = (caller_control_action_t *)switch_core_alloc(conference->pool,sizeof(caller_control_action_t));
+						if (action != NULL) {
+							action->handler = ccfntbl[i].handler;
+							action->data = NULL;
+							status = switch_ivr_digit_stream_parser_set_event(conference->dtmf_parser,ccfntbl[i].digits,action);
+						} else {
+							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to alloc memory for caller control binding '%s' to '%s'\n",ccfntbl[i].key,ccfntbl[i].digits);
+							status = SWITCH_STATUS_MEMERR;
+						}
 					}
 				}
 			} else if (strcasecmp(controls_set,"custom") == 0) {
@@ -3580,43 +3626,43 @@
 				for (xml_kvp = switch_xml_child(xml_controls, "control"); xml_kvp; xml_kvp = xml_kvp->next) {
 					char *key = (char *) switch_xml_attr(xml_kvp, "action");
 					char *val = (char *) switch_xml_attr(xml_kvp, "digits");
+					char *data = (char *)switch_xml_attr_soft(xml_kvp, "data");
 
 					if(!switch_strlen_zero(key) && !switch_strlen_zero(val)) {
 						int i;
-						caller_control_action_t *action;
 
 						// scan through all of the valid actions, and if found,
 						// set the new caller control action digit string, then
 						// stop scanning the table, and go to the next xml kvp.
 						for(i=0,status=SWITCH_STATUS_NOOP; i<CCFNTBL_QTY && status == SWITCH_STATUS_NOOP; i++) {
-							caller_control_menu_ctx_t *menu_ctx = NULL;
 
 							if(strcasecmp(ccfntbl[i].key,key) == 0) {
-								switch(ccfntbl[i].action)
-								{
-									case CALLER_CONTROL_MENU:
-										{
-											char *menu_name = (char *)switch_xml_attr_soft(xml_kvp, "menu-name");
+								status = SWITCH_STATUS_SUCCESS;
 
-											status = conference_caller_control_menu_build(&menu_ctx,conference,profile,menu_name);
-											if (status != SWITCH_STATUS_SUCCESS) {
-												switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to build menu '%s' bound to '%s'\n", menu_name, val);
-												break;
-											}
-										}
-										// deliberate fall through to default case
-									default:
-										switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Installing caller control action '%s' bound to '%s'.\n",key,val);
-										action = (caller_control_action_t *)switch_core_alloc(conference->pool,sizeof(caller_control_action_t));
-										if (action != NULL) {
-											action->handler = ccfntbl[i].handler;
-											action->data = (void *)menu_ctx;
-											status = switch_ivr_digit_stream_parser_set_event(conference->dtmf_parser,val,action);
-										} else {
-											switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to alloc memory for caller control binding '%s' to '%s'\n",ccfntbl[i].key,ccfntbl[i].digits);
-											status = SWITCH_STATUS_MEMERR;
-										}
-										break;
+								if (ccfntbl[i].action == CALLER_CONTROL_MENU) {
+									caller_control_menu_ctx_t *menu_ctx = NULL;
+
+									status = conference_caller_control_menu_build(&menu_ctx,conference,profile,data);
+									data = (char *)menu_ctx;
+
+									if (status != SWITCH_STATUS_SUCCESS) {
+										switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to build menu '%s' bound to '%s'\n",data,val);
+									}
+								}
+
+								if (status == SWITCH_STATUS_SUCCESS) {
+									caller_control_action_t *action;
+
+									switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Installing caller control action '%s' bound to '%s'.\n",key,val);
+									action = (caller_control_action_t *)switch_core_alloc(conference->pool,sizeof(caller_control_action_t));
+									if (action != NULL) {
+										action->handler = ccfntbl[i].handler;
+										action->data = (void *)data;
+										status = switch_ivr_digit_stream_parser_set_event(conference->dtmf_parser,val,action);
+									} else {
+										switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to alloc memory for caller control binding '%s' to '%s'\n",ccfntbl[i].key,ccfntbl[i].digits);
+										status = SWITCH_STATUS_MEMERR;
+									}
 								}
 							}
 						}



More information about the Freeswitch-svn mailing list