[Freeswitch-svn] [commit] r3440 - freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference
Freeswitch SVN
knhor at freeswitch.org
Wed Nov 22 20:40:14 EST 2006
Author: knhor
Date: Wed Nov 22 20:40:14 2006
New Revision: 3440
Modified:
freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c
Log:
mostly complete support or ivr menus with caller control callbacks
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 22 20:40:14 2006
@@ -56,12 +56,23 @@
FILE_STOP_ALL
} file_stop_t;
+/* Global Values */
+static struct {
+ switch_memory_pool_t *conference_pool;
+ switch_mutex_t *conference_mutex;
+ switch_hash_t *conference_hash;
+ switch_mutex_t *id_mutex;
+ switch_mutex_t *hash_mutex;
+ uint32_t id_pool;
+ int32_t running;
+ uint32_t threads;
+} globals;
+
typedef enum {
- CALLER_CONTROL_NOEVENT,
CALLER_CONTROL_MUTE,
CALLER_CONTROL_DEAF_MUTE,
CALLER_CONTROL_ENERGY_UP,
- CALLER_CONTROL_ENERGY_EQU_CONFERENCE,
+ CALLER_CONTROL_ENERGY_EQU_CONF,
CALLER_CONTROL_ENERGEY_DN,
CALLER_CONTROL_VOL_TALK_UP,
CALLER_CONTROL_VOL_TALK_ZERO,
@@ -70,44 +81,23 @@
CALLER_CONTROL_VOL_LISTEN_ZERO,
CALLER_CONTROL_VOL_LISTEN_DN,
CALLER_CONTROL_HANGUP,
+ CALLER_CONTROL_MENU,
} caller_control_t;
-static struct _caller_control_actions_struct {
- char *key;
- char *default_digits;
- caller_control_t action;
-} caller_control_actions[] = {
- {"mute", "0", CALLER_CONTROL_MUTE},
- {"deaf mute", "*", CALLER_CONTROL_DEAF_MUTE},
- {"energy up", "9", CALLER_CONTROL_ENERGY_UP},
- {"energy equ", "8", CALLER_CONTROL_ENERGY_EQU_CONFERENCE},
- {"energy dn", "7", CALLER_CONTROL_ENERGEY_DN},
- {"vol talk up", "3", CALLER_CONTROL_VOL_TALK_UP},
- {"vol talk zero", "2", CALLER_CONTROL_VOL_TALK_ZERO},
- {"vol talk dn", "1", CALLER_CONTROL_VOL_TALK_DN},
- {"vol listen up", "6", CALLER_CONTROL_VOL_LISTEN_UP},
- {"vol listen zero", "5", CALLER_CONTROL_VOL_LISTEN_ZERO},
- {"vol listen dn", "4", CALLER_CONTROL_VOL_LISTEN_DN},
- {"hangup", "#", CALLER_CONTROL_HANGUP},
-};
-#define CALLER_CONTROL_ACTIONS_QTY (sizeof(caller_control_actions)/sizeof(caller_control_actions[0]))
-
-/* Global Values */
-static struct {
- switch_memory_pool_t *conference_pool;
- switch_mutex_t *conference_mutex;
- switch_hash_t *conference_hash;
- switch_mutex_t *id_mutex;
- switch_mutex_t *hash_mutex;
- uint32_t id_pool;
- int32_t running;
- uint32_t threads;
-} globals;
-
-// forward declaration for conference_obj structure
+// forward declaration for conference_obj and caller_control
struct conference_member;
typedef struct conference_member conference_member_t;
+typedef struct caller_control_actions {
+ void (*handler)(conference_member_t *, void *);
+ void *data;
+} caller_control_action_t;
+
+typedef struct caller_control_menu_info {
+ switch_ivr_menu_t *stack;
+ char *name;
+} caller_control_menu_info_t;
+
typedef enum {
MFLAG_RUNNING = (1 << 0),
MFLAG_CAN_SPEAK = (1 << 1),
@@ -117,7 +107,6 @@
MFLAG_NOCHANNEL = (1 << 5)
} member_flag_t;
-
typedef enum {
CFLAG_RUNNING = (1 << 0),
CFLAG_DYNAMIC = (1 << 1),
@@ -137,7 +126,7 @@
NODE_TYPE_SPEECH
} node_type_t;
-struct confernce_file_node {
+typedef struct confernce_file_node {
switch_file_handle_t fh;
switch_speech_handle_t sh;
node_type_t type;
@@ -145,12 +134,10 @@
switch_memory_pool_t *pool;
uint32_t leadin;
struct confernce_file_node *next;
-};
+} confernce_file_node_t;
-typedef struct confernce_file_node confernce_file_node_t;
-
/* Conference Object */
-struct conference_obj {
+typedef struct conference_obj {
char *name;
char *timer_name;
char *tts_engine;
@@ -186,16 +173,14 @@
uint32_t count;
int32_t energy_level;
uint8_t min;
-};
-typedef struct conference_obj conference_obj_t;
+} conference_obj_t;
/* Relationship with another member */
-struct conference_relationship {
+typedef struct conference_relationship {
uint32_t id;
uint32_t flags;
struct conference_relationship *next;
-};
-typedef struct conference_relationship conference_relationship_t;
+} conference_relationship_t;
/* Conference Member Object */
struct conference_member {
@@ -231,12 +216,11 @@
};
/* Record Node */
-struct conference_record {
+typedef struct conference_record {
conference_obj_t *conference;
char *path;
switch_memory_pool_t *pool;
-};
-typedef struct conference_record conference_record_t;
+} conference_record_t;
// API command parser
typedef struct api_command {
@@ -272,7 +256,6 @@
static void conference_function(switch_core_session_t *session, char *data);
static void launch_conference_thread(conference_obj_t *conference);
static void *SWITCH_THREAD_FUNC input_thread_run(switch_thread_t *thread, void *obj);
-static void launch_input_thread(conference_member_t *member, switch_memory_pool_t *pool);
static switch_status_t conference_local_play_file(switch_core_session_t *session, char *path, uint32_t leadin, char *buf, switch_size_t len);
static switch_status_t conference_member_play_file(conference_member_t *member, char *file, uint32_t leadin);
static switch_status_t conference_member_say(conference_obj_t *conference, conference_member_t *member, char *text, uint32_t leadin);
@@ -807,7 +790,7 @@
return NULL;
}
-static void conference_loop_fn_mute_toggle(conference_member_t *member)
+static void conference_loop_fn_mute_toggle(conference_member_t *member, void *data)
{
if (switch_test_flag(member, MFLAG_CAN_SPEAK)) {
conf_api_sub_mute(member, NULL, NULL);
@@ -817,7 +800,7 @@
}
}
-static void conference_loop_fn_deafmute_toggle(conference_member_t *member)
+static void conference_loop_fn_deafmute_toggle(conference_member_t *member, void *data)
{
if (switch_test_flag(member, MFLAG_CAN_SPEAK)) {
conf_api_sub_mute(member, NULL, NULL);
@@ -828,7 +811,7 @@
}
}
-static void conference_loop_fn_energy_up(conference_member_t *member)
+static void conference_loop_fn_energy_up(conference_member_t *member, void *data)
{
char msg[512];
@@ -842,7 +825,7 @@
conference_member_say(member->conference, member, msg, 0);
}
-static void conference_loop_fn_energy_equ_conference(conference_member_t *member)
+static void conference_loop_fn_energy_equ_conf(conference_member_t *member, void *data)
{
char msg[512];
@@ -853,7 +836,7 @@
conference_member_say(member->conference, member, msg, 0);
}
-static void conference_loop_fn_energy_dn(conference_member_t *member)
+static void conference_loop_fn_energy_dn(conference_member_t *member, void *data)
{
char msg[512];
@@ -867,7 +850,7 @@
conference_member_say(member->conference, member, msg, 0);
}
-static void conference_loop_fn_volume_talk_up(conference_member_t *member)
+static void conference_loop_fn_volume_talk_up(conference_member_t *member, void *data)
{
char msg[512];
@@ -879,7 +862,7 @@
conference_member_say(member->conference, member, msg, 0);
}
-static void conference_loop_fn_volume_talk_zero(conference_member_t *member)
+static void conference_loop_fn_volume_talk_zero(conference_member_t *member, void *data)
{
char msg[512];
@@ -890,7 +873,7 @@
conference_member_say(member->conference, member, msg, 0);
}
-static void conference_loop_fn_volume_talk_dn(conference_member_t *member)
+static void conference_loop_fn_volume_talk_dn(conference_member_t *member, void *data)
{
char msg[512];
@@ -902,7 +885,7 @@
conference_member_say(member->conference, member, msg, 0);
}
-static void conference_loop_fn_volume_listen_up(conference_member_t *member)
+static void conference_loop_fn_volume_listen_up(conference_member_t *member, void *data)
{
char msg[512];
@@ -914,7 +897,7 @@
conference_member_say(member->conference, member, msg, 0);
}
-static void conference_loop_fn_volume_listen_zero(conference_member_t *member)
+static void conference_loop_fn_volume_listen_zero(conference_member_t *member, void *data)
{
char msg[512];
@@ -925,7 +908,7 @@
conference_member_say(member->conference, member, msg, 0);
}
-static void conference_loop_fn_volume_listen_dn(conference_member_t *member)
+static void conference_loop_fn_volume_listen_dn(conference_member_t *member, void *data)
{
char msg[512];
@@ -937,11 +920,34 @@
conference_member_say(member->conference, member, msg, 0);
}
-static void conference_loop_fn_hangup(conference_member_t *member)
+static void conference_loop_fn_hangup(conference_member_t *member, void *data)
{
switch_clear_flag_locked(member, MFLAG_RUNNING);
}
+typedef struct caller_control_menu_ctx {
+ switch_ivr_menu_xml_ctx_t *xml_ctx;
+ switch_ivr_menu_t *menu_stack;
+ char *name;
+} caller_control_menu_ctx_t;
+
+static void conference_loop_fn_menu(conference_member_t *member, void *data)
+{
+ if (data != NULL) {
+ caller_control_menu_ctx_t *menu_ctx = (caller_control_menu_ctx_t *)data;
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "conference_loop_fn_menu handler '%s'\n",menu_ctx->name);
+ if (menu_ctx->menu_stack != NULL && menu_ctx->xml_ctx != NULL) {
+ switch_ivr_menu_execute(member->session,menu_ctx->menu_stack,menu_ctx->name,NULL);
+ } else {
+ if(menu_ctx->menu_stack == NULL)
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "conference_loop_fn_menu handler NULL menu_stack\n");
+ if(menu_ctx->xml_ctx == NULL)
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "conference_loop_fn_menu handler NULL xml_ctx\n");
+ }
+ }
+}
+
/* Create a thread for the conference and launch it */
static void launch_input_thread(conference_member_t *member, switch_memory_pool_t *pool)
{
@@ -1038,51 +1044,13 @@
switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
if(member->conference->dtmf_parser != NULL) {
- for (digit = dtmf; *digit; digit++) {
- int *action = (int *)switch_ivr_digit_stream_parser_feed(member->conference->dtmf_parser, *digit);
+ caller_control_action_t *action;
- if (action != NULL) {
- switch(*action) {
- case CALLER_CONTROL_NOEVENT:
- // the digit string collected so far has not been recognized
- break;
- case CALLER_CONTROL_MUTE:
- conference_loop_fn_mute_toggle(member);
- break;
- case CALLER_CONTROL_DEAF_MUTE:
- conference_loop_fn_deafmute_toggle(member);
- break;
- case CALLER_CONTROL_ENERGY_UP:
- conference_loop_fn_energy_up(member);
- break;
- case CALLER_CONTROL_ENERGY_EQU_CONFERENCE:
- conference_loop_fn_energy_equ_conference(member);
- break;
- case CALLER_CONTROL_ENERGEY_DN:
- conference_loop_fn_energy_dn(member);
- break;
- case CALLER_CONTROL_VOL_TALK_UP:
- conference_loop_fn_volume_talk_up(member);
- break;
- case CALLER_CONTROL_VOL_TALK_ZERO:
- conference_loop_fn_volume_talk_zero(member);
- break;
- case CALLER_CONTROL_VOL_TALK_DN:
- conference_loop_fn_volume_talk_dn(member);
- break;
- case CALLER_CONTROL_VOL_LISTEN_UP:
- conference_loop_fn_volume_listen_up(member);
- break;
- case CALLER_CONTROL_VOL_LISTEN_ZERO:
- conference_loop_fn_volume_listen_zero(member);
- break;
- case CALLER_CONTROL_VOL_LISTEN_DN:
- conference_loop_fn_volume_listen_dn(member);
- break;
- case CALLER_CONTROL_HANGUP:
- conference_loop_fn_hangup(member);
- break;
- }
+ 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);
+ if (action != NULL && action->handler != NULL) {
+ action->handler(member,action->data);
}
}
}
@@ -3254,11 +3222,71 @@
/*.chat_interface */ &conference_chat_interface
};
+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;
+
+ if (param != NULL) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "caller control menu action '%s'\n",param);
+ }
+
+ return action;
+}
+
+static switch_status_t conference_caller_control_menu_build(caller_control_menu_ctx_t **ctx, conference_obj_t *conference, switch_xml_t profile, char *menu_name)
+{
+ switch_status_t status = SWITCH_STATUS_FALSE;
+
+ if (ctx != NULL && conference != NULL && profile != NULL && menu_name != NULL) {
+ switch_xml_t xml_menus = switch_xml_child(profile, "menus");
+ switch_xml_t xml_menu = (xml_menus != NULL ? switch_xml_find_child(xml_menus, "menu", "name", menu_name) : NULL);
+
+ // if we found the requested menu in our profile
+ if (xml_menu != NULL && xml_menu != NULL) {
+ *ctx = (caller_control_menu_ctx_t *)switch_core_alloc(conference->pool,sizeof(caller_control_menu_ctx_t));
+
+ if (*ctx != NULL) {
+ memset(*ctx,0,sizeof(caller_control_menu_ctx_t));
+
+ // setup an xml parser context, and a menu stack context for the specified menu in our memory pool
+ status = switch_ivr_menu_stack_xml_init(&(*ctx)->xml_ctx, conference->pool);
+ if (status == SWITCH_STATUS_SUCCESS) {
+ (*ctx)->name = switch_core_strdup(conference->pool,menu_name);
+ // add our xml menu handler to the xml stack parser
+ status = switch_ivr_menu_stack_xml_add_custom((*ctx)->xml_ctx, "control", &conference_caller_control_menu_handler);
+ if (status != SWITCH_STATUS_SUCCESS)
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to add custom xml handler\n");
+ // parse the xml stack to build the menu stack
+ status = switch_ivr_menu_stack_xml_build((*ctx)->xml_ctx, &(*ctx)->menu_stack, xml_menus, xml_menu, conference->timer_name);
+ if (status != SWITCH_STATUS_SUCCESS)
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to build xml menu stack\n");
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to init xml menu context\n");
+ }
+ if (status != SWITCH_STATUS_SUCCESS)
+ *ctx = NULL;
+ }
+ } else {
+ if(xml_menus == NULL)
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "caller control menu unable to find xml menus\n");
+ if(xml_menu == NULL)
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "caller control menu unable to find xml menu '%s'\n",menu_name);
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "null parameters!\n");
+ }
+
+ return status;
+}
+
/* create a new conferene with a specific profile */
static conference_obj_t *conference_new(char *name, switch_xml_t profile, switch_memory_pool_t *pool)
{
conference_obj_t *conference;
switch_xml_t xml_kvp;
+ switch_xml_t xml_controls;
+ switch_xml_t xml_menus;
+ char *controls_set = NULL;
char *rate_name = NULL;
char *interval_name = NULL;
char *timer_name = NULL;
@@ -3470,46 +3498,125 @@
conference->rate = rate;
conference->interval = interval;
- if(switch_ivr_digit_stream_parser_new(conference->pool,&conference->dtmf_parser) == SWITCH_STATUS_SUCCESS) {
- int i;
+ xml_controls = switch_xml_child(profile, "controls");
+ controls_set = (xml_controls != NULL ? (char *) switch_xml_attr_soft(xml_controls, "set") : NULL);
- // count the number of caller control definitons in the profile
- for (i=0,xml_kvp = switch_xml_child(profile, "control"); xml_kvp; xml_kvp = xml_kvp->next) {
- i++;
- }
- // map in the default control handler strings only if the profile has no caller control definitions
- if (i == 0) {
- for(i=0,status=SWITCH_STATUS_SUCCESS; status == SWITCH_STATUS_SUCCESS && i<CALLER_CONTROL_ACTIONS_QTY; i++) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Installing default caller control action name '%s' bound to '%s' digits.\n",
- caller_control_actions[i].key,caller_control_actions[i].default_digits);
- status = switch_ivr_digit_stream_parser_set_event(conference->dtmf_parser,caller_control_actions[i].default_digits,(void *)&(caller_control_actions[i].action));
- }
- }
+ // try to build caller control if the set has been specified and != "none"
+ if (xml_controls != NULL && controls_set != NULL && strcasecmp(controls_set,"none") != 0) {
+ struct default_caller_control_table {
+ char *key;
+ char *digits;
+ caller_control_t action;
+ void (*handler)(conference_member_t *, void *);
+ } dcctbl[] = {
+ {"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},
+ };
+ int dcctbl_qty = (sizeof(dcctbl)/sizeof(dcctbl[0]));
- // parse the profile tree for caller control digit strings
- for (xml_kvp = switch_xml_child(profile, "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");
+ if(switch_ivr_digit_stream_parser_new(conference->pool,&conference->dtmf_parser) == SWITCH_STATUS_SUCCESS) {
+
+ // map in the default control handler strings if specified
+ if (strcasecmp(controls_set,"default") == 0) {
+ int i;
+ caller_control_action_t *action;
- if(key != NULL && val != NULL && *key && *val) {
- // 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<CALLER_CONTROL_ACTIONS_QTY && status == SWITCH_STATUS_NOOP; i++) {
- if(strcasecmp(caller_control_actions[i].key,key) == 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Installing caller control action name '%s' bound to '%s' digits.\n",key,val);
- status = switch_ivr_digit_stream_parser_set_event(conference->dtmf_parser,val,(void *)&caller_control_actions[i].action);
+ for(i=0,status=SWITCH_STATUS_SUCCESS; status == SWITCH_STATUS_SUCCESS && i<dcctbl_qty; i++) {
+ switch(dcctbl[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",
+ dcctbl[i].key,
+ dcctbl[i].digits);
+ action = (caller_control_action_t *)switch_core_alloc(conference->pool,sizeof(caller_control_action_t));
+ if (action != NULL) {
+ action->handler = dcctbl[i].handler;
+ action->data = NULL;
+ status = switch_ivr_digit_stream_parser_set_event(conference->dtmf_parser,dcctbl[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",dcctbl[i].key,dcctbl[i].digits);
+ status = SWITCH_STATUS_MEMERR;
+ }
+ break;
}
}
- if(status == SWITCH_STATUS_NOOP) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid caller control action name '%s'.\n",key);
+ } else if (strcasecmp(controls_set,"custom") == 0) {
+ // parse the controls tree for caller control digit strings
+ 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");
+
+ 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<dcctbl_qty && status == SWITCH_STATUS_NOOP; i++) {
+ caller_control_menu_ctx_t *menu_ctx = NULL;
+
+ if(strcasecmp(dcctbl[i].key,key) == 0) {
+ switch(dcctbl[i].action)
+ {
+ case CALLER_CONTROL_MENU:
+ {
+ char *menu_name = (char *)switch_xml_attr_soft(xml_kvp, "menu-name");
+
+ 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 = dcctbl[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",dcctbl[i].key,dcctbl[i].digits);
+ status = SWITCH_STATUS_MEMERR;
+ }
+ break;
+ }
+ }
+ }
+ if(status == SWITCH_STATUS_NOOP) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid caller control action name '%s'.\n",key);
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid caller control config entry pair action='%s' digits='%s'\n",key,val);
+ }
}
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid caller control config entry pair action='%s' digits='%s'\n",key,val);
}
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to allocate caller control digit parser.\n");
}
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to allocate caller control digit parser.\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no caller controls intalled.\n");
+ }
+
+ xml_menus = switch_xml_child(profile, "menus");
+ if (xml_menus != NULL) {
+// switch_xml_t xml_menu;
}
/* Activate the conference mutex for exclusivity */
More information about the Freeswitch-svn
mailing list