[commit] r3839 - freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference
Author: knhor Date: Wed Dec 27 01:02:24 2006 New Revision: 3839 Modified: freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c Log: clean up the conf_api_dispatch and conf_api_sub_xxx argument handling. commonize the code to get xml section pointers. enhance chat's list output w/ more caller info. reformatted the conf_api_sub_commands table so that it is readable, please leave it that way. alphabetically sorted the conf_api_sub_commands table. 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 Dec 27 01:02:24 2006 @@ -54,6 +54,9 @@ /* this doesn't work correctly yet, don't bother trying! */ //#define OPTION_IVR_MENU_SUPPORT */ +/* define this if you want your xmpp users to be able to admin the conferences via chat */ +//#define ENABLE_CHAT_ADMIN + typedef enum { FILE_STOP_CURRENT, FILE_STOP_ALL @@ -149,11 +152,13 @@ /* conference xml config sections */ typedef struct conf_xml_cfg { + switch_xml_t cxml; switch_xml_t profile; switch_xml_t controls; #ifdef OPTION_IVR_MENU_SUPPORT switch_xml_t menus; #endif +// switch_xml_t chat_admin; } conf_xml_cfg_t; /* Conference Object */ @@ -193,6 +198,8 @@ uint32_t count; int32_t energy_level; uint8_t min; +// switch_hash_t *chat_admin; +// switch_hash_t *chat_id; } conference_obj_t; /* Relationship with another member */ @@ -312,6 +319,7 @@ static switch_status_t conf_api_sub_undeaf(conference_member_t *member, switch_stream_handle_t *stream, void *data); +static switch_status_t conference_get_xml_sections(char *profile_name, conf_xml_cfg_t *xml_cfg); /* Return a Distinct ID # */ static uint32_t next_member_id(void) @@ -368,17 +376,18 @@ conference_member_t *member = NULL; assert(conference != NULL); - assert(id != 0); - for(member = conference->members; member; member = member->next) { - - if (switch_test_flag(member, MFLAG_NOCHANNEL)) { - continue; - } - - if (member->id == id) { - break; - } + if (id != 0) { + for(member = conference->members; member; member = member->next) { + + if (switch_test_flag(member, MFLAG_NOCHANNEL)) { + continue; + } + + if (member->id == id) { + break; + } + } } @@ -394,7 +403,7 @@ assert (conference != NULL); for(member = conference->members; member; member = member->next) { - if (switch_test_flag(member, MFLAG_NOCHANNEL) && (!path || !strcmp(path, member->rec_path))) { + if (switch_test_flag(member, MFLAG_NOCHANNEL) && (path == NULL || !strcmp(path, member->rec_path))) { switch_clear_flag_locked(member, MFLAG_RUNNING); count++; } @@ -521,9 +530,6 @@ assert(conference != NULL); assert(member != NULL); - - - switch_mutex_lock(conference->mutex); switch_mutex_lock(conference->member_mutex); @@ -1202,8 +1208,6 @@ 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]); @@ -2122,7 +2126,6 @@ assert(stream != 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; @@ -2135,11 +2138,15 @@ profile = switch_channel_get_caller_profile(channel); - stream->write_function(stream, "%u) %s (%s)\n", + stream->write_function(stream, "%u) %s (%s) - %s/%s - %d/%d/%d\n", member->id, profile->caller_id_name, - profile->caller_id_number - ); + profile->caller_id_number, + (switch_test_flag(member, MFLAG_CAN_HEAR) ? "hear" : "deaf"), + (switch_test_flag(member, MFLAG_CAN_SPEAK) ? "speak" : "mute"), + member->volume_in_level, + member->volume_out_level, + member->energy_level); } @@ -2481,11 +2488,10 @@ void *val; char *d = ";"; int pretty = 0; - int argofs = (argc >= 2 && strcasecmp(argv[1], "list") == 0); // detect being called from chat vs. api - if (argv[1+argofs]) { - if (argv[2+argofs] && !strcasecmp(argv[1+argofs], "delim")) { - d = argv[2+argofs]; + if (argv[1]) { + if (argv[2] && !strcasecmp(argv[1], "delim")) { + d = argv[2]; if (*d == '"') { if (++d) { @@ -2497,7 +2503,7 @@ d = ";"; } } - } else if (strcasecmp(argv[1+argofs], "pretty") == 0) { + } else if (strcasecmp(argv[1], "pretty") == 0) { pretty = 1; } } @@ -2507,10 +2513,12 @@ switch_hash_this(hi, NULL, NULL, &val); conference = (conference_obj_t *) val; - stream->write_function(stream, "Conference %s (%u member%s)\n", + stream->write_function(stream, "Conference %s (%u member%s, %s)\n", conference->name, conference->count, - conference->count == 1 ? "" : "s"); + conference->count == 1 ? "" : "s", + (switch_test_flag(conference, CFLAG_LOCKED) ? "locked" : "unlocked") + ); if (pretty) { conference_list_pretty(conference, stream); } else { @@ -2539,35 +2547,35 @@ assert(stream != NULL); - if (argc == 3) { - if (conference_play_file(conference, argv[2], 0, NULL) == SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "(play) Playing file %s\n", argv[2]); + if (argc == 1) { + if (conference_play_file(conference, argv[0], 0, NULL) == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "(play) Playing file %s\n", argv[0]); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", conference->name); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "play-file"); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "File", argv[2]); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "File", argv[0]); switch_event_fire(&event); } } else { - stream->write_function(stream, "(play) File: %s not found.\n", argv[2] ? argv[2] : "(unspecified)"); + stream->write_function(stream, "(play) File: %s not found.\n", argv[0] ? argv[0] : "(unspecified)"); } ret_status = SWITCH_STATUS_SUCCESS; - } else if (argc == 4) { - uint32_t id = atoi(argv[3]); + } else if (argc >= 2) { + uint32_t id = atoi(argv[1]); conference_member_t *member; if ((member = conference_member_get(conference, id))) { - if (conference_member_play_file(member, argv[2], 0) == SWITCH_STATUS_SUCCESS) { - stream->write_function(stream, "(play) Playing file %s to member %u\n", argv[2], id); + if (conference_member_play_file(member, argv[0], 0) == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "(play) Playing file %s to member %u\n", argv[0], id); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", conference->name); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", id); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "play-file-member"); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "File", argv[2]); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "File", argv[0]); switch_event_fire(&event); } } else { - stream->write_function(stream, "(play) File: %s not found.\n", argv[2] ? argv[2] : "(unspecified)"); + stream->write_function(stream, "(play) File: %s not found.\n", argv[0] ? argv[0] : "(unspecified)"); } ret_status = SWITCH_STATUS_SUCCESS; } else { @@ -2677,14 +2685,14 @@ assert(conference != NULL); assert(stream != NULL); - if (argc > 2) { - current = strcasecmp(argv[2], "current") ? 0 : 1; - all = strcasecmp(argv[2], "all") ? 0 : 1; + if (argc >= 1) { + current = strcasecmp(argv[0], "current") ? 0 : 1; + all = strcasecmp(argv[0], "all") ? 0 : 1; } if (current || all) { - if (argc == 4) { - uint32_t id = atoi(argv[3]); + if (argc >= 2) { + uint32_t id = atoi(argv[1]); conference_member_t *member; if ((member = conference_member_get(conference, id))) { @@ -2711,14 +2719,10 @@ assert(conference != NULL); assert(stream != NULL); - if (argc > 4) { - uint8_t nospeak = 0, nohear = 0, clear = 0; - nospeak = strstr(argv[4], "nospeak") ? 1 : 0; - nohear = strstr(argv[4], "nohear") ? 1 : 0; - - if (!strcasecmp(argv[4], "clear")) { - clear = 1; - } + if (argc > 2) { + uint8_t clear = (strcasecmp(argv[2], "clear") == 0); + uint8_t nospeak = (strstr(argv[2], "nospeak") != NULL); + uint8_t nohear = (strstr(argv[2], "nohear") != NULL); if (!(clear || nospeak || nohear)) { ret_status = SWITCH_STATUS_GENERR; @@ -2728,8 +2732,8 @@ if (clear) { conference_member_t *member = NULL; - uint32_t id = atoi(argv[2]); - uint32_t oid = atoi(argv[3]); + uint32_t id = atoi(argv[0]); + uint32_t oid = atoi(argv[1]); switch_mutex_lock(conference->mutex); switch_mutex_lock(conference->member_mutex); @@ -2743,8 +2747,8 @@ switch_mutex_unlock(conference->mutex); } else if (nospeak || nohear) { conference_member_t *member = NULL, *other_member = NULL; - uint32_t id = atoi(argv[2]); - uint32_t oid = atoi(argv[3]); + uint32_t id = atoi(argv[0]); + uint32_t oid = atoi(argv[1]); switch_mutex_lock(conference->mutex); switch_mutex_lock(conference->member_mutex); @@ -2788,7 +2792,7 @@ assert(stream != NULL); switch_set_flag_locked(conference, CFLAG_LOCKED); - stream->write_function(stream, "OK %s locked\n", argv[0]); + stream->write_function(stream, "OK %s locked\n", conference->name); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", conference->name); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "lock"); @@ -2806,7 +2810,7 @@ assert(stream != NULL); switch_clear_flag_locked(conference, CFLAG_LOCKED); - stream->write_function(stream, "OK %s unlocked\n", argv[0]); + stream->write_function(stream, "OK %s unlocked\n", conference->name); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", conference->name); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "unlock"); @@ -2824,8 +2828,8 @@ assert(conference != NULL); assert(stream != NULL); - if (argc > 2) { - conference_outcall(conference, NULL, argv[2], 60, NULL, argv[4], argv[3]); + if (argc >= 1) { + conference_outcall(conference, NULL, argv[0], 60, NULL, (argc >= 3 ?argv[2] : NULL), (argc >=2 ? argv[1] : NULL)); stream->write_function(stream, "OK\n"); } else { ret_status = SWITCH_STATUS_GENERR; @@ -2841,17 +2845,15 @@ assert(conference != NULL); assert(stream != NULL); - if (argc > 3 && !switch_strlen_zero(argv[2])) { + if (argc >= 2 && !switch_strlen_zero(argv[0])) { int x; - for (x = 3; x<argc; x++) { + for (x = 1; x<argc; x++) { conference_member_t *member = NULL; uint32_t id = atoi(argv[x]); conference_obj_t *new_conference = NULL; switch_channel_t *channel; switch_event_t *event; - char *profile_name; - 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); @@ -2861,10 +2863,11 @@ 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[2]))) { + if (!(new_conference = (conference_obj_t *) switch_core_hash_find(globals.conference_hash, argv[0]))) { switch_memory_pool_t *pool = NULL; + conf_xml_cfg_t xml_cfg = {0}; char *conf_name; - conf_xml_cfg_t xml_cfg = {0}; + char *profile_name; /* Setup a memory pool to use. */ if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { @@ -2872,35 +2875,26 @@ goto done; } - conf_name = switch_core_strdup(pool, argv[2]); + conf_name = switch_core_strdup(pool, argv[0]); if ((profile_name = strchr(conf_name, '@'))) { *profile_name++ = '\0'; - /* Open the config from the xml registry */ - if (!(cxml = switch_xml_open_cfg(global_cf_name, &cfg, NULL))) { + /* get the xml config sections */ + if (conference_get_xml_sections(profile_name, &xml_cfg) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", global_cf_name); goto done; } - - if ((profiles = switch_xml_child(cfg, "profiles"))) { - 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 */ - if (cxml) { - switch_xml_free(cxml); - cxml = NULL; - } - /* Create the conference object. */ new_conference = conference_new(conf_name, xml_cfg, pool); + /* Release the config registry handle */ + if (xml_cfg.cxml) { + switch_xml_free(xml_cfg.cxml); + } + if (!new_conference) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); if (pool != NULL) { @@ -2923,14 +2917,14 @@ conference_del_member(member->last_conference, member); conference_add_member(new_conference, member); - stream->write_function(stream, "OK Members sent to conference %s.\n", argv[2]); + stream->write_function(stream, "OK Member %u sent to conference %s.\n", member->id, argv[0]); /* 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); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Old-Conference-Name", conference->name); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Conference-Name", argv[3]); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Conference-Name", argv[0]); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "transfer"); switch_event_fire(&event); } @@ -2949,8 +2943,8 @@ assert(conference != NULL); assert(stream != NULL); - if (argc > 2) { - launch_conference_record_thread(conference, argv[2]); + if (argc >= 1) { + launch_conference_record_thread(conference, argv[0]); } else { ret_status = SWITCH_STATUS_GENERR; } @@ -2965,11 +2959,11 @@ assert(conference != NULL); assert(stream != NULL); - if (argc > 2) { - int all = (strcasecmp(argv[2], "all") == 0 ); + if (argc >= 1) { + int all = (strcasecmp(argv[0], "all") == 0 ); - if (!conference_record_stop(conference, all ? NULL : argv[2]) && !all) { - stream->write_function(stream, "non-existant recording '%s'\n", argv[2]); + if (!conference_record_stop(conference, (all ? NULL : argv[0])) && !all) { + stream->write_function(stream, "non-existant recording '%s'\n", argv[0]); } } else { ret_status = SWITCH_STATUS_GENERR; @@ -2980,31 +2974,31 @@ /* API Interface Function sub-commands */ static api_command_t conf_api_sub_commands[] = { - {"list", &conf_api_sub_list, CONF_API_SUB_ARGS_SPLIT, "<confname> list [delim <string>]"}, - {"energy", &conf_api_sub_energy, CONF_API_SUB_MEMBER_TARGET, "<confname> energy <member_id|all|last> [<newval>]"}, - {"volume_in", &conf_api_sub_volume_in, CONF_API_SUB_MEMBER_TARGET, "<confname> volume_in <member_id|all|last> [<newval>]"}, - {"volume_out", &conf_api_sub_volume_out, CONF_API_SUB_MEMBER_TARGET, "<confname> volume_out <member_id|all|last> [<newval>]"}, - {"play", &conf_api_sub_play, CONF_API_SUB_ARGS_SPLIT, "<confname> play <file_path> [<member_id>]"}, - {"say", &conf_api_sub_say, CONF_API_SUB_ARGS_AS_ONE, "<confname> say <text>"}, - {"saymember", &conf_api_sub_saymember, CONF_API_SUB_ARGS_AS_ONE, "<confname> saymember <member_id> <text>"}, - {"stop", &conf_api_sub_stop, CONF_API_SUB_MEMBER_TARGET, "<confname> stop <[current|all|last]> [<member_id>]"}, - {"kick", &conf_api_sub_kick, CONF_API_SUB_MEMBER_TARGET, "<confname> kick <[member_id|all|last]>"}, - {"mute", &conf_api_sub_mute, CONF_API_SUB_MEMBER_TARGET, "<confname> mute <[member_id|all]|last>"}, - {"unmute", &conf_api_sub_unmute, CONF_API_SUB_MEMBER_TARGET, "<confname> unmute <[member_id|all]|last>"}, - {"deaf", &conf_api_sub_deaf, CONF_API_SUB_MEMBER_TARGET, "<confname> deaf <[member_id|all]|last>"}, - {"undeaf", &conf_api_sub_undeaf, CONF_API_SUB_MEMBER_TARGET, "<confname> undeaf <[member_id|all]|last>"}, - {"relate", &conf_api_sub_relate, CONF_API_SUB_ARGS_SPLIT, "<confname> relate <member_id> <other_member_id> [nospeak|nohear|clear]"}, - {"lock", &conf_api_sub_lock, CONF_API_SUB_ARGS_SPLIT, "<confname> lock"}, - {"unlock", &conf_api_sub_unlock, CONF_API_SUB_ARGS_SPLIT, "<confname> unlock"}, - {"dial", &conf_api_sub_dial, CONF_API_SUB_ARGS_SPLIT, "<confname> dial <endpoint_module_name>/<destination> <callerid number> <callerid name>"}, - {"transfer", &conf_api_sub_transfer, CONF_API_SUB_ARGS_SPLIT, "<confname> transfer <conference_name> <member id> [...<member id>]"}, - {"record", &conf_api_sub_record, CONF_API_SUB_ARGS_SPLIT, "<confname> record <filename>"}, - {"norecord", &conf_api_sub_norecord, CONF_API_SUB_ARGS_SPLIT, "<confname> norecord <[filename|all]>"}, + {"deaf", &conf_api_sub_deaf, CONF_API_SUB_MEMBER_TARGET, "<confname> deaf <[member_id|all]|last>"}, + {"dial", &conf_api_sub_dial, CONF_API_SUB_ARGS_SPLIT, "<confname> dial <endpoint_module_name>/<destination> <callerid number> <callerid name>"}, + {"energy", &conf_api_sub_energy, CONF_API_SUB_MEMBER_TARGET, "<confname> energy <member_id|all|last> [<newval>]"}, + {"kick", &conf_api_sub_kick, CONF_API_SUB_MEMBER_TARGET, "<confname> kick <[member_id|all|last]>"}, + {"list", &conf_api_sub_list, CONF_API_SUB_ARGS_SPLIT, "<confname> list [delim <string>]"}, + {"lock", &conf_api_sub_lock, CONF_API_SUB_ARGS_SPLIT, "<confname> lock"}, + {"mute", &conf_api_sub_mute, CONF_API_SUB_MEMBER_TARGET, "<confname> mute <[member_id|all]|last>"}, + {"norecord", &conf_api_sub_norecord, CONF_API_SUB_ARGS_SPLIT, "<confname> norecord <[filename|all]>"}, + {"play", &conf_api_sub_play, CONF_API_SUB_ARGS_SPLIT, "<confname> play <file_path> [<member_id>]"}, + {"record", &conf_api_sub_record, CONF_API_SUB_ARGS_SPLIT, "<confname> record <filename>"}, + {"relate", &conf_api_sub_relate, CONF_API_SUB_ARGS_SPLIT, "<confname> relate <member_id> <other_member_id> [nospeak|nohear|clear]"}, + {"say", &conf_api_sub_say, CONF_API_SUB_ARGS_AS_ONE, "<confname> say <text>"}, + {"saymember", &conf_api_sub_saymember, CONF_API_SUB_ARGS_AS_ONE, "<confname> saymember <member_id> <text>"}, + {"stop", &conf_api_sub_stop, CONF_API_SUB_MEMBER_TARGET, "<confname> stop <[current|all|last]> [<member_id>]"}, + {"transfer", &conf_api_sub_transfer, CONF_API_SUB_ARGS_SPLIT, "<confname> transfer <conference_name> <member id> [...<member id>]"}, + {"undeaf", &conf_api_sub_undeaf, CONF_API_SUB_MEMBER_TARGET, "<confname> undeaf <[member_id|all]|last>"}, + {"unlock", &conf_api_sub_unlock, CONF_API_SUB_ARGS_SPLIT, "<confname> unlock"}, + {"unmute", &conf_api_sub_unmute, CONF_API_SUB_MEMBER_TARGET, "<confname> unmute <[member_id|all]|last>"}, + {"volume_in", &conf_api_sub_volume_in, CONF_API_SUB_MEMBER_TARGET, "<confname> volume_in <member_id|all|last> [<newval>]"}, + {"volume_out", &conf_api_sub_volume_out, CONF_API_SUB_MEMBER_TARGET, "<confname> volume_out <member_id|all|last> [<newval>]"}, }; #define CONFFUNCAPISIZE (sizeof(conf_api_sub_commands)/sizeof(conf_api_sub_commands[0])) -switch_status_t conf_api_dispatch(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv, const char *cmdline, int argn) +switch_status_t conf_api_dispatch(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv, const char *cmdline) { switch_status_t status = SWITCH_STATUS_FALSE; uint32_t i, found = 0; @@ -3013,7 +3007,7 @@ /* loop through the command table to find a match */ for (i = 0; i<CONFFUNCAPISIZE && !found; i++) { - if (strcasecmp(argv[argn], conf_api_sub_commands[i].pname) == 0) { + if (strcasecmp(argv[0], conf_api_sub_commands[i].pname) == 0) { found = 1; switch(conf_api_sub_commands[i].fntype) { @@ -3021,7 +3015,7 @@ case CONF_API_SUB_ARGS_SPLIT: { conf_api_args_cmd_t pfn = (conf_api_args_cmd_t)conf_api_sub_commands[i].pfnapicmd; - if (pfn(conference, stream, argc, argv) != SWITCH_STATUS_SUCCESS) { + if (pfn(conference, stream, argc-1, argv+1) != SWITCH_STATUS_SUCCESS) { /* command returned error, so show syntax usage */ stream->write_function(stream, conf_api_sub_commands[i].psyntax); } @@ -3030,20 +3024,19 @@ /* member specific command that can be itteratted */ case CONF_API_SUB_MEMBER_TARGET: - { - uint32_t id = atoi(argv[argn+1]); - int all = ( id == 0 && strcasecmp(argv[argn+1], "all") == 0 ); - int last = ( id == 0 && strcasecmp(argv[argn+1], "last") == 0 ); + if (argc > 1) { + uint32_t id = atoi(argv[1]); + int all = ( id == 0 && strcasecmp(argv[1], "all") == 0 ); + int last = ( id == 0 && strcasecmp(argv[1], "last") == 0 ); if (all) { - conference_member_itterator(conference, stream, conf_api_sub_commands[i].pfnapicmd, argv[argn+2]); + conference_member_itterator(conference, stream, conf_api_sub_commands[i].pfnapicmd, argv[2]); } else if (last) { conference_member_t *member = NULL; conference_member_t *last_member = NULL; + /* find last (newest) member */ switch_mutex_lock(conference->member_mutex); - - /* find last (oldest) member */ member = conference->members; while (member != NULL) { if (last_member == NULL || member->id > last_member->id) { @@ -3051,20 +3044,19 @@ } member = member->next; } + switch_mutex_unlock(conference->member_mutex); - /* exec functio on last (oldest) member */ + /* exec function on last (newest) member */ if (last_member != NULL) { conf_api_member_cmd_t pfn = (conf_api_member_cmd_t)conf_api_sub_commands[i].pfnapicmd; - pfn(last_member, stream, argv[argn+2]); + pfn(last_member, stream, (argc > 2 ? argv[2] : NULL)); } - - switch_mutex_unlock(conference->member_mutex); } else { 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]); + pfn(member, stream, (argc > 2 ? argv[2] : NULL)); } else { if (id == 0) { stream->write_function(stream, conf_api_sub_commands[i].psyntax); @@ -3073,7 +3065,9 @@ } } } - } + } else { + stream->write_function(stream, conf_api_sub_commands[i].psyntax); + } break; /* commands that deals with all text after command */ @@ -3103,7 +3097,7 @@ } if (!found) { - stream->write_function(stream, "Confernece command '%s' not found.\n", argv[argn]); + stream->write_function(stream, "Confernece command '%s' not found.\n", argv[0]); } else { status = SWITCH_STATUS_SUCCESS; } @@ -3153,7 +3147,8 @@ } if (argc >= 2) { - conf_api_dispatch(conference, stream, argc, argv, (const char *)buf, 1); + /* call the command dispatcher after left shifting the command line */ + conf_api_dispatch(conference, stream, argc-1, argv+1, (const char *)buf); } else { stream->write_function(stream, "Conference command, not specified.\nTry 'help'\n"); } @@ -3164,8 +3159,10 @@ /* special case the list command, because it doesn't require a conference argument */ if (strcasecmp(argv[0], "list") == 0) { conf_api_sub_list(NULL, stream, argc, argv); + /* provide help */ } else if (strcasecmp(argv[0], "help") == 0 || strcasecmp(argv[0], "commands") == 0) { stream->write_function(stream, "%s\n", conf_api_interface.syntax); + /* failure */ } else { stream->write_function(stream, "Conference %s not found\n", argv[0]); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Conference %s not found\n", argv[0]); @@ -3334,6 +3331,31 @@ return status; } +static switch_status_t conference_get_xml_sections(char *profile_name, conf_xml_cfg_t *xml_cfg) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + + if (!switch_strlen_zero(profile_name) && xml_cfg != NULL) { + switch_xml_t cfg = NULL, profiles = NULL; + + xml_cfg->cxml = switch_xml_open_cfg(global_cf_name, &cfg, NULL); + + if (xml_cfg->cxml != NULL) { + if ((profiles = switch_xml_child(cfg, "profiles"))) { + 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 +// xml_cfg->chat_admin = switch_xml_child(cfg, "chat-admin"); + status = SWITCH_STATUS_SUCCESS; + } + } + + return status; +} + /* Application interface function that is called from the dialplan to join the channel to a conference */ static void conference_function(switch_core_session_t *session, char *data) { @@ -3349,7 +3371,6 @@ char *flags_prefix = "+flags{"; char *bridgeto = NULL; char *profile_name = 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}; @@ -3411,20 +3432,11 @@ if ((profile_name = strchr(conf_name, '@'))) { *profile_name++ = '\0'; - /* Open the config from the xml registry */ - if (!(cxml = switch_xml_open_cfg(global_cf_name, &cfg, NULL))) { + /* get the xml config sections */ + if (conference_get_xml_sections(profile_name, &xml_cfg) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", global_cf_name); goto done; } - - if ((profiles = switch_xml_child(cfg, "profiles"))) { - 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 */ @@ -3557,9 +3569,9 @@ } /* Release the config registry handle */ - if (cxml) { - switch_xml_free(cxml); - cxml = NULL; + if (xml_cfg.cxml) { + switch_xml_free(xml_cfg.cxml); + xml_cfg.cxml = NULL; } /* if we're using "bridge:" make an outbound call and bridge it in */ @@ -3693,8 +3705,8 @@ switch_buffer_destroy(&member.mux_buffer); /* Release the config registry handle */ - if (cxml) { - switch_xml_free(cxml); + if (xml_cfg.cxml) { + switch_xml_free(xml_cfg.cxml); } if (freepool) { @@ -3816,16 +3828,20 @@ if (argc) { /* special case list */ if (strcasecmp(argv[0], "list") == 0) { + stream.write_function(&stream, "(%u member%s, %s)\n", + conference->count, + conference->count == 1 ? "" : "s", + (switch_test_flag(conference, CFLAG_LOCKED) ? "locked" : "unlocked") + ); conference_list_pretty(conference, &stream); - /* provide help */ - } - else { - if (strcasecmp(argv[0], "help") == 0 || strcasecmp(argv[0], "commands") == 0) { +#ifdef ENABLE_CHAT_ADMIN + /* provide help */ + } else if (strcasecmp(argv[0], "help") == 0 || strcasecmp(argv[0], "commands") == 0) { stream.write_function(&stream, "%s\n", conf_api_interface.syntax); - /* find a normal command */ - } else { - conf_api_dispatch(conference, &stream, argc, argv, (const char *)body, 0); - } + /* find a normal command */ + } else { + conf_api_dispatch(conference, &stream, argc, argv, (const char *)body); +#endif } } else { stream.write_function(&stream, "No parameters specified.\nTry 'help'\n");
participants (1)
-
Freeswitch SVN