Freeswitch-svn
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- 12151 discussions
Author: anthm
Date: Sun Dec 31 16:06:03 2006
New Revision: 3879
Modified:
freeswitch/trunk/src/switch_ivr.c
Log:
fix hold issue reported by irate anonymous guy on irc
Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c (original)
+++ freeswitch/trunk/src/switch_ivr.c Sun Dec 31 16:06:03 2006
@@ -1301,7 +1301,7 @@
} else { /* time off the channel (if you must) */
switch_frame_t *read_frame;
switch_status_t status;
- while (switch_channel_test_flag(channel, CF_HOLD)) {
+ while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_HOLD)) {
switch_yield(10000);
}
status = switch_core_session_read_frame(session, &read_frame, -1, 0);
@@ -1604,7 +1604,7 @@
switch_frame_t *read_frame;
switch_status_t status = switch_core_session_read_frame(session, &read_frame, -1, 0);
- while (switch_channel_test_flag(channel, CF_HOLD)) {
+ while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_HOLD)) {
switch_yield(10000);
}
@@ -1661,7 +1661,7 @@
switch_frame_t *read_frame;
switch_status_t status = switch_core_session_read_frame(session, &read_frame, -1, 0);
- while (switch_channel_test_flag(channel, CF_HOLD)) {
+ while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_HOLD)) {
switch_yield(10000);
}
1
0
[commit] r3878 - freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference
by Freeswitch SVN 31 Dec '06
by Freeswitch SVN 31 Dec '06
31 Dec '06
Author: knhor
Date: Sun Dec 31 15:02:01 2006
New Revision: 3878
Modified:
freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c
Log:
oops.. don't keep the xml config registry locked!
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 31 15:02:01 2006
@@ -199,7 +199,6 @@
uint32_t count;
int32_t energy_level;
uint8_t min;
- conf_xml_cfg_t xml_cfg;
switch_hash_t *chat_permissions_map;
} conference_obj_t;
@@ -1679,31 +1678,6 @@
/* Start the input thread */
launch_conference_loop_input(member, switch_core_session_get_pool(member->session));
- /* caller control configuration chores */
- if (switch_ivr_digit_stream_parser_new(member->pool, &member->dtmf_parser) == SWITCH_STATUS_SUCCESS) {
- switch_status_t status = SWITCH_STATUS_FALSE;
-
- /* if no controls, or default controls specified, install default */
- if (member->conference->caller_controls == NULL || *member->conference->caller_controls == '\0' || strcasecmp(member->conference->caller_controls, "default") == 0) {
- status = caller_control_build_default(member);
- } else if (strcasecmp(member->conference->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(member->conference->xml_cfg.controls, "group", "name", member->conference->caller_controls);
-#ifdef OPTION_IVR_MENU_SUPPORT
- status = caller_control_build_custom(member, xml_controls, member->conference->xml_cfg.menus);
-#else
- status = caller_control_build_custom(member, 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", member->conference->caller_controls);
- }
- } else {
- 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");
- }
-
/* build a digit stream object */
if (member->dtmf_parser != NULL && switch_ivr_digit_stream_new(member->dtmf_parser, &member->digit_stream) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Warning Will Robinson, there is no digit parser stream object\n");
@@ -3174,10 +3148,6 @@
if (pool != NULL) {
switch_core_destroy_memory_pool(&pool);
}
- /* Release the config registry handle */
- if (xml_cfg.cxml) {
- switch_xml_free(xml_cfg.cxml);
- }
goto done;
}
@@ -3189,6 +3159,12 @@
/* Start the conference thread for this conference */
launch_conference_thread(new_conference);
+
+ /* Release the config registry thread lock */
+ if (xml_cfg.cxml) {
+ switch_xml_free(xml_cfg.cxml);
+ memset(&xml_cfg,0,sizeof(xml_cfg));
+ }
}
/* move the member from the old conference to the new one */
@@ -3952,6 +3928,37 @@
msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
switch_core_session_receive_message(session, &msg);
+ /* caller control configuration chores */
+ if (switch_ivr_digit_stream_parser_new(member.pool, &member.dtmf_parser) == SWITCH_STATUS_SUCCESS) {
+ switch_status_t status = SWITCH_STATUS_FALSE;
+
+ /* if no controls, or default controls specified, install default */
+ if (member.conference->caller_controls == NULL || *member.conference->caller_controls == '\0' || strcasecmp(member.conference->caller_controls, "default") == 0) {
+ status = caller_control_build_default(&member);
+ } else if (strcasecmp(member.conference->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(xml_cfg.controls, "group", "name", member.conference->caller_controls);
+#ifdef OPTION_IVR_MENU_SUPPORT
+ status = caller_control_build_custom(&member, xml_controls, xml_cfg.menus);
+#else
+ status = caller_control_build_custom(&member, 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", member.conference->caller_controls);
+ }
+ } else {
+ 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");
+ }
+
+ /* Release the config registry thread lock */
+ if (xml_cfg.cxml) {
+ switch_xml_free(xml_cfg.cxml);
+ memset(&xml_cfg,0,sizeof(xml_cfg));
+ }
+
/* Run the confernece loop */
conference_loop_output(&member);
@@ -3976,11 +3983,6 @@
switch_buffer_destroy(&member.audio_buffer);
switch_buffer_destroy(&member.mux_buffer);
- /* Release the config registry handle */
- if (xml_cfg.cxml) {
- switch_xml_free(xml_cfg.cxml);
- }
-
if (freepool) {
switch_core_destroy_memory_pool(&freepool);
}
@@ -4154,15 +4156,15 @@
/*.chat_interface */ &conference_chat_interface
};
-switch_status_t chat_permissions_get(conference_obj_t *conference)
+switch_status_t chat_permissions_get(conference_obj_t *conference, conf_xml_cfg_t *xml_cfg)
{
- switch_status_t status = SWITCH_STATUS_FALSE;
int count = 0;
assert(conference != NULL);
+ assert(xml_cfg != NULL);
- if (conference->xml_cfg.chat_permissions != NULL && !switch_strlen_zero(conference->chat_permissions)) {
- switch_xml_t profile = switch_xml_find_child(conference->xml_cfg.chat_permissions, "profile", "name", conference->chat_permissions);
+ if (xml_cfg->chat_permissions != NULL && !switch_strlen_zero(conference->chat_permissions)) {
+ switch_xml_t profile = switch_xml_find_child(xml_cfg->chat_permissions, "profile", "name", conference->chat_permissions);
if (profile != NULL) {
switch_xml_t xml_kvp;
@@ -4183,14 +4185,11 @@
count ++;
}
}
- if (count != 0) {
- status = SWITCH_STATUS_SUCCESS;
- }
}
}
}
- return status;
+ return (count != 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE);
}
/* create a new conferene with a specific profile */
@@ -4423,12 +4422,8 @@
conference->rate = rate;
conference->interval = interval;
- /* copy the xml config sections to the new conference */
- memcpy(&conference->xml_cfg,xml_cfg,sizeof(conf_xml_cfg_t));
-
/* build the chat interface permissions map */
- chat_permissions_get(conference);
-
+ chat_permissions_get(conference, xml_cfg);
/* Activate the conference mutex for exclusivity */
switch_mutex_init(&conference->mutex, SWITCH_MUTEX_NESTED, conference->pool);
@@ -4512,7 +4507,7 @@
}
done:
- /* Release the config registry handle */
+ /* Release the config registry thread lock */
if (cxml) {
switch_xml_free(cxml);
cxml = NULL;
1
0
31 Dec '06
Author: anthm
Date: Sun Dec 31 14:54:16 2006
New Revision: 3877
Modified:
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
freeswitch/trunk/src/switch_ivr.c
Log:
fix messed up switch statement
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Sun Dec 31 14:54:16 2006
@@ -4441,19 +4441,30 @@
case nua_r_shutdown:
case nua_r_get_params:
case nua_r_invite:
+ case nua_r_unregister:
+ case nua_r_options:
+ case nua_i_fork:
+ case nua_r_info:
+ case nua_r_bye:
+ case nua_i_bye:
+ case nua_r_unsubscribe:
+ case nua_r_publish:
+ case nua_r_message:
+ case nua_r_notify:
+ case nua_i_notify:
+ case nua_i_cancel:
+ case nua_i_error:
+ case nua_i_active:
+ case nua_i_ack:
+ case nua_i_terminated:
+ case nua_r_set_params:
break;
case nua_r_register:
sip_r_register(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
- case nua_r_unregister:
- break;
- case nua_r_options:
- break;
case nua_i_options:
sip_i_options(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
- case nua_i_fork:
- break;
case nua_i_invite:
if (!session) {
sip_i_invite(nua, profile, nh, sofia_private, sip, tags);
@@ -4470,13 +4481,9 @@
case nua_i_state:
sip_i_state(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
- case nua_r_bye:
- case nua_i_bye:
case nua_i_message:
sip_i_message(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
- case nua_r_info:
- break;
case nua_i_info:
sip_i_info(nua, profile, nh, session, sip, tags);
break;
@@ -4493,28 +4500,14 @@
case nua_i_subscribe:
sip_i_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
- case nua_r_unsubscribe:
- case nua_r_publish:
- case nua_r_message:
- case nua_r_notify:
- case nua_i_notify:
- case nua_i_cancel:
- case nua_i_error:
- case nua_i_active:
- case nua_i_ack:
- case nua_i_terminated:
- case nua_r_set_params:
- break;
-
default:
- if (status > 100)
+ if (status > 100) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: unknown event %d: %03d %s\n",
nua_event_name (event), event, status, phrase);
- else
+ } else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: unknown event %d\n", nua_event_name (event), event);
-
+ }
break;
-
}
done:
Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c (original)
+++ freeswitch/trunk/src/switch_ivr.c Sun Dec 31 14:54:16 2006
@@ -3306,17 +3306,6 @@
switch_event_fire(&event);
}
- if (switch_channel_test_flag(caller_channel, CF_TRANSFER) && !switch_channel_test_flag(peer_channel, CF_TRANSFER)) {
- //switch_channel_hangup(peer_channel, SWITCH_CAUSE_NORMAL_CLEARING);
- //switch_yield(2000000);
- }
-
- if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && switch_channel_test_flag(peer_channel, CF_TRANSFER)) {
- //switch_channel_hangup(caller_channel, SWITCH_CAUSE_NORMAL_CLEARING);
- //switch_yield(2000000);
- }
-
-
this_audio_thread->objs[0] = NULL;
this_audio_thread->objs[1] = NULL;
this_audio_thread->objs[2] = NULL;
1
0
[commit] r3876 - freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference
by Freeswitch SVN 31 Dec '06
by Freeswitch SVN 31 Dec '06
31 Dec '06
Author: knhor
Date: Sun Dec 31 03:20:45 2006
New Revision: 3876
Modified:
freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c
Log:
add simple chat permissions using the following configuration syntax example;
<configuration name="conference.conf" description="Audio Conference">
<profiles>
<profile name="default">
<param name="chat-permissions" value="default"/>
</profile>
</profiles>
<chat-permissions>
<profile name="default">
<!-- both of these users have a functionally equivalent capability set -->
<user name="bob(a)somewhere.com" commands="all"/>
<!-- individually specified commands must be book-end'ed with the | charachter -->
<user name="harry(a)somewhere.com" commands="|deaf|dial|energy|kick|list|lock|mute|norecord|play|record|relate|say|saymember|stop|transfer|undeaf|unlock|unmute|volume_in|volume_out|"/>
</profile>
</chat-permissions>
</configuration>
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 31 03:20:45 2006
@@ -184,6 +184,7 @@
char *profile_name;
char *domain;
char *caller_controls;
+ char *chat_permissions;
uint32_t flags;
switch_call_cause_t bridge_hangup_cause;
switch_mutex_t *flag_mutex;
@@ -199,7 +200,7 @@
int32_t energy_level;
uint8_t min;
conf_xml_cfg_t xml_cfg;
-// switch_hash_t *chat_permissions;
+ switch_hash_t *chat_permissions_map;
} conference_obj_t;
/* Relationship with another member */
@@ -1477,8 +1478,6 @@
xml_menus = switch_xml_child(menu_group, "menus");
xml_menu = (xml_menus != NULL ? switch_xml_find_child(xml_menus, "menu", "name", menu_name) : NULL);
-
-
/* 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));
@@ -3255,7 +3254,7 @@
static api_command_t conf_api_sub_commands[] = {
{"deaf", (api_cmd_fn_t)&conf_api_sub_deaf, CONF_API_SUB_MEMBER_TARGET, "<confname> deaf <[member_id|all]|last>"},
{"dial", (api_cmd_fn_t)&conf_api_sub_dial, CONF_API_SUB_ARGS_SPLIT, "<confname> dial <endpoint_module_name>/<destination> <callerid number> <callerid name> <flags>"},
- {"energy", (api_cmd_fn_t)&conf_api_sub_energy, CONF_API_SUB_MEMBER_TARGET, "<confname> energy <member_id|all|last> [<newval>]"},
+ {"energy", (api_cmd_fn_t)&conf_api_sub_energy, CONF_API_SUB_MEMBER_TARGET, "<confname> energy <member_id|all|last> [<newval>]"},
{"kick", (api_cmd_fn_t)&conf_api_sub_kick, CONF_API_SUB_MEMBER_TARGET, "<confname> kick <[member_id|all|last]>"},
{"list", (api_cmd_fn_t)&conf_api_sub_list, CONF_API_SUB_ARGS_SPLIT, "<confname> list [delim <string>]"},
{"lock", (api_cmd_fn_t)&conf_api_sub_lock, CONF_API_SUB_ARGS_SPLIT, "<confname> lock"},
@@ -3627,7 +3626,7 @@
#ifdef OPTION_IVR_MENU_SUPPORT
xml_cfg->menus = switch_xml_child(cfg, "menus");
#endif
- xml_cfg->chat_permissions = switch_xml_child(cfg, "chat-permisions");
+ xml_cfg->chat_permissions = switch_xml_child(cfg, "chat-permissions");
status = SWITCH_STATUS_SUCCESS;
}
}
@@ -4093,12 +4092,15 @@
if (body != NULL && (lbuf = strdup(body))) {
int argc;
char *argv[25];
+ char *perm = NULL;
memset(argv, 0, sizeof(argv));
argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
/* try to find a command to execute */
if (argc) {
+ char *cmd = switch_mprintf("|%s|",argv[0]);
+
/* special case list */
if (strcasecmp(argv[0], "list") == 0) {
stream.write_function(&stream, "(%u member%s, %s)\n",
@@ -4108,12 +4110,16 @@
);
conference_list_pretty(conference, &stream);
#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);
+ } else if (conference->chat_permissions != NULL
+ && (perm = (char *) switch_core_hash_find(conference->chat_permissions_map, from)) != NULL
+ && (strcasecmp(perm,"all") == 0 || (cmd != NULL && strstr(perm,cmd) != NULL))) {
+ /* provide help */
+ 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);
+ }
#endif
}
} else {
@@ -4148,6 +4154,45 @@
/*.chat_interface */ &conference_chat_interface
};
+switch_status_t chat_permissions_get(conference_obj_t *conference)
+{
+ switch_status_t status = SWITCH_STATUS_FALSE;
+ int count = 0;
+
+ assert(conference != NULL);
+
+ if (conference->xml_cfg.chat_permissions != NULL && !switch_strlen_zero(conference->chat_permissions)) {
+ switch_xml_t profile = switch_xml_find_child(conference->xml_cfg.chat_permissions, "profile", "name", conference->chat_permissions);
+
+ if (profile != NULL) {
+ switch_xml_t xml_kvp;
+
+ if (conference->chat_permissions_map != NULL) {
+ switch_core_hash_destroy(conference->chat_permissions_map);
+ }
+ switch_core_hash_init(&conference->chat_permissions_map, conference->pool);
+
+ if (conference->chat_permissions_map != NULL) {
+ for (xml_kvp = switch_xml_child(profile, "user"); xml_kvp; xml_kvp = xml_kvp->next) {
+ char *name = (char *) switch_xml_attr(xml_kvp, "name");
+ char *commands = (char *) switch_xml_attr(xml_kvp, "commands");
+
+ if (!switch_strlen_zero(name) && !switch_strlen_zero(commands)) {
+ switch_core_hash_insert(conference->chat_permissions_map, name, commands);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "chat-permissions %s=%s\n",name,commands);
+ count ++;
+ }
+ }
+ if (count != 0) {
+ status = SWITCH_STATUS_SUCCESS;
+ }
+ }
+ }
+ }
+
+ return status;
+}
+
/* create a new conferene with a specific profile */
static conference_obj_t *conference_new(char *name, conf_xml_cfg_t *xml_cfg, switch_memory_pool_t *pool)
{
@@ -4175,6 +4220,7 @@
char *caller_id_name = NULL;
char *caller_id_number = NULL;
char *caller_controls = NULL;
+ char *chat_permissions = NULL;
uint32_t rate = 8000, interval = 20;
switch_status_t status;
@@ -4245,6 +4291,8 @@
caller_id_number = val;
} else if (!strcasecmp(var, "caller-controls")) {
caller_controls = val;
+ } else if (!strcasecmp(var, "chat-permissions")) {
+ chat_permissions = val;
}
}
@@ -4362,6 +4410,10 @@
conference->caller_controls = switch_core_strdup(conference->pool, caller_controls);
}
+ if (!switch_strlen_zero(chat_permissions)) {
+ conference->chat_permissions = switch_core_strdup(conference->pool, chat_permissions);
+ }
+
conference->name = switch_core_strdup(conference->pool, name);
if (domain) {
conference->domain = switch_core_strdup(conference->pool, domain);
@@ -4374,6 +4426,10 @@
/* copy the xml config sections to the new conference */
memcpy(&conference->xml_cfg,xml_cfg,sizeof(conf_xml_cfg_t));
+ /* build the chat interface permissions map */
+ chat_permissions_get(conference);
+
+
/* Activate the conference mutex for exclusivity */
switch_mutex_init(&conference->mutex, SWITCH_MUTEX_NESTED, conference->pool);
switch_mutex_init(&conference->member_mutex, SWITCH_MUTEX_NESTED, conference->pool);
1
0
[commit] r3875 - freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference
by Freeswitch SVN 30 Dec '06
by Freeswitch SVN 30 Dec '06
30 Dec '06
Author: knhor
Date: Sat Dec 30 18:58:06 2006
New Revision: 3875
Modified:
freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c
Log:
add flags paramenter back to dial api command.
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 Sat Dec 30 18:58:06 2006
@@ -3109,7 +3109,7 @@
assert(stream != NULL);
if (argc >= 1) {
- conference_outcall(conference, NULL, argv[0], 60, NULL, (argc >= 3 ?argv[2] : NULL), (argc >=2 ? argv[1] : NULL));
+ conference_outcall(conference, NULL, argv[0], 60, (argc >= 4 ? argv[3] : NULL), (argc >= 3 ? argv[2] : NULL), (argc >=2 ? argv[1] : NULL));
stream->write_function(stream, "OK\n");
} else {
ret_status = SWITCH_STATUS_GENERR;
@@ -3253,26 +3253,26 @@
/* API Interface Function sub-commands */
static api_command_t conf_api_sub_commands[] = {
- {"deaf", (api_cmd_fn_t)&conf_api_sub_deaf, CONF_API_SUB_MEMBER_TARGET, "<confname> deaf <[member_id|all]|last>"},
- {"dial", (api_cmd_fn_t)&conf_api_sub_dial, CONF_API_SUB_ARGS_SPLIT, "<confname> dial <endpoint_module_name>/<destination> <callerid number> <callerid name>"},
- {"energy", (api_cmd_fn_t)&conf_api_sub_energy, CONF_API_SUB_MEMBER_TARGET, "<confname> energy <member_id|all|last> [<newval>]"},
- {"kick", (api_cmd_fn_t)&conf_api_sub_kick, CONF_API_SUB_MEMBER_TARGET, "<confname> kick <[member_id|all|last]>"},
- {"list", (api_cmd_fn_t)&conf_api_sub_list, CONF_API_SUB_ARGS_SPLIT, "<confname> list [delim <string>]"},
- {"lock", (api_cmd_fn_t)&conf_api_sub_lock, CONF_API_SUB_ARGS_SPLIT, "<confname> lock"},
- {"mute", (api_cmd_fn_t)&conf_api_sub_mute, CONF_API_SUB_MEMBER_TARGET, "<confname> mute <[member_id|all]|last>"},
- {"norecord", (api_cmd_fn_t)&conf_api_sub_norecord, CONF_API_SUB_ARGS_SPLIT, "<confname> norecord <[filename|all]>"},
- {"play", (api_cmd_fn_t)&conf_api_sub_play, CONF_API_SUB_ARGS_SPLIT, "<confname> play <file_path> [<member_id>]"},
- {"record", (api_cmd_fn_t)&conf_api_sub_record, CONF_API_SUB_ARGS_SPLIT, "<confname> record <filename>"},
- {"relate", (api_cmd_fn_t)&conf_api_sub_relate, CONF_API_SUB_ARGS_SPLIT, "<confname> relate <member_id> <other_member_id> [nospeak|nohear|clear]"},
- {"say", (api_cmd_fn_t)&conf_api_sub_say, CONF_API_SUB_ARGS_AS_ONE, "<confname> say <text>"},
- {"saymember", (api_cmd_fn_t)&conf_api_sub_saymember, CONF_API_SUB_ARGS_AS_ONE, "<confname> saymember <member_id> <text>"},
- {"stop", (api_cmd_fn_t)&conf_api_sub_stop, CONF_API_SUB_MEMBER_TARGET, "<confname> stop <[current|all|last]> [<member_id>]"},
- {"transfer", (api_cmd_fn_t)&conf_api_sub_transfer, CONF_API_SUB_ARGS_SPLIT, "<confname> transfer <conference_name> <member id> [...<member id>]"},
- {"undeaf", (api_cmd_fn_t)&conf_api_sub_undeaf, CONF_API_SUB_MEMBER_TARGET, "<confname> undeaf <[member_id|all]|last>"},
- {"unlock", (api_cmd_fn_t)&conf_api_sub_unlock, CONF_API_SUB_ARGS_SPLIT, "<confname> unlock"},
- {"unmute", (api_cmd_fn_t)&conf_api_sub_unmute, CONF_API_SUB_MEMBER_TARGET, "<confname> unmute <[member_id|all]|last>"},
- {"volume_in", (api_cmd_fn_t)&conf_api_sub_volume_in, CONF_API_SUB_MEMBER_TARGET, "<confname> volume_in <member_id|all|last> [<newval>]"},
- {"volume_out", (api_cmd_fn_t)&conf_api_sub_volume_out, CONF_API_SUB_MEMBER_TARGET, "<confname> volume_out <member_id|all|last> [<newval>]"},
+ {"deaf", (api_cmd_fn_t)&conf_api_sub_deaf, CONF_API_SUB_MEMBER_TARGET, "<confname> deaf <[member_id|all]|last>"},
+ {"dial", (api_cmd_fn_t)&conf_api_sub_dial, CONF_API_SUB_ARGS_SPLIT, "<confname> dial <endpoint_module_name>/<destination> <callerid number> <callerid name> <flags>"},
+ {"energy", (api_cmd_fn_t)&conf_api_sub_energy, CONF_API_SUB_MEMBER_TARGET, "<confname> energy <member_id|all|last> [<newval>]"},
+ {"kick", (api_cmd_fn_t)&conf_api_sub_kick, CONF_API_SUB_MEMBER_TARGET, "<confname> kick <[member_id|all|last]>"},
+ {"list", (api_cmd_fn_t)&conf_api_sub_list, CONF_API_SUB_ARGS_SPLIT, "<confname> list [delim <string>]"},
+ {"lock", (api_cmd_fn_t)&conf_api_sub_lock, CONF_API_SUB_ARGS_SPLIT, "<confname> lock"},
+ {"mute", (api_cmd_fn_t)&conf_api_sub_mute, CONF_API_SUB_MEMBER_TARGET, "<confname> mute <[member_id|all]|last>"},
+ {"norecord", (api_cmd_fn_t)&conf_api_sub_norecord, CONF_API_SUB_ARGS_SPLIT, "<confname> norecord <[filename|all]>"},
+ {"play", (api_cmd_fn_t)&conf_api_sub_play, CONF_API_SUB_ARGS_SPLIT, "<confname> play <file_path> [<member_id>]"},
+ {"record", (api_cmd_fn_t)&conf_api_sub_record, CONF_API_SUB_ARGS_SPLIT, "<confname> record <filename>"},
+ {"relate", (api_cmd_fn_t)&conf_api_sub_relate, CONF_API_SUB_ARGS_SPLIT, "<confname> relate <member_id> <other_member_id> [nospeak|nohear|clear]"},
+ {"say", (api_cmd_fn_t)&conf_api_sub_say, CONF_API_SUB_ARGS_AS_ONE, "<confname> say <text>"},
+ {"saymember", (api_cmd_fn_t)&conf_api_sub_saymember, CONF_API_SUB_ARGS_AS_ONE, "<confname> saymember <member_id> <text>"},
+ {"stop", (api_cmd_fn_t)&conf_api_sub_stop, CONF_API_SUB_MEMBER_TARGET, "<confname> stop <[current|all|last]> [<member_id>]"},
+ {"transfer", (api_cmd_fn_t)&conf_api_sub_transfer, CONF_API_SUB_ARGS_SPLIT, "<confname> transfer <conference_name> <member id> [...<member id>]"},
+ {"undeaf", (api_cmd_fn_t)&conf_api_sub_undeaf, CONF_API_SUB_MEMBER_TARGET, "<confname> undeaf <[member_id|all]|last>"},
+ {"unlock", (api_cmd_fn_t)&conf_api_sub_unlock, CONF_API_SUB_ARGS_SPLIT, "<confname> unlock"},
+ {"unmute", (api_cmd_fn_t)&conf_api_sub_unmute, CONF_API_SUB_MEMBER_TARGET, "<confname> unmute <[member_id|all]|last>"},
+ {"volume_in", (api_cmd_fn_t)&conf_api_sub_volume_in, CONF_API_SUB_MEMBER_TARGET, "<confname> volume_in <member_id|all|last> [<newval>]"},
+ {"volume_out", (api_cmd_fn_t)&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]))
1
0
[commit] r3874 - freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference
by Freeswitch SVN 30 Dec '06
by Freeswitch SVN 30 Dec '06
30 Dec '06
Author: knhor
Date: Sat Dec 30 16:52:09 2006
New Revision: 3874
Modified:
freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c
Log:
fix void function pointer for mikej
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 Sat Dec 30 16:52:09 2006
@@ -158,7 +158,7 @@
#ifdef OPTION_IVR_MENU_SUPPORT
switch_xml_t menus;
#endif
-// switch_xml_t chat_admin;
+ switch_xml_t chat_permissions;
} conf_xml_cfg_t;
/* Conference Object */
@@ -199,8 +199,7 @@
int32_t energy_level;
uint8_t min;
conf_xml_cfg_t xml_cfg;
-// switch_hash_t *chat_admin;
-// switch_hash_t *chat_id;
+// switch_hash_t *chat_permissions;
} conference_obj_t;
/* Relationship with another member */
@@ -258,10 +257,12 @@
CONF_API_SUB_ARGS_AS_ONE
} conference_fntype_t;
+typedef void (*api_cmd_fn_t)(void *);
+
/* API command parser */
typedef struct api_command {
char *pname;
- void *pfnapicmd;
+ api_cmd_fn_t pfnapicmd;
conference_fntype_t fntype;
char *psyntax;
} api_command_t;
@@ -1373,13 +1374,13 @@
{"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 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 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 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 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},
#ifdef OPTION_IVR_MENU_SUPPORT
@@ -3252,26 +3253,26 @@
/* API Interface Function sub-commands */
static api_command_t conf_api_sub_commands[] = {
- {"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>]"},
+ {"deaf", (api_cmd_fn_t)&conf_api_sub_deaf, CONF_API_SUB_MEMBER_TARGET, "<confname> deaf <[member_id|all]|last>"},
+ {"dial", (api_cmd_fn_t)&conf_api_sub_dial, CONF_API_SUB_ARGS_SPLIT, "<confname> dial <endpoint_module_name>/<destination> <callerid number> <callerid name>"},
+ {"energy", (api_cmd_fn_t)&conf_api_sub_energy, CONF_API_SUB_MEMBER_TARGET, "<confname> energy <member_id|all|last> [<newval>]"},
+ {"kick", (api_cmd_fn_t)&conf_api_sub_kick, CONF_API_SUB_MEMBER_TARGET, "<confname> kick <[member_id|all|last]>"},
+ {"list", (api_cmd_fn_t)&conf_api_sub_list, CONF_API_SUB_ARGS_SPLIT, "<confname> list [delim <string>]"},
+ {"lock", (api_cmd_fn_t)&conf_api_sub_lock, CONF_API_SUB_ARGS_SPLIT, "<confname> lock"},
+ {"mute", (api_cmd_fn_t)&conf_api_sub_mute, CONF_API_SUB_MEMBER_TARGET, "<confname> mute <[member_id|all]|last>"},
+ {"norecord", (api_cmd_fn_t)&conf_api_sub_norecord, CONF_API_SUB_ARGS_SPLIT, "<confname> norecord <[filename|all]>"},
+ {"play", (api_cmd_fn_t)&conf_api_sub_play, CONF_API_SUB_ARGS_SPLIT, "<confname> play <file_path> [<member_id>]"},
+ {"record", (api_cmd_fn_t)&conf_api_sub_record, CONF_API_SUB_ARGS_SPLIT, "<confname> record <filename>"},
+ {"relate", (api_cmd_fn_t)&conf_api_sub_relate, CONF_API_SUB_ARGS_SPLIT, "<confname> relate <member_id> <other_member_id> [nospeak|nohear|clear]"},
+ {"say", (api_cmd_fn_t)&conf_api_sub_say, CONF_API_SUB_ARGS_AS_ONE, "<confname> say <text>"},
+ {"saymember", (api_cmd_fn_t)&conf_api_sub_saymember, CONF_API_SUB_ARGS_AS_ONE, "<confname> saymember <member_id> <text>"},
+ {"stop", (api_cmd_fn_t)&conf_api_sub_stop, CONF_API_SUB_MEMBER_TARGET, "<confname> stop <[current|all|last]> [<member_id>]"},
+ {"transfer", (api_cmd_fn_t)&conf_api_sub_transfer, CONF_API_SUB_ARGS_SPLIT, "<confname> transfer <conference_name> <member id> [...<member id>]"},
+ {"undeaf", (api_cmd_fn_t)&conf_api_sub_undeaf, CONF_API_SUB_MEMBER_TARGET, "<confname> undeaf <[member_id|all]|last>"},
+ {"unlock", (api_cmd_fn_t)&conf_api_sub_unlock, CONF_API_SUB_ARGS_SPLIT, "<confname> unlock"},
+ {"unmute", (api_cmd_fn_t)&conf_api_sub_unmute, CONF_API_SUB_MEMBER_TARGET, "<confname> unmute <[member_id|all]|last>"},
+ {"volume_in", (api_cmd_fn_t)&conf_api_sub_volume_in, CONF_API_SUB_MEMBER_TARGET, "<confname> volume_in <member_id|all|last> [<newval>]"},
+ {"volume_out", (api_cmd_fn_t)&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]))
@@ -3308,7 +3309,7 @@
int last = ( id == 0 && strcasecmp(argv[1], "last") == 0 );
if (all) {
- conference_member_itterator(conference, stream, conf_api_sub_commands[i].pfnapicmd, argv[2]);
+ conference_member_itterator(conference, stream, (conf_api_member_cmd_t)conf_api_sub_commands[i].pfnapicmd, argv[2]);
} else if (last) {
conference_member_t *member = NULL;
conference_member_t *last_member = NULL;
@@ -3626,7 +3627,7 @@
#ifdef OPTION_IVR_MENU_SUPPORT
xml_cfg->menus = switch_xml_child(cfg, "menus");
#endif
-// xml_cfg->chat_admin = switch_xml_child(cfg, "chat-admin");
+ xml_cfg->chat_permissions = switch_xml_child(cfg, "chat-permisions");
status = SWITCH_STATUS_SUCCESS;
}
}
1
0
[commit] r3873 - freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference
by Freeswitch SVN 30 Dec '06
by Freeswitch SVN 30 Dec '06
30 Dec '06
Author: knhor
Date: Sat Dec 30 15:04:41 2006
New Revision: 3873
Modified:
freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c
Log:
move caller control digit parser from the conference to the caller
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 Sat Dec 30 15:04:41 2006
@@ -55,7 +55,7 @@
//#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
+#define ENABLE_CHAT_ADMIN
typedef enum {
FILE_STOP_CURRENT,
@@ -178,12 +178,12 @@
char *kicked_sound;
char *caller_id_name;
char *caller_id_number;
- switch_ivr_digit_stream_parser_t *dtmf_parser;
char *pin;
char *pin_sound;
char *bad_pin_sound;
char *profile_name;
char *domain;
+ char *caller_controls;
uint32_t flags;
switch_call_cause_t bridge_hangup_cause;
switch_mutex_t *flag_mutex;
@@ -198,6 +198,7 @@
uint32_t count;
int32_t energy_level;
uint8_t min;
+ conf_xml_cfg_t xml_cfg;
// switch_hash_t *chat_admin;
// switch_hash_t *chat_id;
} conference_obj_t;
@@ -239,6 +240,7 @@
switch_audio_resampler_t *read_resampler;
conference_file_node_t *fnode;
conference_relationship_t *relationships;
+ switch_ivr_digit_stream_parser_t *dtmf_parser;
switch_ivr_digit_stream_t *digit_stream;
struct conference_member *next;
};
@@ -295,7 +297,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, conf_xml_cfg_t cfg, switch_memory_pool_t *pool);
+static conference_obj_t *conference_new(char *name, conf_xml_cfg_t *xml_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);
@@ -885,8 +887,6 @@
switch_thread_rwlock_unlock(conference->rwlock);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write Lock OFF\n");
- switch_ivr_digit_stream_parser_destroy(conference->dtmf_parser);
-
if (conference->pool) {
switch_memory_pool_t *pool = conference->pool;
switch_core_destroy_memory_pool(&pool);
@@ -1389,6 +1389,256 @@
};
#define CCFNTBL_QTY (sizeof(ccfntbl)/sizeof(ccfntbl[0]))
+#ifdef OPTION_IVR_MENU_SUPPORT
+static switch_ivr_action_t caller_control_ivr_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 (!switch_strlen_zero(param)) {
+ if (obj != NULL) {
+ int i, found;
+ char *action_name = strdup(param);
+
+ 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);
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unable to invoke caller control menu action '%s', NULL member!\n", param);
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NULL or empty param!\n");
+ }
+
+ return action;
+}
+
+/*
+ static switch_status_t ivr_menu_callback_play_file(char *file, uint32_t leadin, void *member)
+ {
+ switch_status_t status;
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ivr_menu_callback_play_file\n");
+ status = conference_member_play_file((conference_member_t *)member, file, leadin);
+ if (status != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ivr_menu_callback_play_file ERROR\n");
+ }
+
+ return status;
+ }
+
+ static switch_status_t ivr_menu_callback_say(char *file, uint32_t leadin, void *member)
+ {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ivr_menu_callback_say\n");
+ return conference_member_say((conference_member_t *)member, file, leadin);
+ }
+*/
+
+static switch_status_t caller_control_ivr_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;
+ switch_xml_t xml_menus;
+ switch_xml_t xml_menu;
+
+ assert(conference != NULL);
+ assert(ctx != NULL);
+ assert(menu_group != NULL);
+ assert(menu_name != NULL);
+ assert(xml_menus != NULL);
+
+ xml_menus = switch_xml_child(menu_group, "menus");
+ xml_menu = (xml_menus != NULL ? switch_xml_find_child(xml_menus, "menu", "name", menu_name) : NULL);
+
+
+
+ /* 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));
+
+ 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", &caller_control_ivr_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");
+
+ /*
+ // instruct ivr menu to use our file play and tts routines
+ status = switch_ivr_menu_set_fileplay_callback((*ctx)->menu_stack, &ivr_menu_callback_play_file);
+ if (status != SWITCH_STATUS_SUCCESS)
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to set file play calback\n");
+ status = switch_ivr_menu_set_tts_callback((*ctx)->menu_stack, &ivr_menu_callback_say);
+ if (status != SWITCH_STATUS_SUCCESS)
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to set tts calback\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);
+ }
+
+ return status;
+}
+#endif
+
+static switch_status_t caller_control_build_default(conference_member_t *member)
+{
+ switch_status_t status = SWITCH_STATUS_FALSE;
+ uint32_t i;
+ caller_control_action_t *action;
+
+ assert(member != NULL);
+
+ for(i = 0, status = SWITCH_STATUS_SUCCESS; status == SWITCH_STATUS_SUCCESS && i<CCFNTBL_QTY; i++) {
+ 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(member->pool, sizeof(caller_control_action_t));
+ if (action != NULL) {
+ action->fndesc = &ccfntbl[i];
+ action->data = NULL;
+ status = switch_ivr_digit_stream_parser_set_event(member->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;
+ }
+ }
+ }
+
+
+ return status;
+}
+
+static switch_status_t caller_control_build_custom(conference_member_t *member, switch_xml_t xml_controls, switch_xml_t xml_menus)
+{
+ switch_status_t status = SWITCH_STATUS_FALSE;
+ switch_xml_t xml_kvp;
+
+ assert(member != NULL);
+ assert(xml_controls != NULL);
+
+ /* 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");
+ char *data = (char *)switch_xml_attr_soft(xml_kvp, "data");
+
+ if (!switch_strlen_zero(key) && !switch_strlen_zero(val)) {
+ uint32_t i;
+
+ /* 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++) {
+
+ if (strcasecmp(ccfntbl[i].key, key) == 0) {
+ status = SWITCH_STATUS_SUCCESS;
+#ifdef OPTION_IVR_MENU_SUPPORT
+ 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);
+
+ /* 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 = caller_control_ivr_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
+
+ 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(member->pool, sizeof(caller_control_action_t));
+ if (action != NULL) {
+ action->fndesc = &ccfntbl[i];
+ action->data = (void *)data;
+ status = switch_ivr_digit_stream_parser_set_event(member->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;
+ }
+ }
+ }
+ }
+ 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);
+ }
+ }
+
+ return status;
+}
+
/* marshall frames from the conference (or file or tts output) to the call leg */
/* NB. this starts the input thread after some initial setup for the call leg */
static void conference_loop_output(conference_member_t *member)
@@ -1429,8 +1679,33 @@
/* Start the input thread */
launch_conference_loop_input(member, switch_core_session_get_pool(member->session));
+ /* caller control configuration chores */
+ if (switch_ivr_digit_stream_parser_new(member->pool, &member->dtmf_parser) == SWITCH_STATUS_SUCCESS) {
+ switch_status_t status = SWITCH_STATUS_FALSE;
+
+ /* if no controls, or default controls specified, install default */
+ if (member->conference->caller_controls == NULL || *member->conference->caller_controls == '\0' || strcasecmp(member->conference->caller_controls, "default") == 0) {
+ status = caller_control_build_default(member);
+ } else if (strcasecmp(member->conference->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(member->conference->xml_cfg.controls, "group", "name", member->conference->caller_controls);
+#ifdef OPTION_IVR_MENU_SUPPORT
+ status = caller_control_build_custom(member, xml_controls, member->conference->xml_cfg.menus);
+#else
+ status = caller_control_build_custom(member, 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", member->conference->caller_controls);
+ }
+ } else {
+ 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");
+ }
+
/* build a digit stream object */
- if (member->conference->dtmf_parser != NULL && switch_ivr_digit_stream_new(member->conference->dtmf_parser, &member->digit_stream) != SWITCH_STATUS_SUCCESS) {
+ if (member->dtmf_parser != NULL && switch_ivr_digit_stream_new(member->dtmf_parser, &member->digit_stream) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Warning Will Robinson, there is no digit parser stream object\n");
}
@@ -1482,15 +1757,15 @@
if (switch_channel_has_dtmf(channel)) {
switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
- if (member->conference->dtmf_parser != NULL) {
+ if (member->dtmf_parser != NULL) {
for (digit = dtmf; *digit && caller_action == NULL; digit++) {
- caller_action = (caller_control_action_t *)switch_ivr_digit_stream_parser_feed(member->conference->dtmf_parser, member->digit_stream, *digit);
+ caller_action = (caller_control_action_t *)switch_ivr_digit_stream_parser_feed(member->dtmf_parser, member->digit_stream, *digit);
}
}
/* otherwise, clock the parser so that it can handle digit timeout detection */
- } else if (member->conference->dtmf_parser != NULL) {
- caller_action = (caller_control_action_t *)switch_ivr_digit_stream_parser_feed(member->conference->dtmf_parser, member->digit_stream, '\0');
+ } else if (member->dtmf_parser != NULL) {
+ caller_action = (caller_control_action_t *)switch_ivr_digit_stream_parser_feed(member->dtmf_parser, member->digit_stream, '\0');
}
/* if a caller action has been detected, handle it */
@@ -1618,6 +1893,10 @@
switch_ivr_digit_stream_destroy(member->digit_stream);
}
+ if (member->dtmf_parser != NULL) {
+ switch_ivr_digit_stream_parser_destroy(member->dtmf_parser);
+ }
+
switch_clear_flag_locked(member, MFLAG_RUNNING);
switch_core_timer_destroy(&timer);
@@ -2888,18 +3167,17 @@
}
/* 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);
- }
+ new_conference = conference_new(conf_name, &xml_cfg, pool);
if (!new_conference) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
if (pool != NULL) {
switch_core_destroy_memory_pool(&pool);
}
+ /* Release the config registry handle */
+ if (xml_cfg.cxml) {
+ switch_xml_free(xml_cfg.cxml);
+ }
goto done;
}
@@ -3454,7 +3732,7 @@
}
/* Create the conference object. */
- conference = conference_new(conf_name, xml_cfg, pool);
+ conference = conference_new(conf_name, &xml_cfg, pool);
if (!conference) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
@@ -3481,7 +3759,7 @@
freepool = pool;
/* couldn't find the conference, create one */
} else {
- conference = conference_new(conf_name, xml_cfg, pool);
+ conference = conference_new(conf_name, &xml_cfg, pool);
if (!conference) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
@@ -3568,12 +3846,6 @@
}
}
- /* Release the config registry handle */
- 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 */
if (!switch_strlen_zero(bridgeto) && strcasecmp(bridgeto, "none")) {
if (conference_outcall(conference, session, bridgeto, 60, NULL, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
@@ -3875,258 +4147,8 @@
/*.chat_interface */ &conference_chat_interface
};
-#ifdef OPTION_IVR_MENU_SUPPORT
-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 (!switch_strlen_zero(param)) {
- if (obj != NULL) {
- int i, found;
- char *action_name = strdup(param);
-
- 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);
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unable to invoke caller control menu action '%s', NULL member!\n", param);
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NULL or empty param!\n");
- }
-
- return action;
-}
-
-/*
- static switch_status_t ivr_menu_callback_play_file(char *file, uint32_t leadin, void *member)
- {
- switch_status_t status;
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ivr_menu_callback_play_file\n");
- status = conference_member_play_file((conference_member_t *)member, file, leadin);
- if (status != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ivr_menu_callback_play_file ERROR\n");
- }
-
- return status;
- }
-
- static switch_status_t ivr_menu_callback_say(char *file, uint32_t leadin, void *member)
- {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ivr_menu_callback_say\n");
- return conference_member_say((conference_member_t *)member, file, leadin);
- }
-*/
-
-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;
- switch_xml_t xml_menus;
- switch_xml_t xml_menu;
-
- assert(conference != NULL);
- assert(ctx != NULL);
- assert(menu_group != NULL);
- assert(menu_name != NULL);
- assert(xml_menus != NULL);
-
- xml_menus = switch_xml_child(menu_group, "menus");
- xml_menu = (xml_menus != NULL ? switch_xml_find_child(xml_menus, "menu", "name", menu_name) : NULL);
-
-
-
- /* 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));
-
- 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");
-
- /*
- // instruct ivr menu to use our file play and tts routines
- status = switch_ivr_menu_set_fileplay_callback((*ctx)->menu_stack, &ivr_menu_callback_play_file);
- if (status != SWITCH_STATUS_SUCCESS)
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to set file play calback\n");
- status = switch_ivr_menu_set_tts_callback((*ctx)->menu_stack, &ivr_menu_callback_say);
- if (status != SWITCH_STATUS_SUCCESS)
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to set tts calback\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);
- }
-
- return status;
-}
-#endif
-
-static switch_status_t conf_default_controls(conference_obj_t *conference)
-{
- switch_status_t status = SWITCH_STATUS_FALSE;
- uint32_t i;
- caller_control_action_t *action;
-
- assert(conference != NULL);
-
- for(i = 0, status = SWITCH_STATUS_SUCCESS; status == SWITCH_STATUS_SUCCESS && i<CCFNTBL_QTY; i++) {
- 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->fndesc = &ccfntbl[i];
- 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;
- }
- }
- }
-
-
- return status;
-}
-
-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;
- switch_xml_t xml_kvp;
-
- assert(conference != NULL);
- assert(xml_controls != NULL);
-
- /* 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");
- char *data = (char *)switch_xml_attr_soft(xml_kvp, "data");
-
- if (!switch_strlen_zero(key) && !switch_strlen_zero(val)) {
- uint32_t i;
-
- /* 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++) {
-
- if (strcasecmp(ccfntbl[i].key, key) == 0) {
- status = SWITCH_STATUS_SUCCESS;
-#ifdef OPTION_IVR_MENU_SUPPORT
- 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);
-
- /* 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
-
- 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->fndesc = &ccfntbl[i];
- 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;
- }
- }
- }
- }
- 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);
- }
- }
-
- return status;
-}
-
/* create a new conferene with a specific profile */
-static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_memory_pool_t *pool)
+static conference_obj_t *conference_new(char *name, conf_xml_cfg_t *xml_cfg, switch_memory_pool_t *pool)
{
conference_obj_t *conference;
switch_xml_t xml_kvp;
@@ -4162,7 +4184,7 @@
}
/* parse the profile tree for param values */
- for (xml_kvp = switch_xml_child(cfg.profile, "param"); xml_kvp; xml_kvp = xml_kvp->next) {
+ for (xml_kvp = switch_xml_child(xml_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] = "";
@@ -4335,6 +4357,10 @@
conference->energy_level = atoi(energy_level);
}
+ if (!switch_strlen_zero(caller_controls)) {
+ conference->caller_controls = switch_core_strdup(conference->pool, caller_controls);
+ }
+
conference->name = switch_core_strdup(conference->pool, name);
if (domain) {
conference->domain = switch_core_strdup(conference->pool, domain);
@@ -4343,31 +4369,9 @@
}
conference->rate = rate;
conference->interval = interval;
- conference->dtmf_parser = NULL;
-
- /* caller control configuration chores */
- if (switch_ivr_digit_stream_parser_new(conference->pool, &conference->dtmf_parser) == SWITCH_STATUS_SUCCESS) {
- /* if no controls, or default controls specified, install default */
- if (caller_controls == NULL || *caller_controls == '\0' || strcasecmp(caller_controls, "default") == 0) {
- status = conf_default_controls(conference);
- } 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_INFO, "no caller controls intalled.\n");
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to allocate caller control digit parser.\n");
- }
+ /* copy the xml config sections to the new conference */
+ memcpy(&conference->xml_cfg,xml_cfg,sizeof(conf_xml_cfg_t));
/* Activate the conference mutex for exclusivity */
switch_mutex_init(&conference->mutex, SWITCH_MUTEX_NESTED, conference->pool);
1
0
Author: anthm
Date: Sat Dec 30 12:22:17 2006
New Revision: 3872
Modified:
freeswitch/trunk/src/mod/endpoints/mod_iax/mod_iax.c
Log:
add break to iax
Modified: freeswitch/trunk/src/mod/endpoints/mod_iax/mod_iax.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_iax/mod_iax.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_iax/mod_iax.c Sat Dec 30 12:22:17 2006
@@ -56,7 +56,8 @@
TFLAG_VOICE = (1 << 4),
TFLAG_HANGUP = (1 << 5),
TFLAG_LINEAR = (1 << 6),
- TFLAG_CODEC = (1 << 7)
+ TFLAG_CODEC = (1 << 7),
+ TFLAG_BREAK = (1 << 8)
} TFLAGS;
typedef enum {
@@ -573,6 +574,9 @@
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
//switch_thread_cond_signal(tech_pvt->cond);
break;
+ case SWITCH_SIG_BREAK:
+ switch_set_flag_locked(tech_pvt, TFLAG_BREAK);
+ break;
default:
break;
}
@@ -644,10 +648,19 @@
tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
-
-
+ tech_pvt->read_frame.flags = SFF_NONE;
+
while (switch_test_flag(tech_pvt, TFLAG_IO)) {
//switch_thread_cond_wait(tech_pvt->cond, tech_pvt->mutex);
+ if (switch_test_flag_locked(tech_pvt, TFLAG_BREAK)) {
+ switch_clear_flag(tech_pvt, TFLAG_BREAK);
+ tech_pvt->read_frame.datalen = 13;
+ memset(tech_pvt->read_frame.data, 0, 13);
+ tech_pvt->read_frame.flags = SFF_CNG;
+ *frame = &tech_pvt->read_frame;
+ return SWITCH_STATUS_SUCCESS;
+ }
+
if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
return SWITCH_STATUS_FALSE;
}
1
0
29 Dec '06
Author: anthm
Date: Fri Dec 29 15:42:16 2006
New Revision: 3871
Modified:
freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
Log:
add system to js
Modified: freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c (original)
+++ freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c Fri Dec 29 15:42:16 2006
@@ -2239,6 +2239,22 @@
return JS_TRUE;
}
+/* Replace this with more robust version later */
+static JSBool js_system(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+ char *cmd;
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+
+ if (argc > 0 && (cmd = JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) {
+ *rval = INT_TO_JSVAL( system(cmd) );
+ return JS_TRUE;
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Arguements\n");
+ return JS_FALSE;
+}
+
+
static JSBool js_file_unlink(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
const char *path;
@@ -2261,6 +2277,7 @@
{"apiExecute", js_api_execute, 2},
{"use", js_api_use, 1},
{"fileDelete", js_file_unlink, 1},
+ {"system", js_system, 1},
#ifdef HAVE_CURL
{"fetchURLHash", js_fetchurl_hash, 1},
{"fetchURLFile", js_fetchurl_file, 1},
1
0
[commit] r3870 - in freeswitch/trunk/src: . include mod/endpoints/mod_sofia
by Freeswitch SVN 29 Dec '06
by Freeswitch SVN 29 Dec '06
29 Dec '06
Author: anthm
Date: Fri Dec 29 11:39:56 2006
New Revision: 3870
Modified:
freeswitch/trunk/src/include/switch_core.h
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
freeswitch/trunk/src/switch_core.c
Log:
fix locking and add lock debugging as a define
Modified: freeswitch/trunk/src/include/switch_core.h
==============================================================================
--- freeswitch/trunk/src/include/switch_core.h (original)
+++ freeswitch/trunk/src/include/switch_core.h Fri Dec 29 11:39:56 2006
@@ -230,24 +230,60 @@
///\defgroup rwl Read/Write Locking
///\ingroup core1
///\{
+
+#ifdef SWITCH_DEBUG_RWLOCKS
+SWITCH_DECLARE(switch_status_t) switch_core_session_perform_read_lock(switch_core_session_t *session,
+ const char *file,
+ const char *func,
+ int line);
+#endif
+
/*!
\brief Acquire a read lock on the session
\param session the session to acquire from
\return success if it is safe to read from the session
*/
+#ifdef SWITCH_DEBUG_RWLOCKS
+#define switch_core_session_read_lock(session) switch_core_session_perform_read_lock(session, __FILE__, __SWITCH_FUNC__, __LINE__)
+#else
SWITCH_DECLARE(switch_status_t) switch_core_session_read_lock(switch_core_session_t *session);
+#endif
+
+
+#ifdef SWITCH_DEBUG_RWLOCKS
+SWITCH_DECLARE(void) switch_core_session_perform_write_lock(switch_core_session_t *session,
+ const char *file,
+ const char *func,
+ int line);
+#endif
/*!
\brief Acquire a write lock on the session
\param session the session to acquire from
*/
+#ifdef SWITCH_DEBUG_RWLOCKS
+#define switch_core_session_write_lock(session) switch_core_session_perform_write_lock(session, __FILE__, __SWITCH_FUNC__, __LINE__)
+#else
SWITCH_DECLARE(void) switch_core_session_write_lock(switch_core_session_t *session);
+#endif
+
+#ifdef SWITCH_DEBUG_RWLOCKS
+SWITCH_DECLARE(void) switch_core_session_perform_rwunlock(switch_core_session_t *session,
+ const char *file,
+ const char *func,
+ int line);
+#endif
/*!
\brief Unlock a read or write lock on as given session
\param session the session
*/
+#ifdef SWITCH_DEBUG_RWLOCKS
+#define switch_core_session_rwunlock(session) switch_core_session_perform_rwunlock(session, __FILE__, __SWITCH_FUNC__, __LINE__)
+#else
SWITCH_DECLARE(void) switch_core_session_rwunlock(switch_core_session_t *session);
+#endif
+
///\}
///\defgroup sh State Handlers
@@ -410,13 +446,24 @@
*/
SWITCH_DECLARE(char *) switch_core_session_get_uuid(switch_core_session_t *session);
+#ifdef SWITCH_DEBUG_RWLOCKS
+SWITCH_DECLARE(switch_core_session_t *) switch_core_session_perform_locate(char *uuid_str,
+ const char *file,
+ const char *func,
+ int line);
+#endif
+
/*!
\brief Locate a session based on it's uuiid
\param uuid_str the unique id of the session you want to find
\return the session or NULL
\note if the session was located it will have a read lock obtained which will need to be released with switch_core_session_rwunlock()
*/
+#ifdef SWITCH_DEBUG_RWLOCKS
+#define switch_core_session_locate(uuid_str) switch_core_session_perform_locate(uuid_str, __FILE__, __SWITCH_FUNC__, __LINE__)
+#else
SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_str);
+#endif
/*!
\brief Retrieve a global variable from the core
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Fri Dec 29 11:39:56 2006
@@ -2613,7 +2613,7 @@
switch_channel_set_variable(channel, "endpoint_disposition", "EARLY MEDIA");
switch_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA);
switch_channel_set_flag(channel, CF_EARLY_MEDIA);
- return;
+ goto done;
}
switch_channel_set_variable(channel, "endpoint_disposition", "NO CODECS");
nua_respond(nh, SIP_488_NOT_ACCEPTABLE,
Modified: freeswitch/trunk/src/switch_core.c
==============================================================================
--- freeswitch/trunk/src/switch_core.c (original)
+++ freeswitch/trunk/src/switch_core.c Fri Dec 29 11:39:56 2006
@@ -543,31 +543,66 @@
return runtime.state_handlers[index];
}
+#ifdef SWITCH_DEBUG_RWLOCKS
+SWITCH_DECLARE(switch_status_t) switch_core_session_perform_read_lock(switch_core_session_t *session,
+ const char *file,
+ const char *func,
+ int line)
+#else
SWITCH_DECLARE(switch_status_t) switch_core_session_read_lock(switch_core_session_t *session)
+#endif
{
switch_status_t status = SWITCH_STATUS_FALSE;
if (session->rwlock) {
if (switch_test_flag(session, SSF_DESTROYED)) {
status = SWITCH_STATUS_FALSE;
+#ifdef SWITCH_DEBUG_RWLOCKS
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, (char *) file, func, line, SWITCH_LOG_DEBUG, "%s Read lock FAIL\n",
+ switch_channel_get_name(session->channel));
+#endif
} else {
status = (switch_status_t) switch_thread_rwlock_tryrdlock(session->rwlock);
+#ifdef SWITCH_DEBUG_RWLOCKS
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, (char *) file, func, line, SWITCH_LOG_DEBUG, "%s Read lock AQUIRED\n",
+ switch_channel_get_name(session->channel));
+#endif
}
}
return status;
}
+#ifdef SWITCH_DEBUG_RWLOCKS
+SWITCH_DECLARE(void) switch_core_session_perform_write_lock(switch_core_session_t *session,
+ const char *file,
+ const char *func,
+ int line)
+{
+
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, (char *) file, func, line, SWITCH_LOG_DEBUG, "%s Write lock AQUIRED\n",
+ switch_channel_get_name(session->channel));
+#else
SWITCH_DECLARE(void) switch_core_session_write_lock(switch_core_session_t *session)
{
+#endif
switch_thread_rwlock_wrlock(session->rwlock);
}
+#ifdef SWITCH_DEBUG_RWLOCKS
+SWITCH_DECLARE(void) switch_core_session_perform_rwunlock(switch_core_session_t *session,
+ const char *file,
+ const char *func,
+ int line)
+{
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, (char *) file, func, line, SWITCH_LOG_DEBUG, "%s Read/Write lock CLEARED\n",
+ switch_channel_get_name(session->channel));
+#else
SWITCH_DECLARE(void) switch_core_session_rwunlock(switch_core_session_t *session)
{
-
+#endif
switch_thread_rwlock_unlock(session->rwlock);
-
+
}
SWITCH_DECLARE(char *) switch_core_get_variable(char *varname)
@@ -575,7 +610,15 @@
return (char *) switch_core_hash_find(runtime.global_vars, varname);
}
+
+#ifdef SWITCH_DEBUG_RWLOCKS
+SWITCH_DECLARE(switch_core_session_t *) switch_core_session_perform_locate(char *uuid_str,
+ const char *file,
+ const char *func,
+ int line)
+#else
SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_str)
+#endif
{
switch_core_session_t *session = NULL;
@@ -583,7 +626,11 @@
switch_mutex_lock(runtime.session_table_mutex);
if ((session = switch_core_hash_find(runtime.session_table, uuid_str))) {
/* Acquire a read lock on the session */
- if (switch_test_flag(session, SSF_DESTROYED) || switch_thread_rwlock_tryrdlock(session->rwlock) != SWITCH_STATUS_SUCCESS) {
+#ifdef SWITCH_DEBUG_RWLOCKS
+ if (switch_core_session_perform_read_lock(session, file, func, line) != SWITCH_STATUS_SUCCESS) {
+#else
+ if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
+#endif
/* not available, forget it */
session = NULL;
}
@@ -601,6 +648,7 @@
void *val;
switch_core_session_t *session;
switch_channel_t *channel;
+ uint32_t loops = 0;
switch_mutex_lock(runtime.session_table_mutex);
for (hi = switch_hash_first(runtime.memory_pool, runtime.session_table); hi; hi = switch_hash_next(hi)) {
@@ -614,7 +662,12 @@
switch_mutex_unlock(runtime.session_table_mutex);
while(runtime.session_count > 0) {
- switch_yield(10000);
+ switch_yield(100000);
+ if (++loops == 100) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Giving up with %d session%s remaining\n",
+ runtime.session_count, runtime.session_count == 1 ? "" : "s");
+ break;
+ }
}
}
@@ -626,11 +679,11 @@
switch_mutex_lock(runtime.session_table_mutex);
if ((session = switch_core_hash_find(runtime.session_table, uuid_str)) != 0) {
/* Acquire a read lock on the session or forget it the channel is dead */
- if (switch_thread_rwlock_tryrdlock(session->rwlock) == SWITCH_STATUS_SUCCESS) {
+ if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
if (switch_channel_get_state(session->channel) < CS_HANGUP) {
status = switch_core_session_receive_message(session, message);
}
- switch_thread_rwlock_unlock(session->rwlock);
+ switch_core_session_rwunlock(session);
}
}
switch_mutex_unlock(runtime.session_table_mutex);
@@ -646,11 +699,11 @@
switch_mutex_lock(runtime.session_table_mutex);
if ((session = switch_core_hash_find(runtime.session_table, uuid_str)) != 0) {
/* Acquire a read lock on the session or forget it the channel is dead */
- if (switch_thread_rwlock_tryrdlock(session->rwlock) == SWITCH_STATUS_SUCCESS) {
+ if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
if (switch_channel_get_state(session->channel) < CS_HANGUP) {
status = switch_core_session_queue_event(session, event);
}
- switch_thread_rwlock_unlock(session->rwlock);
+ switch_core_session_rwunlock(session);
}
}
switch_mutex_unlock(runtime.session_table_mutex);
@@ -1654,7 +1707,7 @@
assert(session != NULL);
/* Acquire a read lock on the session or forget it the channel is dead */
- if (switch_thread_rwlock_tryrdlock(session->rwlock) == SWITCH_STATUS_SUCCESS) {
+ if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
if (switch_channel_get_state(session->channel) < CS_HANGUP) {
if (session->endpoint_interface->io_routines->receive_event) {
status = session->endpoint_interface->io_routines->receive_event(session, *event);
@@ -1676,7 +1729,7 @@
switch_event_destroy(event);
}
}
- switch_thread_rwlock_unlock(session->rwlock);
+ switch_core_session_rwunlock(session);
}
return status;
@@ -4182,6 +4235,8 @@
runtime.console = NULL;
}
+ switch_yield(1000000);
+
if (runtime.memory_pool) {
apr_pool_destroy(runtime.memory_pool);
if (!vg) {
1
0