[Freeswitch-svn] [commit] r3839 - freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference
Freeswitch SVN
knhor at freeswitch.org
Wed Dec 27 01:02:24 EST 2006
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");
More information about the Freeswitch-svn
mailing list