diff --git a/conf/lang/en/ivr/sounds.xml b/conf/lang/en/ivr/sounds.xml
index 58db0a6c15..e436e294a3 100644
--- a/conf/lang/en/ivr/sounds.xml
+++ b/conf/lang/en/ivr/sounds.xml
@@ -8,4 +8,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/sofia-sip/configure.gnu b/libs/sofia-sip/configure.gnu
index e9cd89ac7c..4b64a47b7b 100644
--- a/libs/sofia-sip/configure.gnu
+++ b/libs/sofia-sip/configure.gnu
@@ -1,4 +1,4 @@
#! /bin/sh
srcpath=$(dirname $0 2>/dev/null ) || srcpath="."
-$srcpath/configure "$@" --with-pic --with-glib=no --disable-shared --without-doxygen
+$srcpath/configure "$@" --with-pic --with-glib=no --disable-shared --without-doxygen --disable-stun
diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h
index 176b841147..8fa0439b47 100644
--- a/src/include/switch_channel.h
+++ b/src/include/switch_channel.h
@@ -625,7 +625,7 @@ SWITCH_DECLARE(void) switch_channel_mark_hold(switch_channel_t *channel, switch_
/** @} */
SWITCH_DECLARE(switch_status_t) switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix);
-
+SWITCH_DECLARE(switch_status_t) switch_channel_api_on(switch_channel_t *channel, const char *variable_prefix);
SWITCH_END_EXTERN_C
#endif
diff --git a/src/include/switch_types.h b/src/include/switch_types.h
index f6183e6018..dd36b7f680 100644
--- a/src/include/switch_types.h
+++ b/src/include/switch_types.h
@@ -131,12 +131,21 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_COPY_XML_CDR_VARIABLE "copy_xml_cdr"
#define SWITCH_CURRENT_APPLICATION_VARIABLE "current_application"
#define SWITCH_PROTO_SPECIFIC_HANGUP_CAUSE_VARIABLE "proto_specific_hangup_cause"
+
#define SWITCH_CHANNEL_EXECUTE_ON_ANSWER_VARIABLE "execute_on_answer"
#define SWITCH_CHANNEL_EXECUTE_ON_PRE_ANSWER_VARIABLE "execute_on_pre_answer"
#define SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE "execute_on_media"
-#define SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE "api_on_answer"
#define SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE "execute_on_ring"
#define SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE "execute_on_tone_detect"
+#define SWITCH_CHANNEL_EXECUTE_ON_ORIGINATE_VARIABLE "execute_on_originate"
+
+#define SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE "api_on_answer"
+#define SWITCH_CHANNEL_API_ON_PRE_ANSWER_VARIABLE "api_on_pre_answer"
+#define SWITCH_CHANNEL_API_ON_MEDIA_VARIABLE "api_on_media"
+#define SWITCH_CHANNEL_API_ON_RING_VARIABLE "api_on_ring"
+#define SWITCH_CHANNEL_API_ON_TONE_DETECT_VARIABLE "api_on_tone_detect"
+#define SWITCH_CHANNEL_API_ON_ORIGINATE_VARIABLE "api_on_originate"
+
#define SWITCH_CALL_TIMEOUT_VARIABLE "call_timeout"
#define SWITCH_HOLDING_UUID_VARIABLE "holding_uuid"
#define SWITCH_SOFT_HOLDING_UUID_VARIABLE "soft_holding_uuid"
diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c
index 2a5a2aa2d1..aa95b1e28c 100644
--- a/src/mod/applications/mod_callcenter/mod_callcenter.c
+++ b/src/mod/applications/mod_callcenter/mod_callcenter.c
@@ -850,7 +850,7 @@ cc_status_t cc_agent_get(const char *key, const char *agent, char *ret_result, s
switch_event_t *event;
char res[256];
- /* Check to see if agent already exist */
+ /* Check to see if agent already exists */
sql = switch_mprintf("SELECT count(*) FROM agents WHERE name = '%q'", agent);
cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
switch_safe_free(sql);
@@ -860,8 +860,8 @@ cc_status_t cc_agent_get(const char *key, const char *agent, char *ret_result, s
goto done;
}
- if (!strcasecmp(key, "status") ) {
- /* Check to see if agent already exist */
+ if (!strcasecmp(key, "status") || !strcasecmp(key, "state") || !strcasecmp(key, "uuid") ) {
+ /* Check to see if agent already exists */
sql = switch_mprintf("SELECT %q FROM agents WHERE name = '%q'", key, agent);
cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
switch_safe_free(sql);
@@ -869,9 +869,15 @@ cc_status_t cc_agent_get(const char *key, const char *agent, char *ret_result, s
result = CC_STATUS_SUCCESS;
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) {
+ char tmpname[256];
+ if (!strcasecmp(key, "uuid")) {
+ switch_snprintf(tmpname, sizeof(tmpname), "CC-Agent-UUID");
+ } else {
+ switch_snprintf(tmpname, sizeof(tmpname), "CC-Agent-%c%s", (char) switch_toupper(key[0]), key+1);
+ }
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", agent);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Action", "agent-status-get");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-Status", res);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Action", "agent-%s-get", key);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, tmpname, res);
switch_event_fire(&event);
}
@@ -1400,6 +1406,10 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
/* Proceed contact the agent to offer the member */
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) {
+ switch_channel_t *member_channel = switch_core_session_get_channel(member_session);
+ switch_caller_profile_t *member_profile = switch_channel_get_caller_profile(member_channel);
+ const char *member_dnis = member_profile->rdnis;
+
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Queue", h->queue_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Action", "agent-offering");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name);
@@ -1409,6 +1419,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", h->member_session_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", h->member_cid_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Number", h->member_cid_number);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-DNIS", member_dnis);
switch_event_fire(&event);
}
@@ -1548,6 +1559,9 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
t_agent_answered = local_epoch_time_now(NULL);
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) {
+ switch_caller_profile_t *member_profile = switch_channel_get_caller_profile(member_channel);
+ const char *member_dnis = member_profile->rdnis;
+
switch_channel_event_set_data(agent_channel, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Queue", h->queue_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Action", "bridge-agent-start");
@@ -1561,6 +1575,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", h->member_session_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", h->member_cid_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Number", h->member_cid_number);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-DNIS", member_dnis);
switch_event_fire(&event);
}
/* for xml_cdr needs */
@@ -2676,7 +2691,9 @@ static int list_result_callback(void *pArg, int argc, char **argv, char **column
"\tcallcenter_config agent set busy_delay_time [agent_name] [wait second] | \n"\
"\tcallcenter_config agent set no_answer_delay_time [agent_name] [wait second] | \n"\
"\tcallcenter_config agent get status [agent_name] | \n" \
-"\tcallcenter_config agent list | \n" \
+"\tcallcenter_config agent get state [agent_name] | \n" \
+"\tcallcenter_config agent get uuid [agent_name] | \n" \
+"\tcallcenter_config agent list [[agent_name]] | \n" \
"\tcallcenter_config tier add [queue_name] [agent_name] [level] [position] | \n" \
"\tcallcenter_config tier set state [queue_name] [agent_name] [state] | \n" \
"\tcallcenter_config tier set level [queue_name] [agent_name] [level] | \n" \
@@ -2832,7 +2849,14 @@ SWITCH_STANDARD_API(cc_config_api_function)
struct list_result cbt;
cbt.row_process = 0;
cbt.stream = stream;
- sql = switch_mprintf("SELECT * FROM agents");
+ if ( argc-initial_argc > 1 ) {
+ stream->write_function(stream, "%s", "-ERR Invalid!\n");
+ goto done;
+ } else if ( argc-initial_argc == 1 ) {
+ sql = switch_mprintf("SELECT * FROM agents WHERE name='%q'", argv[0 + initial_argc]);
+ } else {
+ sql = switch_mprintf("SELECT * FROM agents");
+ }
cc_execute_sql_callback(NULL /* queue */, NULL /* mutex */, sql, list_result_callback, &cbt /* Call back variables */);
switch_safe_free(sql);
stream->write_function(stream, "%s", "+OK\n");
diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c
index 39e6380399..8c260ddf7f 100755
--- a/src/mod/applications/mod_dptools/mod_dptools.c
+++ b/src/mod/applications/mod_dptools/mod_dptools.c
@@ -3669,7 +3669,9 @@ static switch_status_t file_string_file_close(switch_file_handle_t *handle)
{
file_string_context_t *context = handle->private_info;
- switch_core_file_close(&context->fh);
+ if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) {
+ switch_core_file_close(&context->fh);
+ }
return SWITCH_STATUS_SUCCESS;
}
diff --git a/src/mod/applications/mod_protovm/Makefile b/src/mod/applications/mod_protovm/Makefile
deleted file mode 100644
index 92f8441104..0000000000
--- a/src/mod/applications/mod_protovm/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-BASE=../../../..
-LOCAL_OBJS=ivr.o util.o config.o menu.o
-include $(BASE)/build/modmake.rules
diff --git a/src/mod/applications/mod_protovm/config.c b/src/mod/applications/mod_protovm/config.c
deleted file mode 100644
index 6a2573b83a..0000000000
--- a/src/mod/applications/mod_protovm/config.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Copy paste from FS mod_voicemail */
-#include
-
-#include "config.h"
-
-const char *global_cf = "protovm.conf";
-
-void populate_profile_menu_event(vmivr_profile_t *profile, vmivr_menu_profile_t *menu) {
- switch_xml_t cfg, xml, x_profiles, x_profile, x_keys, x_phrases, x_menus, x_menu;
-
- free_profile_menu_event(menu);
-
- if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf);
- goto end;
- }
- if (!(x_profiles = switch_xml_child(cfg, "profiles"))) {
- goto end;
- }
-
- if ((x_profile = switch_xml_find_child(x_profiles, "profile", "name", profile->name))) {
- if ((x_menus = switch_xml_child(x_profile, "menus"))) {
- if ((x_menu = switch_xml_find_child(x_menus, "menu", "name", menu->name))) {
- if ((x_keys = switch_xml_child(x_menu, "keys"))) {
- switch_event_import_xml(switch_xml_child(x_keys, "key"), "dtmf", "action", &menu->event_keys_dtmf);
- switch_event_import_xml(switch_xml_child(x_keys, "key"), "action", "dtmf", &menu->event_keys_action);
- switch_event_import_xml(switch_xml_child(x_keys, "key"), "action", "variable", &menu->event_keys_varname);
- }
- if ((x_phrases = switch_xml_child(x_menu, "phrases"))) {
- switch_event_import_xml(switch_xml_child(x_phrases, "phrase"), "name", "value", &menu->event_phrases);
- }
- }
- }
- }
-end:
- if (xml)
- switch_xml_free(xml);
- return;
-
-}
-
-void free_profile_menu_event(vmivr_menu_profile_t *menu) {
- if (menu->event_keys_dtmf) {
- switch_event_destroy(&menu->event_keys_dtmf);
- }
- if (menu->event_keys_action) {
- switch_event_destroy(&menu->event_keys_action);
- }
- if (menu->event_keys_varname) {
- switch_event_destroy(&menu->event_keys_varname);
- }
-
- if (menu->event_phrases) {
- switch_event_destroy(&menu->event_phrases);
- }
-}
-
-vmivr_profile_t *get_profile(switch_core_session_t *session, const char *profile_name)
-{
- vmivr_profile_t *profile = NULL;
- switch_xml_t cfg, xml, x_profiles, x_profile, x_apis, param;
-
- if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf);
- return profile;
- }
- if (!(x_profiles = switch_xml_child(cfg, "profiles"))) {
- goto end;
- }
-
- if ((x_profile = switch_xml_find_child(x_profiles, "profile", "name", profile_name))) {
- if (!(profile = switch_core_session_alloc(session, sizeof(vmivr_profile_t)))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Alloc Failure\n");
- goto end;
- }
-
- profile->name = profile_name;
-
- profile->current_msg = 0;
- profile->current_msg_uuid = NULL;
-
- /* TODO Make the following configurable */
- profile->api_profile = profile->name;
- profile->menu_check_auth = "std_authenticate";
- profile->menu_check_main = "std_navigator";
- profile->menu_check_terminate = "std_purge";
-
- if ((x_apis = switch_xml_child(x_profile, "apis"))) {
- int total_options = 0;
- int total_invalid_options = 0;
- for (param = switch_xml_child(x_apis, "api"); param; param = param->next) {
- char *var, *val;
- if ((var = (char *) switch_xml_attr_soft(param, "name")) && (val = (char *) switch_xml_attr_soft(param, "value"))) {
- if (!strcasecmp(var, "msg_undelete") && !profile->api_msg_undelete)
- profile->api_msg_undelete = switch_core_session_strdup(session, val);
- else if (!strcasecmp(var, "msg_delete") && !profile->api_msg_delete)
- profile->api_msg_delete = switch_core_session_strdup(session, val);
- else if (!strcasecmp(var, "msg_list") && !profile->api_msg_list)
- profile->api_msg_list = switch_core_session_strdup(session, val);
- else if (!strcasecmp(var, "msg_count") && !profile->api_msg_count)
- profile->api_msg_count = switch_core_session_strdup(session, val);
- else if (!strcasecmp(var, "msg_save") && !profile->api_msg_save)
- profile->api_msg_save = switch_core_session_strdup(session, val);
- else if (!strcasecmp(var, "msg_purge") && !profile->api_msg_purge)
- profile->api_msg_purge = switch_core_session_strdup(session, val);
- else if (!strcasecmp(var, "msg_get") && !profile->api_msg_get)
- profile->api_msg_get = switch_core_session_strdup(session, val);
- else if (!strcasecmp(var, "msg_forward") && !profile->api_msg_forward)
- profile->api_msg_forward = switch_core_session_strdup(session, val);
- else if (!strcasecmp(var, "pref_greeting_set") && !profile->api_pref_greeting_set)
- profile->api_pref_greeting_set = switch_core_session_strdup(session, val);
- else if (!strcasecmp(var, "pref_recname_set") && !profile->api_pref_recname_set)
- profile->api_pref_recname_set = switch_core_session_strdup(session, val);
- else if (!strcasecmp(var, "pref_password_set") && !profile->api_pref_password_set)
- profile->api_pref_password_set = switch_core_session_strdup(session, val);
- else if (!strcasecmp(var, "auth_login") && !profile->api_auth_login)
- profile->api_auth_login = switch_core_session_strdup(session, val);
- else
- total_invalid_options++;
- total_options++;
- }
- }
- if (total_options - total_invalid_options != 12) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing api definition for profile '%s'\n", profile_name);
- profile = NULL;
- }
- }
-
- }
-
-end:
- switch_xml_free(xml);
- return profile;
-}
-
diff --git a/src/mod/applications/mod_protovm/config.h b/src/mod/applications/mod_protovm/config.h
deleted file mode 100644
index 2429f2cb36..0000000000
--- a/src/mod/applications/mod_protovm/config.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef _CONFIG_H_
-#define _CONFIG_H_
-
-extern const char *global_cf;
-
-struct vmivr_profile {
- const char *name;
-
- const char *domain;
- const char *id;
-
- int current_msg;
- const char *current_msg_uuid;
-
- const char *menu_check_auth;
- const char *menu_check_main;
- const char *menu_check_terminate;
-
- switch_bool_t authorized;
-
- const char *api_profile;
- const char *api_auth_login;
- const char *api_msg_delete;
- const char *api_msg_undelete;
- const char *api_msg_list;
- const char *api_msg_count;
- const char *api_msg_save;
- const char *api_msg_purge;
- const char *api_msg_get;
- const char *api_msg_forward;
- const char *api_pref_greeting_set;
- const char *api_pref_recname_set;
- const char *api_pref_password_set;
-
-};
-typedef struct vmivr_profile vmivr_profile_t;
-
-struct vmivr_menu_profile {
- const char *name;
-
- switch_event_t *event_keys_action;
- switch_event_t *event_keys_dtmf;
- switch_event_t *event_keys_varname;
- switch_event_t *event_phrases;
-};
-typedef struct vmivr_menu_profile vmivr_menu_profile_t;
-
-vmivr_profile_t *get_profile(switch_core_session_t *session, const char *profile_name);
-
-void free_profile_menu_event(vmivr_menu_profile_t *menu);
-void populate_profile_menu_event(vmivr_profile_t *profile, vmivr_menu_profile_t *menu);
-
-#endif /* _CONFIG_H_ */
diff --git a/src/mod/applications/mod_protovm/ivr.c b/src/mod/applications/mod_protovm/ivr.c
deleted file mode 100644
index a48132b1a2..0000000000
--- a/src/mod/applications/mod_protovm/ivr.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005-2011, Anthony Minessale II
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Marc Olivier Chouinard
- *
- *
- * ivr.c -- MT IVR System Interface
- *
- */
-
-#include
-
-#include "ivr.h"
-
-int match_dtmf(switch_core_session_t *session, dtmf_ss_t *loc) {
- switch_bool_t is_invalid[128] = { SWITCH_FALSE };
- int i;
- loc->potentialMatch = NULL;
- loc->completeMatch = NULL;
- loc->potentialMatchCount = 0;
-
- for (i = 0; i < loc->dtmf_received; i++) {
- int j;
- loc->potentialMatchCount = 0;
- for (j = 0; !zstr(loc->dtmf_accepted[j]) && j < 128; j++) {
- switch_bool_t cMatch = SWITCH_FALSE;
- char test[2] = { 0 };
-
- if (is_invalid[j])
- continue;
-
- test[0] = loc->dtmf_stored[i];
- if (loc->dtmf_accepted[j][i] == 'N' && atoi(test) >= 2 && atoi(test) <= 9)
- cMatch = SWITCH_TRUE;
- if (loc->dtmf_accepted[j][i] == 'X' && atoi(test) >= 0 && atoi(test) <= 9) {
- cMatch = SWITCH_TRUE;
- }
- if (i >= strlen(loc->dtmf_accepted[j]) - 1 && loc->dtmf_accepted[j][strlen(loc->dtmf_accepted[j])-1] == '.')
- cMatch = SWITCH_TRUE;
- if (loc->dtmf_accepted[j][i] == loc->dtmf_stored[i])
- cMatch = SWITCH_TRUE;
-
- if (cMatch == SWITCH_FALSE) {
- is_invalid[j] = SWITCH_TRUE;
- continue;
- }
-
- if (i == strlen(loc->dtmf_accepted[j]) - 1 && loc->dtmf_accepted[j][strlen(loc->dtmf_accepted[j])-1] == '.') {
- loc->completeMatch = loc->dtmf_accepted[j];
- }
- if (i == loc->dtmf_received - 1 && loc->dtmf_received == strlen(loc->dtmf_accepted[j]) && loc->dtmf_accepted[j][strlen(loc->dtmf_accepted[j])-1] != '.') {
- loc->completeMatch = loc->dtmf_accepted[j];
- continue;
- }
- loc->potentialMatchCount++;
- }
- }
-
- return 1;
-}
-
-static switch_status_t cb_on_dtmf_ignore(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
-{
- switch (itype) {
- case SWITCH_INPUT_TYPE_DTMF:
- {
- switch_channel_t *channel = switch_core_session_get_channel(session);
- switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
- switch_channel_queue_dtmf(channel, dtmf);
- return SWITCH_STATUS_BREAK;
- }
- default:
- break;
- }
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t cb_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
-{
- dtmf_ss_t *loc = (dtmf_ss_t*) buf;
-
- switch (itype) {
- case SWITCH_INPUT_TYPE_DTMF:
- {
- switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
- switch_bool_t audio_was_stopped = loc->audio_stopped;
- loc->audio_stopped = SWITCH_TRUE;
-
- if (loc->dtmf_received >= sizeof(loc->dtmf_stored)) {
- loc->result = RES_BUFFER_OVERFLOW;
- break;
- }
- if (!loc->terminate_key || dtmf->digit != loc->terminate_key)
- loc->dtmf_stored[loc->dtmf_received++] = dtmf->digit;
-
- match_dtmf(session, loc);
-
- if (loc->terminate_key && dtmf->digit == loc->terminate_key && loc->result == RES_WAITFORMORE) {
- if (loc->potentialMatchCount == 1 && loc->completeMatch != NULL) {
- loc->result = RES_FOUND;
- } else {
- loc->result = RES_INVALID;
- }
- return SWITCH_STATUS_BREAK;
- } else {
- if (loc->potentialMatchCount == 0 && loc->completeMatch != NULL) {
- loc->result = RES_FOUND;
- return SWITCH_STATUS_BREAK;
- } else if (loc->potentialMatchCount > 0) {
- loc->result = RES_WAITFORMORE;
- if (!audio_was_stopped)
- return SWITCH_STATUS_BREAK;
- } else {
- loc->result = RES_INVALID;
- return SWITCH_STATUS_BREAK;
- }
- }
- }
- break;
- default:
- break;
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-switch_status_t captureMenuInitialize(dtmf_ss_t *loc, char **dtmf_accepted) {
- int i;
-
- memset(loc, 0, sizeof(*loc));
-
- for (i = 0; dtmf_accepted[i] && i < 16; i++) {
- strncpy(loc->dtmf_accepted[i], dtmf_accepted[i], 128);
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-switch_status_t playbackBufferDTMF(switch_core_session_t *session, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout) {
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- switch_channel_t *channel = switch_core_session_get_channel(session);
-
- if (switch_channel_ready(channel)) {
- switch_input_args_t args = { 0 };
-
- args.input_callback = cb_on_dtmf_ignore;
-
- if (macro_name) {
- status = switch_ivr_phrase_macro_event(session, macro_name, data, event, lang, &args);
- }
- } else {
- status = SWITCH_STATUS_BREAK;
- }
-
- return status;
-}
-
-
-switch_status_t captureMenu(switch_core_session_t *session, dtmf_ss_t *loc, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout) {
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- switch_channel_t *channel = switch_core_session_get_channel(session);
-
- if (switch_channel_ready(channel)) {
- switch_input_args_t args = { 0 };
-
- args.input_callback = cb_on_dtmf;
- args.buf = loc;
-
- if (macro_name && loc->audio_stopped == SWITCH_FALSE && loc->result == RES_WAITFORMORE) {
- status = switch_ivr_phrase_macro_event(session, macro_name, data, event, lang, &args);
- }
-
- if (switch_channel_ready(channel) && (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK) && timeout && loc->result == RES_WAITFORMORE) {
- loc->audio_stopped = SWITCH_TRUE;
- switch_ivr_collect_digits_callback(session, &args, timeout, 0);
- if (loc->result == RES_WAITFORMORE) {
- if (loc->potentialMatchCount == 1 && loc->completeMatch != NULL) {
- loc->result = RES_FOUND;
- } else {
- loc->result = RES_TIMEOUT;
- }
- }
- }
- } else {
- status = SWITCH_STATUS_BREAK;
- }
-
- return status;
-}
-
-switch_status_t captureMenuRecord(switch_core_session_t *session, dtmf_ss_t *loc, switch_event_t *event, const char *file_path, switch_file_handle_t *fh, int max_record_len) {
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- switch_channel_t *channel = switch_core_session_get_channel(session);
-
- if (switch_channel_ready(channel)) {
- switch_input_args_t args = { 0 };
-
- args.input_callback = cb_on_dtmf;
- args.buf = loc;
-
- if (loc->audio_stopped == SWITCH_FALSE && loc->result == RES_WAITFORMORE) {
- loc->recorded_audio = SWITCH_TRUE;
- switch_ivr_gentones(session, "%(1000, 0, 640)", 0, NULL); /* TODO Make this optional and configurable */
- status = switch_ivr_record_file(session, fh, file_path, &args, max_record_len);
-
- }
- if (loc->result == RES_WAITFORMORE) {
- loc->result = RES_TIMEOUT;
- }
-
- } else {
- status = SWITCH_STATUS_BREAK;
- }
-
- return status;
-}
-
-
-/* For Emacs:
- * Local Variables:
- * mode:c
- * indent-tabs-mode:t
- * tab-width:4
- * c-basic-offset:4
- * End:
- * For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4
- */
diff --git a/src/mod/applications/mod_protovm/ivr.h b/src/mod/applications/mod_protovm/ivr.h
deleted file mode 100644
index 99136475fd..0000000000
--- a/src/mod/applications/mod_protovm/ivr.h
+++ /dev/null
@@ -1,30 +0,0 @@
-struct dtmf_ss {
- char dtmf_stored[128];
- int dtmf_received;
- char dtmf_accepted[16][128];
- int result;
- switch_bool_t audio_stopped;
- switch_bool_t recorded_audio;
- const char *potentialMatch;
- int potentialMatchCount;
- const char *completeMatch;
- char terminate_key;
-};
-typedef struct dtmf_ss dtmf_ss_t;
-
-#define RES_WAITFORMORE 0
-#define RES_FOUND 1
-#define RES_INVALID 3
-#define RES_TIMEOUT 4
-#define RES_BREAK 5
-#define RES_RECORD 6
-#define RES_BUFFER_OVERFLOW 99
-
-#define MAX_DTMF_SIZE_OPTION 32
-
-switch_status_t captureMenu(switch_core_session_t *session, dtmf_ss_t *loc, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout);
-switch_status_t captureMenuRecord(switch_core_session_t *session, dtmf_ss_t *loc, switch_event_t *event, const char *file_path, switch_file_handle_t *fh, int max_record_len);
-switch_status_t captureMenuInitialize(dtmf_ss_t *loc, char **dtmf_accepted);
-
-switch_status_t playbackBufferDTMF(switch_core_session_t *session, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout);
-
diff --git a/src/mod/applications/mod_protovm/menu.c b/src/mod/applications/mod_protovm/menu.c
deleted file mode 100644
index ba4229d43d..0000000000
--- a/src/mod/applications/mod_protovm/menu.c
+++ /dev/null
@@ -1,743 +0,0 @@
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005-2011, Anthony Minessale II
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Marc Olivier Chouinard
- *
- *
- * menu.c -- VoiceMail Menu
- *
- */
-#include
-
-#include "ivr.h"
-#include "menu.h"
-#include "util.h"
-#include "config.h"
-
-/* List of available menu */
-vmivr_menu_function_t menu_list[] = {
- {"std_authenticate", mtvm_menu_authenticate},
- {"std_navigator", mtvm_menu_main},
- {"std_record_name", mtvm_menu_record_name},
- {"std_set_password", mtvm_menu_set_password},
- {"std_select_greeting_slot", mtvm_menu_select_greeting_slot},
- {"std_record_greeting_with_slot", mtvm_menu_record_greeting_with_slot},
- {"std_preference", mtvm_menu_preference},
- {"std_purge", mtvm_menu_purge},
- {"std_forward", mtvm_menu_forward},
- { NULL, NULL }
-};
-
-#define MAX_ATTEMPT 3 /* TODO Make these fields configurable */
-#define DEFAULT_IVR_TIMEOUT 3000
-
-void mtvm_menu_purge(switch_core_session_t *session, vmivr_profile_t *profile) {
- if (profile->id && profile->authorized) {
- if (1==1 /* TODO make Purge email on exit optional ??? */) {
- const char *cmd = switch_core_session_sprintf(session, "%s %s %s", profile->api_profile, profile->domain, profile->id);
- mt_api_execute(session, profile->api_msg_purge, cmd);
- }
- }
-}
-void mtvm_menu_main(switch_core_session_t *session, vmivr_profile_t *profile) {
- switch_channel_t *channel = switch_core_session_get_channel(session);
- switch_event_t *msg_list_params = NULL;
- size_t msg_count = 0;
- size_t current_msg = 1;
- size_t next_msg = current_msg;
- size_t previous_msg = current_msg;
- char *cmd = NULL;
- int retry;
-
- /* Different switch to control playback of phrases */
- switch_bool_t initial_count_played = SWITCH_FALSE;
- switch_bool_t skip_header = SWITCH_FALSE;
- switch_bool_t msg_deleted = SWITCH_FALSE;
- switch_bool_t msg_undeleted = SWITCH_FALSE;
- switch_bool_t msg_saved = SWITCH_FALSE;
-
- vmivr_menu_profile_t menu = { "std_navigator" };
-
- /* Initialize Menu Configs */
- populate_profile_menu_event(profile, &menu);
-
- if (!menu.event_keys_dtmf || !menu.event_phrases) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases or Keys\n");
- return;
- }
-
- /* Get VoiceMail List And update msg count */
- cmd = switch_core_session_sprintf(session, "json %s %s %s", profile->api_profile, profile->domain, profile->id);
- msg_list_params = jsonapi2event(session, NULL, profile->api_msg_list, cmd);
- msg_count = atol(switch_event_get_header(msg_list_params,"VM-List-Count"));
-
- /* TODO Add Detection of new message and notify the user */
-
- for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
- switch_core_session_message_t msg = { 0 };
- char cid_buf[1024] = "";
- dtmf_ss_t loc;
- char *dtmfa[16] = { 0 };
- switch_event_t *phrase_params = NULL;
-
- switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS);
-
- append_event_profile(phrase_params, profile, menu);
-
- populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa);
-
- previous_msg = current_msg;
-
- /* Simple Protection to not go out of msg list scope */
- /* TODO: Add Prompt to notify they reached the begining or the end */
- if (next_msg == 0) {
- next_msg = 1;
- } else if (next_msg > msg_count) {
- next_msg = msg_count;
- }
-
- current_msg = next_msg;
-
- captureMenuInitialize(&loc, dtmfa);
-
- /* Prompt related to previous Message here */
- append_event_message(session, profile, phrase_params, msg_list_params, previous_msg);
- if (msg_deleted) {
- msg_deleted = SWITCH_FALSE;
- captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "deleted", phrase_params, NULL, 0);
- }
- if (msg_undeleted) {
- msg_undeleted = SWITCH_FALSE;
- captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "undeleted", phrase_params, NULL, 0);
- }
- if (msg_saved) {
- msg_saved = SWITCH_FALSE;
- captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "saved", phrase_params, NULL, 0);
- }
-
- /* Prompt related the current message */
- append_event_message(session, profile, phrase_params, msg_list_params, current_msg);
-
- /* Save in profile the current msg info for other menu processing AND restoration of our current position */
- switch_snprintf(cid_buf, sizeof(cid_buf), "%s|%s", switch_str_nil(switch_event_get_header(phrase_params, "VM-Message-Caller-Number")), switch_str_nil(switch_event_get_header(phrase_params, "VM-Message-Caller-Name")));
-
- /* Display MSG CID/Name to caller */
- msg.from = __FILE__;
- msg.string_arg = cid_buf;
- msg.message_id = SWITCH_MESSAGE_INDICATE_DISPLAY;
- switch_core_session_receive_message(session, &msg);
-
- profile->current_msg = current_msg;
- profile->current_msg_uuid = switch_core_session_strdup(session, switch_event_get_header(phrase_params, "VM-Message-UUID"));
-
- /* TODO check if msg is gone (purged by another session, notify user and auto jump to next message or something) */
- if (!skip_header) {
- if (!initial_count_played) {
- cmd = switch_core_session_sprintf(session, "json %s %s %s", profile->api_profile, profile->domain, profile->id);
- jsonapi2event(session, phrase_params, profile->api_msg_count, cmd);
- initial_count_played = SWITCH_TRUE;
- captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "msg_count"), NULL, phrase_params, NULL, 0);
- }
- if (msg_count > 0) {
- captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "say_msg_number"), NULL, phrase_params, NULL, 0);
- captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "say_date"), NULL, phrase_params, NULL, 0);
- }
- }
- if (msg_count > 0) {
- /* TODO Update the Read date of a message (When msg start, or when it listen compleatly ??? To be determined */
- captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "play_message"), NULL, phrase_params, NULL, 0);
- }
- skip_header = SWITCH_FALSE;
-
- captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
-
- if (loc.result == RES_TIMEOUT) {
- /* TODO Ask for the prompt Again IF retry != 0 */
- } else if (loc.result == RES_INVALID) {
- /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
- } else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */
- const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored);
-
- /* Reset the try count */
- retry = MAX_ATTEMPT;
-
- if (action) {
- if (!strcasecmp(action, "skip_intro")) { /* Skip Header / Play the recording again */
- skip_header = SWITCH_TRUE;
- } else if (!strcasecmp(action, "next_msg")) { /* Next Message */
- next_msg++;
- } else if (!strcasecmp(action, "prev_msg")) { /* Previous Message */
- next_msg--;
- } else if (!strcasecmp(action, "delete_msg")) { /* Delete / Undelete Message */
- const char *msg_flags = switch_event_get_header(phrase_params, "VM-Message-Flags");
- if (!msg_flags || strncasecmp(msg_flags, "delete", 6)) {
- cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID"));
- mt_api_execute(session, profile->api_msg_delete, cmd);
-
- msg_deleted = SWITCH_TRUE;
- /* TODO Option for auto going to next message or just return to the menu (So user used to do 76 to delete and next message wont be confused) */
- next_msg++;
- } else {
- cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID"));
- mt_api_execute(session, profile->api_msg_undelete, cmd);
-
- msg_undeleted = SWITCH_TRUE;
- }
- } else if (!strcasecmp(action, "save_msg")) { /* Save Message */
- cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID"));
- mt_api_execute(session, profile->api_msg_save, cmd);
-
- msg_saved = SWITCH_TRUE;
- } else if (!strcasecmp(action, "callback")) { /* CallBack caller */
- const char *cid_num = switch_event_get_header(phrase_params, "VM-Message-Caller-Number");
- if (cid_num) {
- /* TODO add detection for private number */
- switch_core_session_execute_exten(session, cid_num, "XML", profile->domain);
- } else {
- /* TODO Some error msg that the msg doesn't contain a caller number */
- }
- } else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */
- void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(action+5);
- if (fPtr) {
- fPtr(session, profile);
- }
- } else if (!strcasecmp(action, "return")) { /* Return */
- retry = -1;
- }
- }
- }
-
- /* IF the API to get the message returned us a COPY of the file locally (temp file create from a DB or from a web server), delete it */
- if (switch_true(switch_event_get_header(phrase_params, "VM-Message-Private-Local-Copy"))) {
- const char *file_path = switch_event_get_header(phrase_params, "VM-Message-File-Path");
- if (file_path && unlink(file_path) != 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to delete temp file [%s]\n", file_path);
- }
- }
- switch_event_destroy(&phrase_params);
- }
-
- switch_event_destroy(&msg_list_params);
-
- free_profile_menu_event(&menu);
-
- return;
-}
-
-void mtvm_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile) {
-
- vmivr_menu_profile_t menu = { "std_forward_ask_prepend" };
- switch_channel_t *channel = switch_core_session_get_channel(session);
- const char *prepend_filepath = NULL;
- int retry;
- switch_bool_t forward_msg = SWITCH_FALSE;
-
- /* Initialize Menu Configs */
- populate_profile_menu_event(profile, &menu);
-
- if (!menu.event_keys_dtmf || !menu.event_phrases) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n");
- return;
- }
-
- for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
- dtmf_ss_t loc;
- char *dtmfa[16] = { 0 };
- switch_event_t *phrase_params = NULL;
-
- switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS);
- append_event_profile(phrase_params, profile, menu);
-
- populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa);
-
- captureMenuInitialize(&loc, dtmfa);
-
- captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
-
- if (loc.result == RES_TIMEOUT) {
- /* TODO Ask for the prompt Again IF retry != 0 */
- } else if (loc.result == RES_INVALID) {
- /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
- } else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */
- const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored);
-
- /* Reset the try count */
- retry = MAX_ATTEMPT;
-
- if (action) {
- if (!strcasecmp(action, "return")) { /* Return to the previous menu */
- retry = -1;
- forward_msg = SWITCH_FALSE;
- } else if (!strcasecmp(action, "prepend")) { /* Prepend record msg */
- vmivr_menu_profile_t sub_menu = { "std_record_message" };
- char *tmp_filepath = generate_random_file_name(session, "protovm", "wav" /* TODO make it configurable */);
- switch_status_t status;
-
- /* Initialize Menu Configs */
- populate_profile_menu_event(profile, &sub_menu);
-
- status = mtvm_menu_record(session, profile, sub_menu, tmp_filepath);
-
- if (status == SWITCH_STATUS_SUCCESS) {
- //char *cmd = switch_core_session_sprintf(session, "%s %s %s %d %s", profile->api_profile, profile->domain, profile->id, gnum, tmp_filepath);
- //char *str_num = switch_core_session_sprintf(session, "%d", gnum);
- //mt_api_execute(session, profile->api_pref_greeting_set, cmd);
- //playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0);
- prepend_filepath = tmp_filepath;
- retry = -1;
- forward_msg = SWITCH_TRUE;
- } else {
- /* TODO Error Recording msg */
- }
- free_profile_menu_event(&sub_menu);
-
- } else if (!strcasecmp(action, "forward")) { /* Forward without prepend msg */
- retry = -1;
- forward_msg = SWITCH_TRUE;
- } else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */
- void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(action+5);
- if (fPtr) {
- fPtr(session, profile);
- }
- }
- }
- }
- switch_event_destroy(&phrase_params);
-
-
- }
- /* Ask Extension to Forward */
- if (forward_msg) {
- for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
- const char *id = NULL;
- vmivr_menu_profile_t sub_menu = { "std_forward_ask_extension" };
-
- /* Initialize Menu Configs */
- populate_profile_menu_event(profile, &sub_menu);
-
- id = mtvm_menu_get_input_set(session, profile, sub_menu, "X.");
- if (id) {
- const char *cmd = switch_core_session_sprintf(session, "%s %s %s %s %s %s %s%s%s", profile->api_profile, profile->domain, profile->id, profile->current_msg_uuid, profile->domain, id, prepend_filepath?" ":"", prepend_filepath?prepend_filepath:"" );
- if (mt_api_execute(session, profile->api_msg_forward, cmd) == SWITCH_STATUS_SUCCESS) {
- playbackBufferDTMF(session, switch_event_get_header(sub_menu.event_phrases, "ack"), "saved", NULL, NULL, 0);
- retry = -1;
- } else {
- playbackBufferDTMF(session, switch_event_get_header(sub_menu.event_phrases, "invalid_extension"), NULL, NULL, NULL, 0);
- }
- } else {
- /* TODO Prompt about input not valid */
- }
- free_profile_menu_event(&sub_menu);
- /* TODO add Confirmation of the transfered number */
- }
- /* TODO Ask if we want to transfer the msg to more person */
-
- }
-
- free_profile_menu_event(&menu);
-}
-
-
-void mtvm_menu_record_name(switch_core_session_t *session, vmivr_profile_t *profile) {
- switch_status_t status;
- vmivr_menu_profile_t menu = { "std_record_name" };
-
- char *tmp_filepath = generate_random_file_name(session, "protovm", "wav" /* TODO make it configurable */);
-
- /* Initialize Menu Configs */
- populate_profile_menu_event(profile, &menu);
-
- status = mtvm_menu_record(session, profile, menu, tmp_filepath);
-
- if (status == SWITCH_STATUS_SUCCESS) {
- char *cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, tmp_filepath);
- mt_api_execute(session, profile->api_pref_recname_set, cmd);
- }
-}
-
-void mtvm_menu_set_password(switch_core_session_t *session, vmivr_profile_t *profile) {
- char *password;
- vmivr_menu_profile_t menu = { "std_set_password" };
-
- /* Initialize Menu Configs */
- populate_profile_menu_event(profile, &menu);
-
- password = mtvm_menu_get_input_set(session, profile, menu, "XXX." /* TODO Conf Min 3 Digit */);
-
- /* TODO Add Prompts to tell if password was set and if it was not */
- if (password) {
- char *cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, password);
- mt_api_execute(session, profile->api_pref_password_set, cmd);
-
- }
-
- free_profile_menu_event(&menu);
-}
-
-void mtvm_menu_authenticate(switch_core_session_t *session, vmivr_profile_t *profile) {
- switch_channel_t *channel = switch_core_session_get_channel(session);
- vmivr_menu_profile_t menu = { "std_authenticate" };
- int retry;
- const char *auth_var = NULL;
- /* Initialize Menu Configs */
- populate_profile_menu_event(profile, &menu);
-
- if (profile->id && (auth_var = switch_channel_get_variable(channel, "voicemail_authorized")) && switch_true(auth_var)) {
- profile->authorized = SWITCH_TRUE;
- }
-
- for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0 && profile->authorized == SWITCH_FALSE; retry--) {
- const char *id = profile->id, *password = NULL;
- char *cmd = NULL;
-
- if (!id) {
- vmivr_menu_profile_t sub_menu = { "std_authenticate_ask_user" };
- /* Initialize Menu Configs */
- populate_profile_menu_event(profile, &sub_menu);
-
- id = mtvm_menu_get_input_set(session, profile, sub_menu, "X." /* TODO Conf Min 3 Digit */);
- free_profile_menu_event(&sub_menu);
- }
- if (!password) {
- vmivr_menu_profile_t sub_menu = { "std_authenticate_ask_password" };
- /* Initialize Menu Configs */
- populate_profile_menu_event(profile, &sub_menu);
-
- password = mtvm_menu_get_input_set(session, profile, sub_menu, "X." /* TODO Conf Min 3 Digit */);
- free_profile_menu_event(&sub_menu);
- }
- cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, id, password);
-
- if (mt_api_execute(session, profile->api_auth_login, cmd) == SWITCH_STATUS_SUCCESS) {
- profile->id = id;
- profile->authorized = SWITCH_TRUE;
- } else {
- playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "fail_auth"), NULL, NULL, NULL, 0);
- }
- }
- free_profile_menu_event(&menu);
-}
-
-void mtvm_menu_select_greeting_slot(switch_core_session_t *session, vmivr_profile_t *profile) {
- vmivr_menu_profile_t menu = { "std_select_greeting_slot" };
-
- const char *result;
- int gnum = -1;
-
- /* Initialize Menu Configs */
- populate_profile_menu_event(profile, &menu);
-
- result = mtvm_menu_get_input_set(session, profile, menu, "X");
-
- if (result)
- gnum = atoi(result);
- if (gnum != -1) {
- char * cmd = switch_core_session_sprintf(session, "%s %s %s %d", profile->api_profile, profile->domain, profile->id, gnum);
- if (mt_api_execute(session, profile->api_pref_greeting_set, cmd) == SWITCH_STATUS_SUCCESS) {
- char *str_num = switch_core_session_sprintf(session, "%d", gnum);
- playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0);
- } else {
- playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "invalid_slot"), NULL, NULL, NULL, 0);
- }
- }
- free_profile_menu_event(&menu);
-}
-
-void mtvm_menu_record_greeting_with_slot(switch_core_session_t *session, vmivr_profile_t *profile) {
-
- vmivr_menu_profile_t menu = { "std_record_greeting_with_slot" };
-
- const char *result;
- int gnum = -1;
-
- /* Initialize Menu Configs */
- populate_profile_menu_event(profile, &menu);
-
- result = mtvm_menu_get_input_set(session, profile, menu, "X");
-
- if (result)
- gnum = atoi(result);
-
- /* If user entered 0, we don't accept it */
- if (gnum > 0) {
- vmivr_menu_profile_t sub_menu = { "std_record_greeting" };
- char *tmp_filepath = generate_random_file_name(session, "protovm", "wav" /* TODO make it configurable */);
- switch_status_t status;
-
- /* Initialize Menu Configs */
- populate_profile_menu_event(profile, &sub_menu);
-
- status = mtvm_menu_record(session, profile, sub_menu, tmp_filepath);
-
- if (status == SWITCH_STATUS_SUCCESS) {
- char *cmd = switch_core_session_sprintf(session, "%s %s %s %d %s", profile->api_profile, profile->domain, profile->id, gnum, tmp_filepath);
- char *str_num = switch_core_session_sprintf(session, "%d", gnum);
- mt_api_execute(session, profile->api_pref_greeting_set, cmd);
- playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0);
- }
- free_profile_menu_event(&sub_menu);
-
- }
-
- free_profile_menu_event(&menu);
-
-}
-
-void mtvm_menu_preference(switch_core_session_t *session, vmivr_profile_t *profile) {
- switch_channel_t *channel = switch_core_session_get_channel(session);
-
- int retry;
-
- vmivr_menu_profile_t menu = { "std_preference" };
-
- /* Initialize Menu Configs */
- populate_profile_menu_event(profile, &menu);
-
- if (!menu.event_keys_dtmf || !menu.event_phrases) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n");
- return;
- }
-
- for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
- dtmf_ss_t loc;
- char *dtmfa[16] = { 0 };
- switch_event_t *phrase_params = NULL;
-
- switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS);
- append_event_profile(phrase_params, profile, menu);
-
- populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa);
-
- captureMenuInitialize(&loc, dtmfa);
-
- captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
-
- if (loc.result == RES_TIMEOUT) {
- /* TODO Ask for the prompt Again IF retry != 0 */
- } else if (loc.result == RES_INVALID) {
- /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
- } else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */
- const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored);
-
- /* Reset the try count */
- retry = MAX_ATTEMPT;
-
- if (action) {
- if (!strcasecmp(action, "return")) { /* Return to the previous menu */
- retry = -1;
- } else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */
- void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(action+5);
- if (fPtr) {
- fPtr(session, profile);
- }
- }
- }
- }
- switch_event_destroy(&phrase_params);
- }
-
- free_profile_menu_event(&menu);
-}
-
-char *mtvm_menu_get_input_set(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *input_mask) {
- char *result = NULL;
- int retry;
- const char *terminate_key = NULL;
- switch_channel_t *channel = switch_core_session_get_channel(session);
-
- if (!menu.event_keys_dtmf || !menu.event_phrases) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys : %s\n", menu.name);
- return result;
- }
-
- terminate_key = switch_event_get_header(menu.event_keys_action, "ivrengine:terminate_entry");
-
- for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
- dtmf_ss_t loc;
- char *dtmfa[16] = { 0 };
- int i;
- switch_event_t *phrase_params = NULL;
-
- switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS);
- append_event_profile(phrase_params, profile, menu);
-
- populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa);
-
- /* Find the last entry and append this one to it */
- for (i=0; dtmfa[i] && i < 16; i++){
- }
- dtmfa[i] = (char *) input_mask;
-
- captureMenuInitialize(&loc, dtmfa);
- if (terminate_key) {
- loc.terminate_key = terminate_key[0];
- }
- captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "instructions"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
-
- if (loc.result == RES_TIMEOUT) {
- /* TODO Ask for the prompt Again IF retry != 0 */
- } else if (loc.result == RES_INVALID) {
- /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
- } else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */
-
- /* Reset the try count */
- retry = MAX_ATTEMPT;
-
- if (!strncasecmp(loc.completeMatch, input_mask, 1)) {
- result = switch_core_session_strdup(session, loc.dtmf_stored);
- retry = -1;
-
- }
- }
- switch_event_destroy(&phrase_params);
- }
-
- return result;
-}
-
-switch_status_t mtvm_menu_record(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *file_name) {
- switch_status_t status = SWITCH_STATUS_FALSE;
- switch_channel_t *channel = switch_core_session_get_channel(session);
- int retry;
-
- switch_bool_t record_prompt = SWITCH_TRUE;
- switch_bool_t listen_recording = SWITCH_FALSE;
- switch_bool_t play_instruction = SWITCH_TRUE;
-
- if (!menu.event_keys_dtmf || !menu.event_phrases) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n");
- return status;
- }
-
- for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
- dtmf_ss_t loc;
-
- char *dtmfa[16] = { 0 };
- switch_event_t *phrase_params = NULL;
- switch_file_handle_t fh = { 0 };
-
- /* TODO Make the following configurable */
- fh.thresh = 200;
- fh.silence_hits = 4;
- //fh.samplerate = 8000;
-
-
- switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS);
- append_event_profile(phrase_params, profile, menu);
-
- populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa);
-
- captureMenuInitialize(&loc, dtmfa);
- if (record_prompt) {
- if (play_instruction) {
- captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "instructions"), NULL, phrase_params, NULL, 0);
- }
- play_instruction = SWITCH_TRUE;
-
- captureMenuRecord(session, &loc, phrase_params, file_name, &fh, 30 /* TODO Make max recording configurable */);
- } else {
- if (listen_recording) {
- switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Record-File-Path", "%s", file_name);
- captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "play_recording"), NULL, phrase_params, NULL, 0);
- listen_recording = SWITCH_FALSE;
-
- }
- captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
- }
-
- if (loc.recorded_audio) {
- /* Reset the try count */
- retry = MAX_ATTEMPT;
-
- /* TODO Check if message is too short */
-
- record_prompt = SWITCH_FALSE;
-
- } else if (loc.result == RES_TIMEOUT) {
- /* TODO Ask for the prompt Again IF retry != 0 */
- } else if (loc.result == RES_INVALID) {
- /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
- } else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */
- const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored);
-
- /* Reset the try count */
- retry = MAX_ATTEMPT;
-
- if (action) {
- if (!strcasecmp(action, "listen")) { /* Listen */
- listen_recording = SWITCH_TRUE;
-
- } else if (!strcasecmp(action, "save")) {
- retry = -1;
- /* TODO ALLOW SAVE ONLY IF FILE IS RECORDED AND HIGHER THAN MIN SIZE */
- status = SWITCH_STATUS_SUCCESS;
-
- } else if (!strcasecmp(action, "rerecord")) {
- record_prompt = SWITCH_TRUE;
-
- } else if (!strcasecmp(action, "skip_instruction")) { /* Skip Recording Greeting */
- play_instruction = SWITCH_FALSE;
-
- } else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */
- void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(action+5);
- if (fPtr) {
- fPtr(session, profile);
- }
- } else if (!strcasecmp(action, "return")) { /* Return */
- retry = -1;
- }
- }
- }
- switch_event_destroy(&phrase_params);
- }
- return status;
-}
-
-
-void (*mtvm_get_menu_function(const char *menu_name))(switch_core_session_t *session, vmivr_profile_t *profile) {
- int i = 0;
-
- if (menu_name) {
- for (i=0; menu_list[i].name ; i++) {
- if (!strcasecmp(menu_list[i].name, menu_name)) {
- return menu_list[i].pt2Func;
- }
- }
- }
- return NULL;
-}
-
-
-
-/* For Emacs:
- * Local Variables:
- * mode:c
- * indent-tabs-mode:t
- * tab-width:4
- * c-basic-offset:4
- * End:
- * For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4
- */
diff --git a/src/mod/applications/mod_protovm/menu.h b/src/mod/applications/mod_protovm/menu.h
deleted file mode 100644
index 82fd993a8f..0000000000
--- a/src/mod/applications/mod_protovm/menu.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _MENU_H_
-#define _MENU_H_
-
-#include "config.h"
-
-void mtvm_menu_purge(switch_core_session_t *session, vmivr_profile_t *profile);
-void mtvm_menu_authenticate(switch_core_session_t *session, vmivr_profile_t *profile);
-void mtvm_menu_main(switch_core_session_t *session, vmivr_profile_t *profile);
-void mtvm_menu_record_name(switch_core_session_t *session, vmivr_profile_t *profile);
-void mtvm_menu_set_password(switch_core_session_t *session, vmivr_profile_t *profile);
-void mtvm_menu_select_greeting_slot(switch_core_session_t *session, vmivr_profile_t *profile);
-void mtvm_menu_record_greeting_with_slot(switch_core_session_t *session, vmivr_profile_t *profile);
-void mtvm_menu_preference(switch_core_session_t *session, vmivr_profile_t *profile);
-void mtvm_menu_forward(switch_core_session_t *session, vmivr_profile_t *profile);
-
-switch_status_t mtvm_menu_record(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *file_name);
-char *mtvm_menu_get_input_set(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *input_mask);
-
-
-struct vmivr_menu_function {
- const char *name;
- void (*pt2Func)(switch_core_session_t *session, vmivr_profile_t *profile);
-
-};
-typedef struct vmivr_menu_function vmivr_menu_function_t;
-
-extern vmivr_menu_function_t menu_list[];
-
-void (*mtvm_get_menu_function(const char *menu_name))(switch_core_session_t *session, vmivr_profile_t *profile);
-
-#endif /* _MENU_H_ */
-
diff --git a/src/mod/applications/mod_protovm/mod_protovm.c b/src/mod/applications/mod_protovm/mod_protovm.c
deleted file mode 100644
index 7d826e03c2..0000000000
--- a/src/mod/applications/mod_protovm/mod_protovm.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005-2011, Anthony Minessale II
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Marc Olivier Chouinard
- *
- *
- * mod_protovm.c -- MT VoiceMail System
- *
- */
-#include
-
-#include "config.h"
-#include "menu.h"
-
-/* Prototypes */
-SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_protovm_shutdown);
-SWITCH_MODULE_RUNTIME_FUNCTION(mod_protovm_runtime);
-SWITCH_MODULE_LOAD_FUNCTION(mod_protovm_load);
-
-/* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime)
- * Defines a switch_loadable_module_function_table_t and a static const char[] modname
- */
-SWITCH_MODULE_DEFINITION(mod_protovm, mod_protovm_load, mod_protovm_shutdown, NULL);
-
-
-#define MTVM_DESC "protovm"
-#define MTVM_USAGE " profile domain [id]"
-
-SWITCH_STANDARD_APP(protovm_function)
-{
- const char *id = NULL;
- const char *domain = NULL;
- const char *profile_name = NULL;
- vmivr_profile_t *profile = NULL;
- int argc = 0;
- char *argv[6] = { 0 };
- char *mydata = NULL;
-
- if (!zstr(data)) {
- mydata = switch_core_session_strdup(session, data);
- argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
- }
-
- if (argv[1])
- profile_name = argv[1];
-
- if (argv[2])
- domain = argv[2];
-
- if (!strcasecmp(argv[0], "check")) {
- if (argv[3])
- id = argv[3];
-
- if (domain && profile_name) {
- profile = get_profile(session, profile_name);
-
- if (profile) {
- void (*fPtrAuth)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(profile->menu_check_auth);
- void (*fPtrMain)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(profile->menu_check_main);
- void (*fPtrTerminate)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(profile->menu_check_terminate);
-
- profile->domain = domain;
- profile->id = id;
-
- if (fPtrAuth && !profile->authorized) {
- fPtrAuth(session, profile);
- }
-
- if (fPtrMain && profile->authorized) {
- fPtrMain(session, profile);
- }
- if (fPtrTerminate) {
- fPtrTerminate(session, profile);
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile '%s' not found\n", profile_name);
- }
- }
- }
- return;
-}
-
-/* Macro expands to: switch_status_t mod_protovm_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */
-SWITCH_MODULE_LOAD_FUNCTION(mod_protovm_load)
-{
- switch_application_interface_t *app_interface;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
-
- /* connect my internal structure to the blank pointer passed to me */
- *module_interface = switch_loadable_module_create_module_interface(pool, modname);
-
- SWITCH_ADD_APP(app_interface, "protovm", "protovm", MTVM_DESC, protovm_function, MTVM_USAGE, SAF_NONE);
-
- /* indicate that the module should continue to be loaded */
- return status;
-}
-
-/*
- Called when the system shuts down
- Macro expands to: switch_status_t mod_protovm_shutdown() */
-SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_protovm_shutdown)
-{
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-/* For Emacs:
- * Local Variables:
- * mode:c
- * indent-tabs-mode:t
- * tab-width:4
- * c-basic-offset:4
- * End:
- * For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4
- */
diff --git a/src/mod/applications/mod_protovm/protovm.conf.xml b/src/mod/applications/mod_protovm/protovm.conf.xml
deleted file mode 100644
index c57e8f72b6..0000000000
--- a/src/mod/applications/mod_protovm/protovm.conf.xml
+++ /dev/null
@@ -1,176 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/mod/applications/mod_protovm/sounds.xml b/src/mod/applications/mod_protovm/sounds.xml
deleted file mode 100644
index 35dcef169a..0000000000
--- a/src/mod/applications/mod_protovm/sounds.xml
+++ /dev/null
@@ -1,397 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/mod/applications/mod_protovm/util.c b/src/mod/applications/mod_protovm/util.c
deleted file mode 100644
index 476e99bd26..0000000000
--- a/src/mod/applications/mod_protovm/util.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005-2011, Anthony Minessale II
- *
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- *
- * The Initial Developer of the Original Code is
- * Anthony Minessale II
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Marc Olivier Chouinard
- *
- *
- * utils.c -- MT VoiceMail / Different utility that might need to go into the core (after cleanup)
- *
- */
-#include
-
-#include "util.h"
-
-switch_status_t mt_merge_media_files(const char** inputs, const char *output) {
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- switch_file_handle_t fh_output = { 0 };
- int channels = 1;
- int rate = 8000; /* TODO Make this configurable */
- int j = 0;
-
- if (switch_core_file_open(&fh_output, output, channels, rate, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open %s\n", output);
- goto end;
- }
-
- for (j = 0; inputs[j] != NULL && j < 128 && status == SWITCH_STATUS_SUCCESS; j++) {
- switch_file_handle_t fh_input = { 0 };
- char buf[2048];
- switch_size_t len = sizeof(buf) / 2;
-
- if (switch_core_file_open(&fh_input, inputs[j], channels, rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open %s\n", inputs[j]);
- status = SWITCH_STATUS_GENERR;
- break;
- }
-
- while (switch_core_file_read(&fh_input, buf, &len) == SWITCH_STATUS_SUCCESS) {
- if (switch_core_file_write(&fh_output, buf, &len) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write error\n");
- status = SWITCH_STATUS_GENERR;
- break;
- }
- }
-
- if (fh_input.file_interface) {
- switch_core_file_close(&fh_input);
- }
- }
-
- if (fh_output.file_interface) {
- switch_core_file_close(&fh_output);
- }
-end:
- return status;
-}
-
-switch_event_t *jsonapi2event(switch_core_session_t *session, switch_event_t *apply_event, const char *api, const char *data) {
- switch_event_t *phrases_event = NULL;
- switch_stream_handle_t stream = { 0 };
- SWITCH_STANDARD_STREAM(stream);
- switch_api_execute(api, data, session, &stream);
- switch_event_create_json(&phrases_event, (char *) stream.data);
- switch_safe_free(stream.data);
-
- if (apply_event) {
- switch_event_header_t *hp;
- for (hp = phrases_event->headers; hp; hp = hp->next) {
- if (!strncasecmp(hp->name, "VM-", 3)) {
- switch_event_add_header(apply_event, SWITCH_STACK_BOTTOM, hp->name, "%s", hp->value);
- }
- }
- switch_event_destroy(&phrases_event);
- phrases_event = apply_event;
-
- }
-
- return phrases_event;
-}
-
-char *generate_random_file_name(switch_core_session_t *session, const char *mod_name, char *file_extension) {
- char rand_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = "";
- switch_uuid_t srand_uuid;
-
- switch_uuid_get(&srand_uuid);
- switch_uuid_format(rand_uuid, &srand_uuid);
-
- return switch_core_session_sprintf(session, "%s%s%s_%s.%s", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, mod_name, rand_uuid, file_extension);
-
-}
-
-switch_status_t mt_api_execute(switch_core_session_t *session, const char *apiname, const char *arguments) {
- switch_status_t status = SWITCH_STATUS_SUCCESS;
-
- switch_stream_handle_t stream = { 0 };
-
- SWITCH_STANDARD_STREAM(stream);
- switch_api_execute(apiname, arguments, session, &stream);
- if (!strncasecmp(stream.data, "-ERR", 4)) {
- status = SWITCH_STATUS_GENERR;
- }
- switch_safe_free(stream.data);
- return status;
-}
-
-void append_event_profile(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu) {
- /* Used for some appending function */
- if (profile->name && profile->id && profile->domain) {
- switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Profile", "%s", profile->name);
- switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Account-ID", "%s", profile->id);
- switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Account-Domain", "%s", profile->domain);
- }
-}
-
-void populate_dtmfa_from_event(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu, char **dtmfa) {
- int i = 0;
- if (menu.event_keys_dtmf) {
- switch_event_header_t *hp;
-
- for (hp = menu.event_keys_dtmf->headers; hp; hp = hp->next) {
- if (strlen(hp->name) < 3 && hp->value) { /* TODO This is a hack to discard default FS Events ! */
- const char *varphrasename = switch_event_get_header(menu.event_keys_varname, hp->value);
- dtmfa[i++] = hp->name;
-
- if (varphrasename && !zstr(varphrasename)) {
- switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, varphrasename, "%s", hp->name);
- }
- }
- }
- }
-
-}
-
-void append_event_message(switch_core_session_t *session, vmivr_profile_t *profile, switch_event_t *phrase_params, switch_event_t *msg_list_event, size_t current_msg) {
-
- char *varname;
- char *apicmd;
-
- varname = switch_mprintf("VM-List-Message-%" SWITCH_SIZE_T_FMT "-UUID", current_msg);
- apicmd = switch_mprintf("json %s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(msg_list_event, varname));
-
- switch_safe_free(varname);
-
- jsonapi2event(session, phrase_params, profile->api_msg_get, apicmd);
-
- /* TODO Set these 2 header correctly */
- switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Message-Type", "%s", "new");
- switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Message-Number", "%"SWITCH_SIZE_T_FMT, current_msg);
-
- switch_event_add_header_string(phrase_params, SWITCH_STACK_BOTTOM, "VM-Message-Private-Local-Copy", "False");
-
- switch_safe_free(apicmd);
-}
-
diff --git a/src/mod/applications/mod_protovm/util.h b/src/mod/applications/mod_protovm/util.h
deleted file mode 100644
index 1c46329e18..0000000000
--- a/src/mod/applications/mod_protovm/util.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _UTIL_H_
-#define _UTIL_H_
-
-#include "config.h"
-
-switch_status_t mt_merge_files(const char** inputs, const char *output);
-
-void append_event_message(switch_core_session_t *session, vmivr_profile_t *profile, switch_event_t *phrase_params, switch_event_t *msg_list_event, size_t current_msg);
-void append_event_profile(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu);
-char *generate_random_file_name(switch_core_session_t *session, const char *mod_name, char *file_extension);
-switch_event_t *jsonapi2event(switch_core_session_t *session, switch_event_t *apply_event, const char *api, const char *data);
-switch_status_t mt_merge_media_files(const char** inputs, const char *output);
-switch_status_t mt_api_execute(switch_core_session_t *session, const char *apiname, const char *arguments);
-void populate_dtmfa_from_event(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu, char **dtmfa);
-#endif /* _UTIL_H_ */
-
diff --git a/src/mod/applications/mod_valet_parking/mod_valet_parking.c b/src/mod/applications/mod_valet_parking/mod_valet_parking.c
index 3e8337d857..291d6c86a5 100644
--- a/src/mod/applications/mod_valet_parking/mod_valet_parking.c
+++ b/src/mod/applications/mod_valet_parking/mod_valet_parking.c
@@ -276,17 +276,19 @@ SWITCH_STANDARD_APP(valet_parking_function)
if (token->timeout) {
const char *var = switch_channel_get_variable(channel, "valet_ticket");
- if (!strcmp(var, token->uuid)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Valet ticket %s accepted.\n", var);
- switch_channel_set_variable(channel, "valet_ticket", NULL);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid token %s\n", token->uuid);
- switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
- return;
+ if (!zstr(var)) {
+ if (!strcmp(var, token->uuid)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Valet ticket %s accepted.\n", var);
+ switch_channel_set_variable(channel, "valet_ticket", NULL);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid token %s\n", token->uuid);
+ switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+ return;
+ }
}
}
- if (token && (b_session = switch_core_session_locate(token->uuid))) {
+ if (!zstr(token->uuid) && (b_session = switch_core_session_locate(token->uuid))) {
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, VALET_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Valet-Lot-Name", lot_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Valet-Extension", ext);
diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c
index 2eb89ebc43..6fc16465d7 100644
--- a/src/mod/applications/mod_voicemail/mod_voicemail.c
+++ b/src/mod/applications/mod_voicemail/mod_voicemail.c
@@ -45,6 +45,7 @@ SWITCH_MODULE_DEFINITION(mod_voicemail, mod_voicemail_load, mod_voicemail_shutdo
#define VM_EVENT_MAINT "vm::maintenance"
#define VM_MAX_GREETINGS 9
+#define VM_EVENT_QUEUE_SIZE 50000
static switch_status_t voicemail_inject(const char *data, switch_core_session_t *session);
@@ -53,6 +54,9 @@ static struct {
switch_hash_t *profile_hash;
int debug;
int message_query_exact_match;
+ int32_t threads;
+ int32_t running;
+ switch_queue_t *event_queue;
switch_mutex_t *mutex;
switch_memory_pool_t *pool;
} globals;
@@ -1160,6 +1164,8 @@ static switch_status_t create_file(switch_core_session_t *session, vm_profile_t
args.buf = input;
args.buflen = sizeof(input);
+ unlink(file_path);
+
switch_ivr_record_file(session, &fh, file_path, &args, profile->max_record_len);
if (switch_file_exists(file_path, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
@@ -1819,7 +1825,7 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p
uint32_t timeout, attempts = 0, retries = 0;
int failed = 0;
msg_type_t play_msg_type = MSG_NONE;
- char *dir_path = NULL, *file_path = NULL;
+ char *dir_path = NULL, *file_path = NULL, *tmp_file_path = NULL;
int total_new_messages = 0;
int total_saved_messages = 0;
int total_new_urgent_messages = 0;
@@ -2099,13 +2105,19 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p
} else {
switch_event_t *params;
file_path = switch_mprintf("%s%sgreeting_%d.%s", dir_path, SWITCH_PATH_SEPARATOR, num, profile->file_ext);
+ tmp_file_path = switch_mprintf("%s%sgreeting_%d_TMP.%s", dir_path, SWITCH_PATH_SEPARATOR, num, profile->file_ext);
+ unlink(tmp_file_path);
+
TRY_CODE(create_file(session, profile, VM_RECORD_GREETING_MACRO, file_path, &message_len, SWITCH_TRUE, NULL, NULL));
+ switch_file_rename(tmp_file_path, file_path, switch_core_session_get_pool(session));
+
sql =
switch_mprintf("update voicemail_prefs set greeting_path='%s' where username='%s' and domain='%s'", file_path, myid,
domain_name);
vm_execute_sql(profile, sql, profile->mutex);
switch_safe_free(sql);
switch_safe_free(file_path);
+ switch_safe_free(tmp_file_path);
switch_event_create_subclass(¶ms, SWITCH_EVENT_CUSTOM, VM_EVENT_MAINT);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Action", "record-greeting");
@@ -2146,10 +2158,14 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p
} else if (!strcmp(input, profile->record_name_key)) {
switch_event_t *params;
file_path = switch_mprintf("%s%srecorded_name.%s", dir_path, SWITCH_PATH_SEPARATOR, profile->file_ext);
+ tmp_file_path = switch_mprintf("%s%srecorded_name_TMP.%s", dir_path, SWITCH_PATH_SEPARATOR, profile->file_ext);
+ unlink(tmp_file_path);
TRY_CODE(create_file(session, profile, VM_RECORD_NAME_MACRO, file_path, &message_len, SWITCH_FALSE, NULL, NULL));
+ switch_file_rename(tmp_file_path, file_path, switch_core_session_get_pool(session));
sql = switch_mprintf("update voicemail_prefs set name_path='%s' where username='%s' and domain='%s'", file_path, myid, domain_name);
vm_execute_sql(profile, sql, profile->mutex);
switch_safe_free(file_path);
+ switch_safe_free(tmp_file_path);
switch_safe_free(sql);
switch_event_create_subclass(¶ms, SWITCH_EVENT_CUSTOM, VM_EVENT_MAINT);
@@ -2431,6 +2447,14 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p
end:
+ switch_safe_free(file_path);
+
+ if (tmp_file_path) {
+ unlink(tmp_file_path);
+ free(tmp_file_path);
+ tmp_file_path = NULL;
+ }
+
if (switch_channel_ready(channel)) {
if (failed) {
status = switch_ivr_phrase_macro(session, VM_ABORT_MACRO, NULL, NULL, NULL);
@@ -3629,16 +3653,14 @@ SWITCH_STANDARD_API(prefs_api_function)
switch_event_add_header_string(new_event, SWITCH_STACK_BOTTOM, "MWI-Message-Account", account); \
switch_event_add_header(new_event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d (%d/%d)", \
+total_new_messages, total_saved_messages, total_new_urgent_messages, total_saved_urgent_messages); \
- created++; \
} \
} \
}
-static void message_query_handler(switch_event_t *event)
+static void actual_message_query_handler(switch_event_t *event)
{
char *account = switch_event_get_header(event, "message-account");
- int created = 0;
switch_event_t *new_event = NULL;
char *dup = NULL;
int total_new_messages = 0;
@@ -3677,6 +3699,10 @@ static void message_query_handler(switch_event_t *event)
switch_hash_this(hi, NULL, NULL, &val);
profile = (vm_profile_t *) val;
parse_profile();
+
+ if (new_event) {
+ break;
+ }
}
}
}
@@ -3685,7 +3711,7 @@ static void message_query_handler(switch_event_t *event)
}
- if (!created) {
+ if (!new_event) {
if (switch_event_create(&new_event, SWITCH_EVENT_MESSAGE_WAITING) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(new_event, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", "no");
switch_event_add_header_string(new_event, SWITCH_STACK_BOTTOM, "MWI-Message-Account", account);
@@ -3707,6 +3733,101 @@ static void message_query_handler(switch_event_t *event)
}
+static int EVENT_THREAD_RUNNING = 0;
+static int EVENT_THREAD_STARTED = 0;
+
+void *SWITCH_THREAD_FUNC vm_event_thread_run(switch_thread_t *thread, void *obj)
+{
+ void *pop;
+ int done = 0;
+
+ switch_mutex_lock(globals.mutex);
+ if (!EVENT_THREAD_RUNNING) {
+ EVENT_THREAD_RUNNING++;
+ globals.threads++;
+ } else {
+ done = 1;
+ }
+ switch_mutex_unlock(globals.mutex);
+
+ if (done) {
+ return NULL;
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Event Thread Started\n");
+
+ while (globals.running == 1) {
+ int count = 0;
+
+ if (switch_queue_trypop(globals.event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
+ switch_event_t *event = (switch_event_t *) pop;
+
+ if (!pop) {
+ break;
+ }
+ actual_message_query_handler(event);
+ switch_event_destroy(&event);
+ count++;
+ }
+
+ if (!count) {
+ switch_yield(100000);
+ }
+ }
+
+ while (switch_queue_trypop(globals.event_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
+ switch_event_t *event = (switch_event_t *) pop;
+ switch_event_destroy(&event);
+ }
+
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Event Thread Ended\n");
+
+ switch_mutex_lock(globals.mutex);
+ globals.threads--;
+ EVENT_THREAD_RUNNING = EVENT_THREAD_STARTED = 0;
+ switch_mutex_unlock(globals.mutex);
+
+ return NULL;
+}
+
+void vm_event_thread_start(void)
+{
+ switch_thread_t *thread;
+ switch_threadattr_t *thd_attr = NULL;
+ int done = 0;
+
+ switch_mutex_lock(globals.mutex);
+ if (!EVENT_THREAD_STARTED) {
+ EVENT_THREAD_STARTED++;
+ } else {
+ done = 1;
+ }
+ switch_mutex_unlock(globals.mutex);
+
+ if (done) {
+ return;
+ }
+
+ switch_threadattr_create(&thd_attr, globals.pool);
+ switch_threadattr_detach_set(thd_attr, 1);
+ switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+ switch_threadattr_priority_increase(thd_attr);
+ switch_thread_create(&thread, thd_attr, vm_event_thread_run, NULL, globals.pool);
+}
+
+void vm_event_handler(switch_event_t *event)
+{
+ switch_event_t *cloned_event;
+
+ switch_event_dup(&cloned_event, event);
+ switch_assert(cloned_event);
+ switch_queue_push(globals.event_queue, cloned_event);
+
+ if (!EVENT_THREAD_STARTED) {
+ vm_event_thread_start();
+ }
+}
struct holder {
vm_profile_t *profile;
@@ -5482,14 +5603,20 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_voicemail_load)
switch_core_hash_init(&globals.profile_hash, globals.pool);
switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
+ switch_mutex_lock(globals.mutex);
+ globals.running = 1;
+ switch_mutex_unlock(globals.mutex);
+
+ switch_queue_create(&globals.event_queue, VM_EVENT_QUEUE_SIZE, globals.pool);
if ((status = load_config()) != SWITCH_STATUS_SUCCESS) {
+ globals.running = 0;
return status;
}
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
- if (switch_event_bind(modname, SWITCH_EVENT_MESSAGE_QUERY, SWITCH_EVENT_SUBCLASS_ANY, message_query_handler, NULL)
+ if (switch_event_bind(modname, SWITCH_EVENT_MESSAGE_QUERY, SWITCH_EVENT_SUBCLASS_ANY, vm_event_handler, NULL)
!= SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
@@ -5534,9 +5661,23 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_voicemail_shutdown)
void *val = NULL;
const void *key;
switch_ssize_t keylen;
+ int sanity = 0;
+
+ switch_mutex_lock(globals.mutex);
+ if (globals.running == 1) {
+ globals.running = 0;
+ }
+ switch_mutex_unlock(globals.mutex);
switch_event_free_subclass(VM_EVENT_MAINT);
- switch_event_unbind_callback(message_query_handler);
+ switch_event_unbind_callback(vm_event_handler);
+
+ while (globals.threads) {
+ switch_cond_next();
+ if (++sanity >= 60000) {
+ break;
+ }
+ }
switch_mutex_lock(globals.mutex);
while ((hi = switch_hash_first(NULL, globals.profile_hash))) {
diff --git a/src/mod/endpoints/mod_rtmp/rtmp_sig.c b/src/mod/endpoints/mod_rtmp/rtmp_sig.c
index ece43bc050..7aaf79d6f6 100644
--- a/src/mod/endpoints/mod_rtmp/rtmp_sig.c
+++ b/src/mod/endpoints/mod_rtmp/rtmp_sig.c
@@ -301,7 +301,7 @@ RTMP_INVOKE_FUNCTION(rtmp_i_makeCall)
amf_object_to_event(argv[3], &event);
}
- if (rtmp_session_create_call(rsession, &newsession, 0, RTMP_DEFAULT_STREAM_AUDIO, number, user, domain, event) != SWITCH_CAUSE_NONE) {
+ if (rtmp_session_create_call(rsession, &newsession, 0, RTMP_DEFAULT_STREAM_AUDIO, number, user, domain, event) != SWITCH_CAUSE_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rsession->uuid), SWITCH_LOG_ERROR, "Couldn't create call.\n");
}
diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c
index 72d82cb10c..10ebfc9899 100644
--- a/src/mod/endpoints/mod_skypopen/oss/main.c
+++ b/src/mod/endpoints/mod_skypopen/oss/main.c
@@ -283,6 +283,7 @@ static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t
* The ioctl() implementation
*/
+#ifndef HAVE_UNLOCKED_IOCTL
static int skypopen_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -302,13 +303,38 @@ static int skypopen_ioctl(struct inode *inode, struct file *filp,
}
}
+#else// HAVE_UNLOCKED_IOCTL
+static long skypopen_unlocked_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+
+ switch (cmd) {
+ case OSS_GETVERSION:
+ return put_user(SOUND_VERSION, p);
+ case SNDCTL_DSP_GETBLKSIZE:
+ return put_user(SKYPOPEN_BLK, p);
+ case SNDCTL_DSP_GETFMTS:
+ return put_user(28731, p);
+
+ default:
+ return 0;
+ }
+
+}
+#endif// HAVE_UNLOCKED_IOCTL
struct file_operations skypopen_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = skypopen_read,
.write = skypopen_write,
+#ifndef HAVE_UNLOCKED_IOCTL
.ioctl = skypopen_ioctl,
+#else// HAVE_UNLOCKED_IOCTL
+ .unlocked_ioctl = skypopen_unlocked_ioctl,
+#endif// HAVE_UNLOCKED_IOCTL
.open = skypopen_c_open,
.release = skypopen_c_release,
};
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index 87817c3c7f..2774e7135a 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -792,6 +792,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
SOATAG_REUSE_REJECTED(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
+ TAG_IF(is_proxy, SOATAG_RTP_SELECT(1)),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h
index 190212a22b..5566854208 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.h
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.h
@@ -354,6 +354,7 @@ struct mod_sofia_globals {
int debug_presence;
int debug_sla;
int auto_restart;
+ int reg_deny_binding_fetch_and_no_lookup; /* backwards compatibility */
int auto_nat;
int tracelevel;
char *capture_server;
@@ -1116,6 +1117,7 @@ switch_t38_options_t *sofia_glue_extract_t38_options(switch_core_session_t *sess
char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefix, const char *sdp, char **mp_type);
void sofia_glue_tech_simplify(private_object_t *tech_pvt);
switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host);
+switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_multi(sofia_profile_t *profile, const char *user, const char *host);
switch_bool_t sofia_glue_profile_exists(const char *key);
void sofia_glue_global_siptrace(switch_bool_t on);
void sofia_glue_global_capture(switch_bool_t on);
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index c225b2bf35..2e2aacf9d0 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -48,7 +48,9 @@ extern su_log_t nth_server_log[];
extern su_log_t nua_log[];
extern su_log_t soa_log[];
extern su_log_t sresolv_log[];
+#ifdef HAVE_SOFIA_STUN
extern su_log_t stun_log[];
+#endif
extern su_log_t su_log_default[];
static void config_sofia_profile_urls(sofia_profile_t * profile);
@@ -1255,8 +1257,9 @@ void sofia_event_callback(nua_event_t event,
if (!zstr(sofia_private->uuid)) {
if ((session = switch_core_session_locate(sofia_private->uuid))) {
-
- if (switch_core_session_running(session)) {
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+
+ if (switch_core_session_running(session) && !switch_channel_test_flag(channel, CF_PROXY_MODE)) {
switch_core_session_queue_signal_data(session, de);
} else {
switch_core_session_message_t msg = { 0 };
@@ -2077,8 +2080,10 @@ static su_log_t *sofia_get_logger(const char *name)
return soa_log;
} else if (!strcasecmp(name, "sresolv")) {
return sresolv_log;
+#ifdef HAVE_SOFIA_STUN
} else if (!strcasecmp(name, "stun")) {
return stun_log;
+#endif
} else if (!strcasecmp(name, "default")) {
return su_log_default;
} else {
@@ -2105,7 +2110,9 @@ switch_status_t sofia_set_loglevel(const char *name, int level)
su_log_set_level(nua_log, level);
su_log_set_level(soa_log, level);
su_log_set_level(sresolv_log, level);
+#ifdef HAVE_SOFIA_STUN
su_log_set_level(stun_log, level);
+#endif
return SWITCH_STATUS_SUCCESS;
}
@@ -2702,6 +2709,12 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
mod_sofia_globals.debug_sla = atoi(val);
} else if (!strcasecmp(var, "auto-restart")) {
mod_sofia_globals.auto_restart = switch_true(val);
+ } else if (!strcasecmp(var, "reg-deny-binding-fetch-and-no-lookup")) { /* backwards compatibility */
+ mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = switch_true(val); /* remove when noone complains about the extra lookup */
+ if (switch_true(val)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Enabling reg-deny-binding-fetch-and-no-lookup - this functionality is "
+ "deprecated and will be removed - let FS devs know if you think it should stay\n");
+ }
} else if (!strcasecmp(var, "rewrite-multicasted-fs-path")) {
if( (!strcasecmp(val, "to_host")) || (!strcasecmp(val, "1")) ) {
/* old behaviour */
@@ -3356,7 +3369,9 @@ switch_status_t config_sofia(int reload, char *profile_name)
su_log_redirect(nua_log, logger, NULL);
su_log_redirect(soa_log, logger, NULL);
su_log_redirect(sresolv_log, logger, NULL);
+#ifdef HAVE_SOFIA_STUN
su_log_redirect(stun_log, logger, NULL);
+#endif
}
if (!zstr(profile_name) && (profile = sofia_glue_find_profile(profile_name))) {
@@ -3377,6 +3392,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
}
mod_sofia_globals.auto_restart = SWITCH_TRUE;
+ mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = SWITCH_FALSE; /* handle backwards compatilibity - by default use new behavior */
mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE;
if ((settings = switch_xml_child(cfg, "global_settings"))) {
@@ -3393,6 +3409,12 @@ switch_status_t config_sofia(int reload, char *profile_name)
mod_sofia_globals.debug_sla = atoi(val);
} else if (!strcasecmp(var, "auto-restart")) {
mod_sofia_globals.auto_restart = switch_true(val);
+ } else if (!strcasecmp(var, "reg-deny-binding-fetch-and-no-lookup")) { /* backwards compatibility */
+ mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = switch_true(val); /* remove when noone complains about the extra lookup */
+ if (switch_true(val)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Enabling reg-deny-binding-fetch-and-no-lookup - this functionality is "
+ "deprecated and will be removed - let FS devs know if you think it should stay\n");
+ }
} else if (!strcasecmp(var, "rewrite-multicasted-fs-path")) {
if( (!strcasecmp(val, "to_host")) || (!strcasecmp(val, "1")) ) {
/* old behaviour */
@@ -6737,35 +6759,37 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
goto end;
}
- if (dtmf.digit && (tech_pvt->dtmf_type == DTMF_INFO ||
- sofia_test_pflag(tech_pvt->profile, PFLAG_LIBERAL_DTMF) || sofia_test_flag(tech_pvt, TFLAG_LIBERAL_DTMF))) {
- /* queue it up */
- switch_channel_queue_dtmf(channel, &dtmf);
+ if (dtmf.digit) {
+ if (tech_pvt->dtmf_type == DTMF_INFO ||
+ sofia_test_pflag(tech_pvt->profile, PFLAG_LIBERAL_DTMF) || sofia_test_flag(tech_pvt, TFLAG_LIBERAL_DTMF)) {
+ /* queue it up */
+ switch_channel_queue_dtmf(channel, &dtmf);
- /* print debug info */
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "INFO DTMF(%c)\n", dtmf.digit);
+ /* print debug info */
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "INFO DTMF(%c)\n", dtmf.digit);
- if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
- const char *uuid;
- switch_core_session_t *session_b;
+ if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
+ const char *uuid;
+ switch_core_session_t *session_b;
- if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) && (session_b = switch_core_session_locate(uuid))) {
- while (switch_channel_has_dtmf(channel)) {
- switch_dtmf_t idtmf = { 0, 0 };
- if (switch_channel_dequeue_dtmf(channel, &idtmf) == SWITCH_STATUS_SUCCESS) {
- switch_core_session_send_dtmf(session_b, &idtmf);
+ if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) && (session_b = switch_core_session_locate(uuid))) {
+ while (switch_channel_has_dtmf(channel)) {
+ switch_dtmf_t idtmf = { 0, 0 };
+ if (switch_channel_dequeue_dtmf(channel, &idtmf) == SWITCH_STATUS_SUCCESS) {
+ switch_core_session_send_dtmf(session_b, &idtmf);
+ }
}
+
+ switch_core_session_rwunlock(session_b);
}
-
- switch_core_session_rwunlock(session_b);
}
- }
- /* Send 200 OK response */
- nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
- } else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
- "IGNORE INFO DTMF(%c) (This channel was not configured to use INFO DTMF!)\n", dtmf.digit);
+ /* Send 200 OK response */
+ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
+ "IGNORE INFO DTMF(%c) (This channel was not configured to use INFO DTMF!)\n", dtmf.digit);
+ }
}
goto end;
}
diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index 006f002334..b7b139e52d 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -3989,7 +3989,6 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_
{
switch_t38_options_t *t38_options = switch_channel_get_private(tech_pvt->channel, "t38_options");
sdp_attribute_t *attr;
- const char *var;
if (!t38_options) {
t38_options = switch_core_session_alloc(tech_pvt->session, sizeof(switch_t38_options_t));
@@ -4069,20 +4068,8 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_
switch_channel_set_private(tech_pvt->channel, "t38_options", t38_options);
switch_channel_set_app_flag_key("T38", tech_pvt->channel, CF_APP_T38);
- if ((var = switch_channel_get_variable(tech_pvt->channel, "sip_execute_on_image"))) {
- char *app, *arg = NULL;
- app = switch_core_session_strdup(tech_pvt->session, var);
-
- if (strstr(app, "::")) {
- switch_core_session_execute_application_async(tech_pvt->session, app, arg);
- } else {
- if ((arg = strchr(app, ' '))) {
- *arg++ = '\0';
- }
-
- switch_core_session_execute_application(tech_pvt->session, app, arg);
- }
- }
+ switch_channel_execute_on(tech_pvt->channel, "sip_execute_on_image");
+ switch_channel_api_on(tech_pvt->channel, "sip_api_on_image");
return t38_options;
}
diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c
index 1d014aff80..e281903dd6 100644
--- a/src/mod/endpoints/mod_sofia/sofia_reg.c
+++ b/src/mod/endpoints/mod_sofia/sofia_reg.c
@@ -30,9 +30,10 @@
* Marcel Barbulescu
* David Knell <>
* Eliot Gable
+ * Leon de Rooij
*
*
- * sofia_ref.c -- SOFIA SIP Endpoint (registration code)
+ * sofia_reg.c -- SOFIA SIP Endpoint (registration code)
*
*/
#include "mod_sofia.h"
@@ -466,6 +467,39 @@ int sofia_reg_find_callback(void *pArg, int argc, char **argv, char **columnName
return cbt->matches == 1 ? 0 : 1;
}
+
+int sofia_reg_find_reg_with_positive_expires_callback(void *pArg, int argc, char **argv, char **columnNames)
+{
+ struct callback_t *cbt = (struct callback_t *) pArg;
+ sofia_destination_t *dst = NULL;
+ long int expires;
+ char *contact = NULL;
+
+ expires = atol(argv[1]) - 60 - (long) switch_epoch_time_now(NULL);
+
+ if (expires > 0) {
+ dst = sofia_glue_get_destination(argv[0]);
+ contact = switch_mprintf("<%s>;expires=%ld", dst->contact, expires);
+
+ if (!cbt->len) {
+ switch_console_push_match(&cbt->list, contact);
+ switch_safe_free(contact);
+ sofia_glue_free_destination(dst);
+ cbt->matches++;
+ return 0;
+ }
+
+ switch_copy_string(cbt->val, contact, cbt->len);
+ switch_safe_free(contact);
+ sofia_glue_free_destination(dst);
+ cbt->matches++;
+ return cbt->matches == 1 ? 0 : 1;
+ }
+
+ return 0;
+}
+
+
int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames)
{
sofia_profile_t *profile = (sofia_profile_t *) pArg;
@@ -875,6 +909,29 @@ switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *p
}
+switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_multi(sofia_profile_t *profile, const char *user, const char *host)
+{
+ struct callback_t cbt = { 0 };
+ char sql[512] = "";
+
+ if (!user) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Called with null user!\n");
+ return NULL;
+ }
+
+ if (host) {
+ switch_snprintf(sql, sizeof(sql), "select contact,expires from sip_registrations where sip_user='%s' and (sip_host='%s' or presence_hosts like '%%%s%%')",
+ user, host, host);
+ } else {
+ switch_snprintf(sql, sizeof(sql), "select contact,expires from sip_registrations where sip_user='%s'", user);
+ }
+
+ sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_find_reg_with_positive_expires_callback, &cbt);
+
+ return cbt.list;
+}
+
+
void sofia_reg_auth_challenge(sofia_profile_t *profile, nua_handle_t *nh, sofia_dispatch_event_t *de,
sofia_regtype_t regtype, const char *realm, int stale)
{
@@ -983,8 +1040,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
}
}
- /* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */
- switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL);
+ /* all callers must confirm that sip and sip->sip_request are not NULL */
+ switch_assert(sip != NULL && sip->sip_request != NULL);
sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
@@ -1032,7 +1089,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
sub_host = to_host;
}
- if (contact->m_url) {
+ if (contact && contact->m_url) {
const char *port = contact->m_url->url_port;
char new_port[25] = "";
const char *contact_host = contact->m_url->url_host;
@@ -1130,7 +1187,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (expires) {
exptime = expires->ex_delta;
- } else if (contact->m_expires) {
+ } else if (contact && contact->m_expires) {
exptime = atol(contact->m_expires);
}
@@ -1163,11 +1220,13 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
+ if (contact)
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", reg_desc);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
+ if (contact)
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-user", from_user);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-host", from_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "network-ip", network_ip);
@@ -1178,7 +1237,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_event_fire(&s_event);
}
- if (exptime && v_event && *v_event) {
+ if (contact && exptime && v_event && *v_event) {
char *exp_var;
char *allow_multireg = NULL;
int auto_connectile = 0;
@@ -1310,11 +1369,13 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
+ if (contact)
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", reg_desc);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
+ if (contact)
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-user", from_user);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-host", from_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "network-ip", network_ip);
@@ -1343,6 +1404,10 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_goto_int(r, 1, end);
}
+
+ if (!contact)
+ goto respond_200_ok;
+
reg:
@@ -1589,69 +1654,107 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
}
}
+ respond_200_ok:
if (regtype == REG_REGISTER) {
char exp_param[128] = "";
char date[80] = "";
switch_event_t *s_mwi_event = NULL;
+ switch_console_callback_match_t *contact_list = NULL;
+ tagi_t *contact_tags;
+ switch_console_callback_match_node_t *m;
+ int i;
+
s_event = NULL;
- if (exptime) {
- switch_snprintf(exp_param, sizeof(exp_param), "expires=%ld", exptime);
- sip_contact_add_param(nua_handle_home(nh), sip->sip_contact, exp_param);
+ if (contact) {
+ if (exptime) {
+ switch_snprintf(exp_param, sizeof(exp_param), "expires=%ld", exptime);
+ sip_contact_add_param(nua_handle_home(nh), sip->sip_contact, exp_param);
- if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) ||
- (reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) {
- if (switch_event_create(&s_mwi_event, SWITCH_EVENT_MESSAGE_QUERY) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(s_mwi_event, SWITCH_STACK_BOTTOM, "Message-Account", "sip:%s@%s", mwi_user, mwi_host);
- switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Sofia-Profile", profile->name);
- switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Call-ID", call_id);
- }
- }
-
- if (sofia_test_pflag(profile, PFLAG_PRESENCE_ON_REGISTER) ||
- (reg_count == 1 && sofia_test_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER))
- || send_pres == 1 || (reg_count == 1 && send_pres == 2)) {
-
- if (sofia_test_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)) {
- if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, sub_host);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence");
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
- switch_event_fire(&s_event);
+ if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) ||
+ (reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) {
+ if (switch_event_create(&s_mwi_event, SWITCH_EVENT_MESSAGE_QUERY) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header(s_mwi_event, SWITCH_STACK_BOTTOM, "Message-Account", "sip:%s@%s", mwi_user, mwi_host);
+ switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Sofia-Profile", profile->name);
+ switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Call-ID", call_id);
}
- } else {
- if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", "Registered");
- switch_event_fire(&s_event);
- }
}
- }
- } else {
- switch_core_del_registration(to_user, reg_host, call_id);
- if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_UNREGISTER) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
+ if (sofia_test_pflag(profile, PFLAG_PRESENCE_ON_REGISTER) ||
+ (reg_count == 1 && sofia_test_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER))
+ || send_pres == 1 || (reg_count == 1 && send_pres == 2)) {
+
+ if (sofia_test_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)) {
+ if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, sub_host);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
+ switch_event_fire(&s_event);
+ }
+ } else {
+ if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", "Registered");
+ switch_event_fire(&s_event);
+ }
+ }
+ }
+ } else {
+ switch_core_del_registration(to_user, reg_host, call_id);
+
+ if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_UNREGISTER) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);
+ }
}
}
switch_rfc822_date(date, switch_micro_time_now());
- nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact),
- TAG_IF(path_val, SIPTAG_PATH_STR(path_val)), NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_END());
+
+ /* generate and respond a 200 OK */
+
+ if (mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup) {
+ /* handle backwards compatibility - contacts will not be looked up but only copied from the request into the response
+ remove this condition later if nobody complains about the extra select of the below new behavior
+ also remove the parts in mod_sofia.h, sofia.c and sofia_reg.c that refer to reg_deny_binding_fetch_and_no_lookup */
+ nua_respond(nh, SIP_200_OK, TAG_IF(contact, SIPTAG_CONTACT(sip->sip_contact)), TAG_IF(path_val, SIPTAG_PATH_STR(path_val)),
+ NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_END());
+
+ } else if ((contact_list = sofia_reg_find_reg_url_with_positive_expires_multi(profile, from_user, reg_host))) {
+ /* all + 1 tag_i elements initialized as NULL - last one implies TAG_END() */
+ switch_zmalloc(contact_tags, sizeof(*contact_tags) * (contact_list->count + 1));
+ i = 0;
+ for (m = contact_list->head; m; m = m->next) {
+ contact_tags[i].t_tag = siptag_contact_str;
+ contact_tags[i].t_value = (tag_value_t) m->val;
+ ++i;
+ }
+
+ nua_respond(nh, SIP_200_OK, TAG_IF(path_val, SIPTAG_PATH_STR(path_val)),
+ NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_NEXT(contact_tags));
+
+ switch_safe_free(contact_tags);
+ switch_console_free_matches(&contact_list);
+
+ } else {
+ /* respond without any contacts */
+ nua_respond(nh, SIP_200_OK, TAG_IF(path_val, SIPTAG_PATH_STR(path_val)),
+ NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_END());
+ }
+
if (s_event) {
switch_event_fire(&s_event);
@@ -1661,7 +1764,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_event_fire(&s_mwi_event);
}
- if (*contact_str && sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE_SYLANTRO)) {
+ if (contact && *contact_str && sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE_SYLANTRO)) {
sofia_sla_handle_register(nua, profile, sip, de, exptime, contact_str);
}
@@ -1707,7 +1810,8 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
- if (!(sip->sip_contact && sip->sip_contact->m_url)) {
+ /* backwards compatibility */
+ if (mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup && !(sip->sip_contact && sip->sip_contact->m_url)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO CONTACT! ip: %s, port: %i\n", network_ip, network_port);
nua_respond(nh, 400, "Missing Contact Header", TAG_END());
goto end;
diff --git a/src/switch_channel.c b/src/switch_channel.c
index 4f272db7e2..0a6071105f 100644
--- a/src/switch_channel.c
+++ b/src/switch_channel.c
@@ -362,7 +362,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf(switch_channel_t *chan
{
switch_status_t status;
void *pop;
- switch_dtmf_t new_dtmf;
+ switch_dtmf_t new_dtmf = { 0 };
switch_assert(dtmf);
@@ -376,14 +376,17 @@ SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf(switch_channel_t *chan
if (is_dtmf(new_dtmf.digit)) {
switch_dtmf_t *dt;
int x = 0;
+ char str[2] = "";
+ str[0] = new_dtmf.digit;
+
if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) {
- switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n",
- switch_channel_get_name(channel), new_dtmf.digit, new_dtmf.duration);
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "%s EXCESSIVE DTMF DIGIT [%s] LEN [%d]\n",
+ switch_channel_get_name(channel), str, new_dtmf.duration);
new_dtmf.duration = switch_core_max_dtmf_duration(0);
} else if (new_dtmf.duration < switch_core_min_dtmf_duration(0)) {
- switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n",
- switch_channel_get_name(channel), new_dtmf.digit, new_dtmf.duration);
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "%s SHORT DTMF DIGIT [%s] LEN [%d]\n",
+ switch_channel_get_name(channel), str, new_dtmf.duration);
new_dtmf.duration = switch_core_min_dtmf_duration(0);
} else if (!new_dtmf.duration) {
new_dtmf.duration = switch_core_default_dtmf_duration(0);
@@ -1014,8 +1017,10 @@ SWITCH_DECLARE(void) switch_channel_process_export(switch_channel_t *channel, sw
const char *vval;
if ((vval = switch_channel_get_variable(channel, argv[x]))) {
char *vvar = argv[x];
- if (!strncasecmp(vvar, "nolocal:", 8)) {
+ if (!strncasecmp(vvar, "nolocal:", 8)) { /* remove this later ? */
vvar += 8;
+ } else if (!strncasecmp(vvar, "_nolocal_", 9)) {
+ vvar += 9;
}
if (var_event) {
switch_event_del_header(var_event, vvar);
@@ -1055,9 +1060,12 @@ SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_var_check(switch_
var = switch_core_session_strdup(channel->session, varname);
if (var) {
- if (!strncasecmp(var, "nolocal:", 8)) {
+ if (!strncasecmp(var, "nolocal:", 8)) { /* remove this later ? */
var_name = var + 8;
local = 0;
+ } else if (!strncasecmp(var, "_nolocal_", 9)) {
+ var_name = var + 9;
+ local = 0;
} else {
var_name = var;
}
@@ -2822,6 +2830,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_ring_ready_value(swi
}
switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE);
+ switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_RING_VARIABLE);
return SWITCH_STATUS_SUCCESS;
}
@@ -2869,7 +2878,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_
switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_PRE_ANSWER_VARIABLE);
switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE);
-
+ switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_PRE_ANSWER_VARIABLE);
+ switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_MEDIA_VARIABLE);
if ((var = switch_channel_get_variable(channel, SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE))) {
switch_channel_set_flag(channel, CF_PASSTHRU_PTIME_MISMATCH);
@@ -2961,43 +2971,108 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_ring_ready_value(switch_c
return status;
}
+static void do_api_on(switch_channel_t *channel, const char *variable)
+{
+ char *app;
+ char *arg = NULL;
+ switch_stream_handle_t stream = { 0 };
+
+ app = switch_core_session_strdup(channel->session, variable);
+
+ if ((arg = strchr(app, ' '))) {
+ *arg++ = '\0';
+ }
+
+ SWITCH_STANDARD_STREAM(stream);
+ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s process %s: %s(%s)\n%s\n",
+ channel->name, variable, app, switch_str_nil(arg), (char *) stream.data);
+ switch_api_execute(app, arg, NULL, &stream);
+ free(stream.data);
+}
+
+
+SWITCH_DECLARE(switch_status_t) switch_channel_api_on(switch_channel_t *channel, const char *variable_prefix)
+{
+ switch_event_header_t *hp;
+ switch_event_t *event;
+ int x = 0;
+
+
+ switch_channel_get_variables(channel, &event);
+
+ for (hp = event->headers; hp; hp = hp->next) {
+ char *var = hp->name;
+ char *val = hp->value;
+
+ if (!strncasecmp(var, variable_prefix, strlen(variable_prefix))) {
+ if (hp->idx) {
+ int i;
+ for (i = 0; i < hp->idx; i++) {
+ x++;
+ do_api_on(channel, hp->array[i]);
+ }
+ } else {
+ x++;
+ do_api_on(channel, val);
+ }
+ }
+ }
+
+ switch_event_destroy(&event);
+
+ return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
+}
+
+static void do_execute_on(switch_channel_t *channel, const char *variable)
+{
+ char *arg = NULL;
+ char *p;
+ int bg = 0;
+ char *app;
+
+ app = switch_core_session_strdup(channel->session, variable);
+
+ for(p = app; p && *p; p++) {
+ if (*p == ' ') {
+ *p++ = '\0';
+ arg = p;
+ break;
+ } else if (*p == ':' && (*(p+1) == ':')) {
+ bg++;
+ break;
+ }
+ }
+
+
+ if (bg) {
+ switch_core_session_execute_application_async(channel->session, app, arg);
+ } else {
+ switch_core_session_execute_application(channel->session, app, arg);
+ }
+}
+
SWITCH_DECLARE(switch_status_t) switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)
{
- switch_event_header_t *hi;
+ switch_event_header_t *hp;
switch_event_t *event;
int x = 0;
switch_channel_get_variables(channel, &event);
- for (hi = event->headers; hi; hi = hi->next) {
- char *var = hi->name;
- char *val = hi->value;
- char *app;
-
+ for (hp = event->headers; hp; hp = hp->next) {
+ char *var = hp->name;
+ char *val = hp->value;
+
if (!strncasecmp(var, variable_prefix, strlen(variable_prefix))) {
- char *arg = NULL;
- char *p;
- int bg = 0;
- x++;
-
- app = switch_core_session_strdup(channel->session, val);
-
- for(p = app; p && *p; p++) {
- if (*p == ' ') {
- *p++ = '\0';
- arg = p;
- break;
- } else if (*p == ':' && (*(p+1) == ':')) {
- bg++;
- break;
+ if (hp->idx) {
+ int i;
+ for (i = 0; i < hp->idx; i++) {
+ x++;
+ do_execute_on(channel, hp->array[i]);
}
- }
-
-
- if (bg) {
- switch_core_session_execute_application_async(channel->session, app, arg);
} else {
- switch_core_session_execute_application(channel->session, app, arg);
+ x++;
+ do_execute_on(channel, val);
}
}
}
@@ -3013,7 +3088,6 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_chan
const char *uuid;
switch_core_session_t *other_session;
const char *var;
- char *app;
switch_assert(channel != NULL);
@@ -3079,24 +3153,10 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_chan
if (!switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE);
+ switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_MEDIA_VARIABLE);
}
- if ((var = switch_channel_get_variable(channel, SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE)) && !zstr(var)) {
- switch_stream_handle_t stream = { 0 };
- char *arg = NULL;
-
- app = switch_core_session_strdup(channel->session, var);
- if ((arg = strchr(app, ' '))) {
- *arg++ = '\0';
- }
-
- SWITCH_STANDARD_STREAM(stream);
- switch_api_execute(app, arg, NULL, &stream);
-
- switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s api on answer: %s(%s)\n%s\n",
- channel->name, app, switch_str_nil(arg), (char *) stream.data);
- free(stream.data);
- }
+ switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE);
switch_channel_presence(channel, "unknown", "answered", NULL);
diff --git a/src/switch_core_file.c b/src/switch_core_file.c
index 58b63bdc4b..28f1172ff8 100644
--- a/src/switch_core_file.c
+++ b/src/switch_core_file.c
@@ -135,10 +135,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file,
switch_uuid_format(uuid_str, &uuid);
fh->spool_path = switch_core_sprintf(fh->memory_pool, "%s%s%s.%s", spool_path, SWITCH_PATH_SEPARATOR, uuid_str, ext);
+ } else {
+ fh->spool_path = NULL;
}
if (rhs) {
fh->handler = switch_core_strdup(fh->memory_pool, rhs);
+ } else {
+ fh->handler = NULL;
}
if (channels) {
diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c
index b23d082bdf..798e7c288f 100644
--- a/src/switch_core_sqldb.c
+++ b/src/switch_core_sqldb.c
@@ -996,7 +996,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread,
trans = 1;
}
- if (len + newlen > sql_len) {
+ if (len + newlen + 1 > sql_len) {
int new_mlen = len + newlen + 10240;
if (new_mlen < runtime.max_sql_buffer_len) {
@@ -1935,7 +1935,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
case SCDB_TYPE_ODBC:
{
char *err;
- switch_cache_db_test_reactive(dbh, "select call_uuid, read_bit_rate from channels", "DROP TABLE channels", create_channels_sql);
+ switch_cache_db_test_reactive(dbh, "select call_uuid, read_bit_rate, sent_callee_name from channels", "DROP TABLE channels", create_channels_sql);
switch_cache_db_test_reactive(dbh, "select * from detailed_calls where sent_callee_name=''", "DROP VIEW detailed_calls", detailed_calls_sql);
switch_cache_db_test_reactive(dbh, "select * from basic_calls where sent_callee_name=''", "DROP VIEW basic_calls", basic_calls_sql);
if (runtime.odbc_dbtype == DBTYPE_DEFAULT) {
diff --git a/src/switch_event.c b/src/switch_event.c
index b469b9f7b7..8265a18207 100644
--- a/src/switch_event.c
+++ b/src/switch_event.c
@@ -333,17 +333,11 @@ static void *SWITCH_THREAD_FUNC switch_event_thread(switch_thread_t *thread, voi
if (++loops > 2) {
- uint32_t last_sps = 0, sess_count = switch_core_session_count();
if (auto_pause) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Event system *still* overloading.\n");
} else {
- switch_core_session_ctl(SCSC_LAST_SPS, &last_sps);
- last_sps = (uint32_t) (float) (last_sps * 0.75f);
- sess_count = (uint32_t) (float) (sess_count * 0.75f);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
- "Event system overloading. Taking a 10 second break, Reducing max_sessions to %d %dsps\n", sess_count, last_sps);
- switch_core_session_limit(sess_count);
- switch_core_session_ctl(SCSC_SPS, &last_sps);
+ "Event system overloading. Taking a 10 second break\n");
auto_pause = 10;
switch_core_session_ctl(SCSC_PAUSE_INBOUND, &auto_pause);
}
diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c
index a47cfbd0c0..b55413f007 100644
--- a/src/switch_ivr_async.c
+++ b/src/switch_ivr_async.c
@@ -2458,6 +2458,8 @@ static switch_status_t tone_on_dtmf(switch_core_session_t *session, const switch
cont->list[i].callback(cont->session, cont->list[i].app, cont->list[i].data);
} else {
switch_channel_execute_on(switch_core_session_get_channel(cont->session), SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE);
+ switch_channel_api_on(switch_core_session_get_channel(cont->session), SWITCH_CHANNEL_API_ON_TONE_DETECT_VARIABLE);
+
if (cont->list[i].app) {
switch_core_session_execute_application_async(cont->session, cont->list[i].app, cont->list[i].data);
}
diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c
index 262d6d7a91..9ab1c1b1da 100644
--- a/src/switch_ivr_originate.c
+++ b/src/switch_ivr_originate.c
@@ -2561,7 +2561,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
switch_channel_set_variable(originate_status[i].peer_channel, "originating_leg_uuid", switch_core_session_get_uuid(session));
}
- switch_channel_execute_on(originate_status[i].peer_channel, "execute_on_originate");
+ switch_channel_execute_on(originate_status[i].peer_channel, SWITCH_CHANNEL_EXECUTE_ON_ORIGINATE_VARIABLE);
+ switch_channel_api_on(originate_status[i].peer_channel, SWITCH_CHANNEL_API_ON_ORIGINATE_VARIABLE);
}
if (table) {
diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c
index bc6ba62120..c5200d0e0e 100644
--- a/src/switch_ivr_play_say.c
+++ b/src/switch_ivr_play_say.c
@@ -377,7 +377,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
int divisor = 0;
int file_flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT;
int restart_limit_on_dtmf = 0;
- const char *prefix;
+ const char *prefix, *var;
prefix = switch_channel_get_variable(channel, "sound_prefix");
@@ -756,6 +756,29 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
switch_core_file_close(fh);
+
+ if ((var = switch_channel_get_variable(channel, "record_post_process_exec_api"))) {
+ char *cmd = switch_core_session_strdup(session, var);
+ char *data, *expanded = NULL;
+ switch_stream_handle_t stream = { 0 };
+
+ SWITCH_STANDARD_STREAM(stream);
+
+ if ((data = strchr(cmd, ':'))) {
+ *data++ = '\0';
+ expanded = switch_channel_expand_variables(channel, data);
+ }
+
+ switch_api_execute(cmd, expanded, session, &stream);
+
+ if (expanded && expanded != data) {
+ free(expanded);
+ }
+
+ switch_safe_free(stream.data);
+
+ }
+
if (read_impl.samples_per_second) {
switch_channel_set_variable_printf(channel, "record_seconds", "%d", fh->samples_out / read_impl.samples_per_second);
switch_channel_set_variable_printf(channel, "record_ms", "%d", fh->samples_out / (read_impl.samples_per_second / 1000));
diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c
index 8fca52eb58..007309781e 100644
--- a/src/switch_loadable_module.c
+++ b/src/switch_loadable_module.c
@@ -994,8 +994,8 @@ static switch_status_t switch_loadable_module_load_module_ex(char *dir, char *fn
switch_snprintf(path, len, "%s%s%s%s", dir, SWITCH_PATH_SEPARATOR, file, ext);
}
- switch_mutex_lock(loadable_modules.mutex);
- if (switch_core_hash_find(loadable_modules.module_hash, file)) {
+
+ if (switch_core_hash_find_locked(loadable_modules.module_hash, file, loadable_modules.mutex)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Module %s Already Loaded!\n", file);
*err = "Module already loaded";
status = SWITCH_STATUS_FALSE;
@@ -1010,7 +1010,7 @@ static switch_status_t switch_loadable_module_load_module_ex(char *dir, char *fn
} else {
*err = "module load file routine returned an error";
}
- switch_mutex_unlock(loadable_modules.mutex);
+
return status;