Author: knhor Date: Sun Dec 10 16:08:25 2006 New Revision: 3598 Modified: freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c Log: move both caller controls and ivr menus out of the conference profile into their own sections with conference.conf xml section 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 Sun Dec 10 16:08:25 2006 @@ -147,6 +147,15 @@ struct confernce_file_node *next; } confernce_file_node_t; +/* conference xml config sections */ +typedef struct conf_xml_cfg { + switch_xml_t profile; + switch_xml_t controls; +#ifdef OPTION_IVR_MENU_SUPPORT + switch_xml_t menus; +#endif +} conf_xml_cfg_t; + /* Conference Object */ typedef struct conference_obj { char *name; @@ -272,7 +281,7 @@ 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_member_t *member, char *text, uint32_t leadin); static uint32_t conference_member_stop_file(conference_member_t *member, file_stop_t stop); -static conference_obj_t *conference_new(char *name, switch_xml_t profile, switch_memory_pool_t *pool); +static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_memory_pool_t *pool); static switch_status_t chat_send(char *proto, char *from, char *to, char *subject, char *body, char *hint); static void launch_conference_record_thread(conference_obj_t *conference, char *path); @@ -2457,7 +2466,7 @@ switch_channel_t *channel; switch_event_t *event; char *profile_name; - switch_xml_t cxml = NULL, cfg = NULL, profile = NULL, profiles = NULL; + switch_xml_t cxml = NULL, cfg = NULL, profiles = NULL; if (!(member = conference_member_get(conference, id))) { stream->write_function(stream, "No Member %u in conference %s.\n", id, conference->name); @@ -2470,6 +2479,7 @@ if (!(new_conference = (conference_obj_t *) switch_core_hash_find(globals.conference_hash, argv[3]))) { switch_memory_pool_t *pool; char *conf_name; + conf_xml_cfg_t xml_cfg; /* Setup a memory pool to use. */ if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { @@ -2489,8 +2499,12 @@ } if ((profiles = switch_xml_child(cfg, "profiles"))) { - profile = switch_xml_find_child(profiles, "profile", "name", profile_name); + xml_cfg.profile = switch_xml_find_child(profiles, "profile", "name", profile_name); } + xml_cfg.controls = switch_xml_child(cfg, "caller-controls"); +#ifdef OPTION_IVR_MENU_SUPPORT + xml_cfg.menus = switch_xml_child(cfg, "menus"); +#endif } /* Release the config registry handle */ @@ -2500,7 +2514,7 @@ } /* Create the conference object. */ - new_conference = conference_new(conf_name, profile, pool); + new_conference = conference_new(conf_name, xml_cfg, pool); if (!new_conference) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); @@ -2907,12 +2921,13 @@ char *flags_prefix = "+flags{"; char *bridgeto = NULL; char *profile_name = NULL; - switch_xml_t cxml = NULL, cfg = NULL, profile = NULL, profiles = NULL; + switch_xml_t cxml = NULL, cfg = NULL, profiles = NULL; char *flags_str; member_flag_t uflags = MFLAG_CAN_SPEAK | MFLAG_CAN_HEAR; switch_core_session_message_t msg = {0}; uint8_t rl = 0, isbr = 0; char *dpin = NULL; + conf_xml_cfg_t xml_cfg; channel = switch_core_session_get_channel(session); assert(channel != NULL); @@ -2975,8 +2990,13 @@ } if ((profiles = switch_xml_child(cfg, "profiles"))) { - profile = switch_xml_find_child(profiles, "profile", "name", profile_name); + xml_cfg.profile = switch_xml_find_child(profiles, "profile", "name", profile_name); } + + xml_cfg.controls = switch_xml_child(cfg, "caller-controls"); +#ifdef OPTION_IVR_MENU_SUPPORT + xml_cfg.menus = switch_xml_child(cfg, "menus"); +#endif } /* if this is a bridging call, and it's not a duplicate, build a */ @@ -2994,7 +3014,7 @@ } /* Create the conference object. */ - conference = conference_new(conf_name, profile, pool); + conference = conference_new(conf_name, xml_cfg, pool); if (!conference) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); @@ -3021,7 +3041,7 @@ freepool = pool; /* couldn't find the conference, create one */ } else { - conference = conference_new(conf_name, profile, pool); + conference = conference_new(conf_name, xml_cfg, pool); if (!conference) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); @@ -3487,15 +3507,15 @@ } */ -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) +static switch_status_t conference_caller_control_menu_build(caller_control_menu_ctx_t **ctx, conference_obj_t *conference, switch_xml_t menu_group, 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"); + if (ctx != NULL && conference != NULL && menu_group != NULL && menu_name != NULL) { + switch_xml_t xml_menus = switch_xml_child(menu_group, "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 we found the requested menu in our menu_group */ if (xml_menu != NULL && xml_menu != NULL) { *ctx = (caller_control_menu_ctx_t *)switch_core_alloc(conference->pool,sizeof(caller_control_menu_ctx_t)); @@ -3575,11 +3595,11 @@ return status; } -static switch_status_t conference_new_install_caller_controls_custom(conference_obj_t *conference, switch_xml_t profile, switch_xml_t xml_controls) +static switch_status_t conference_new_install_caller_controls_custom(conference_obj_t *conference, switch_xml_t xml_controls, switch_xml_t xml_menus) { switch_status_t status = SWITCH_STATUS_FALSE; - if (conference != NULL && profile != NULL && xml_controls != NULL) { + if (conference != NULL && xml_controls != NULL) { switch_xml_t xml_kvp; /* parse the controls tree for caller control digit strings */ @@ -3599,15 +3619,34 @@ if(strcasecmp(ccfntbl[i].key,key) == 0) { status = SWITCH_STATUS_SUCCESS; #ifdef OPTION_IVR_MENU_SUPPORT - if (ccfntbl[i].action == CALLER_CONTROL_MENU) { - caller_control_menu_ctx_t *menu_ctx = NULL; + if (xml_menus != NULL && ccfntbl[i].action == CALLER_CONTROL_MENU) { + char *menu_group_name = strdup(data); + char *menu_name = (menu_group_name != NULL ? strchr(menu_group_name,'/') : NULL); - status = conference_caller_control_menu_build(&menu_ctx,conference,profile,data); - data = (char *)menu_ctx; + /* format: "menu_group_name/menu_name" */ + /* separate the menu name from the menu group */ + if (menu_name != NULL) { + *(menu_name++) = '\0'; + } + /* if there is a menu name, build the menu */ + if (menu_name != NULL) { + caller_control_menu_ctx_t *menu_ctx = NULL; + switch_xml_t menu_group = switch_xml_find_child(xml_menus, "group", "name", menu_group_name); + status = conference_caller_control_menu_build(&menu_ctx, conference, menu_group, menu_name); + data = (char *)menu_ctx; + } else { + status = SWITCH_STATUS_FALSE; + } + 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); } + + /* clean up */ + if (menu_group_name != NULL) { + free(menu_group_name); + } } #endif @@ -3640,12 +3679,10 @@ } /* 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) +static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_memory_pool_t *pool) { conference_obj_t *conference; switch_xml_t xml_kvp; - switch_xml_t xml_controls; - char *controls_set = NULL; char *rate_name = NULL; char *interval_name = NULL; char *timer_name = NULL; @@ -3667,6 +3704,7 @@ char *energy_level = NULL; char *caller_id_name = NULL; char *caller_id_number = NULL; + char *caller_controls = NULL; uint32_t rate = 8000, interval = 20; switch_status_t status; @@ -3677,7 +3715,7 @@ } /* parse the profile tree for param values */ - for (xml_kvp = switch_xml_child(profile, "param"); xml_kvp; xml_kvp = xml_kvp->next) { + for (xml_kvp = switch_xml_child(cfg.profile, "param"); xml_kvp; xml_kvp = xml_kvp->next) { char *var = (char *) switch_xml_attr_soft(xml_kvp, "name"); char *val = (char *) switch_xml_attr_soft(xml_kvp, "value"); char buf[128] = ""; @@ -3735,6 +3773,8 @@ caller_id_name = val; } else if (!strcasecmp(var, "caller-id-number")) { caller_id_number = val; + } else if (!strcasecmp(var, "caller-controls")) { + caller_controls = val; } } @@ -3858,26 +3898,25 @@ conference->interval = interval; conference->dtmf_parser = NULL; - if(switch_ivr_digit_stream_parser_new(conference->pool,&conference->dtmf_parser) == SWITCH_STATUS_SUCCESS) { + /* caller control configuration chores */ + if(switch_ivr_digit_stream_parser_new(conference->pool, &conference->dtmf_parser) == SWITCH_STATUS_SUCCESS) { - /* caller control configuration chores */ - xml_controls = switch_xml_child(profile, "controls"); - controls_set = (xml_controls != NULL ? (char *) switch_xml_attr_soft(xml_controls, "set") : NULL); - - if (xml_controls == NULL) { - /* if no controls specified in the config, assume all should be specified */ + /* if no controls, or default controls specified, install default */ + if (caller_controls == NULL || *caller_controls == '\0' || strcasecmp(caller_controls, "default") == 0) { status = conference_new_install_caller_controls_default(conference); - } else if (xml_controls != NULL && controls_set != NULL && strcasecmp(controls_set,"none") != 0) { - /* try to build caller control if the set has been specified and != "none" */ - if (strcasecmp(controls_set,"default") == 0) { - status = conference_new_install_caller_controls_default(conference); - } else if (strcasecmp(controls_set,"custom") == 0) { - status = conference_new_install_caller_controls_custom(conference,profile,xml_controls); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown caller control set.\n"); + } else if (strcasecmp(caller_controls,"none") != 0) { + /* try to build caller control if the group has been specified and != "none" */ + switch_xml_t xml_controls = switch_xml_find_child(cfg.controls, "group", "name", caller_controls); +#ifdef OPTION_IVR_MENU_SUPPORT + status = conference_new_install_caller_controls_custom(conference, xml_controls, cfg.menus); +#else + status = conference_new_install_caller_controls_custom(conference, xml_controls, NULL); +#endif + if (status != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to install caller controls group '%s'\n",caller_controls); } } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no caller controls intalled.\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "no caller controls intalled.\n"); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to allocate caller control digit parser.\n");