[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