From acd56d2fe2a0458801010cc6b03c524023cbc597 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 22 Aug 2010 18:00:40 -0500 Subject: [PATCH 01/86] expose ASR start_input_timers on the IVR abstraction level --- src/include/switch_ivr.h | 8 ++++++++ src/switch_ivr_async.c | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 40ba1dc16f..692ad8d61b 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -26,6 +26,7 @@ * Anthony Minessale II * Neal Horman * Bret McDanel + * Luke Dashjr (OpenMethods, LLC) * * switch_ivr.h -- IVR Library * @@ -200,6 +201,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_unload_grammar(switch_c SWITCH_DECLARE(switch_status_t) switch_ivr_set_param_detect_speech(switch_core_session_t *session, const char *name, const char *val); +/*! + \brief Start input timers on a background speech detection handle + \param session The session to start the timers on + \return SWITCH_STATUS_SUCCESS if all is well +*/ +SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_start_input_timers(switch_core_session_t *session); + /*! \brief Record a session to disk \param session the session to record diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 4fe5732f82..ae23d0a9f4 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -26,6 +26,7 @@ * Anthony Minessale II * Michael Jerris * Bret McDanel + * Luke Dashjr (OpenMethods, LLC) * * switch_ivr_async.c -- IVR Library (async operations) * @@ -2728,6 +2729,18 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_set_param_detect_speech(switch_core_s return status; } +SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_start_input_timers(switch_core_session_t *session) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY); + + if (sth) { + switch_core_asr_start_input_timers(sth->ah); + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_unload_grammar(switch_core_session_t *session, const char *name) { switch_channel_t *channel = switch_core_session_get_channel(session); From d395b654fb0abab4889d5b8c239728683e772959 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 22 Aug 2010 18:07:24 -0500 Subject: [PATCH 02/86] expose ASR start_input_timers to dialplan via mod_dptools --- src/mod/applications/mod_dptools/mod_dptools.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 5a1b8c5d14..2f496300e8 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -28,6 +28,7 @@ * Michael Murdock * Neal Horman * Bret McDanel + * Luke Dashjr (OpenMethods, LLC) * * mod_dptools.c -- Raw Audio File Streaming Application Module * @@ -95,7 +96,7 @@ SWITCH_STANDARD_DIALPLAN(inline_dialplan_hunt) return extension; } -#define DETECT_SPEECH_SYNTAX " [] OR grammar [] OR pause OR resume" +#define DETECT_SPEECH_SYNTAX " [] OR grammar [] OR pause OR resume OR start_input_timers" SWITCH_STANDARD_APP(detect_speech_function) { char *argv[4]; @@ -116,6 +117,8 @@ SWITCH_STANDARD_APP(detect_speech_function) switch_ivr_stop_detect_speech(session); } else if (!strcasecmp(argv[0], "param")) { switch_ivr_set_param_detect_speech(session, argv[1], argv[2]); + } else if (!strcasecmp(argv[0], "start_input_timers")) { + switch_ivr_detect_speech_start_input_timers(session); } else if (argc >= 3) { switch_ivr_detect_speech(session, argv[0], argv[1], argv[2], argv[3], NULL); } From 439df43cae04a053a1c22befdd7f1009f6cb6dfa Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 22 Aug 2010 18:17:36 -0500 Subject: [PATCH 03/86] document all of detect_speech's valid syntax --- src/mod/applications/mod_dptools/mod_dptools.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 5a1b8c5d14..6d014faf41 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -28,6 +28,7 @@ * Michael Murdock * Neal Horman * Bret McDanel + * Luke Dashjr (OpenMethods, LLC) * * mod_dptools.c -- Raw Audio File Streaming Application Module * @@ -95,7 +96,7 @@ SWITCH_STANDARD_DIALPLAN(inline_dialplan_hunt) return extension; } -#define DETECT_SPEECH_SYNTAX " [] OR grammar [] OR pause OR resume" +#define DETECT_SPEECH_SYNTAX " [] OR grammar [] OR nogrammar OR pause OR resume OR stop OR param " SWITCH_STANDARD_APP(detect_speech_function) { char *argv[4]; From e719ae662b7cb08ebd7f8e732a140e9aeb502960 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 21 Aug 2010 17:44:42 -0500 Subject: [PATCH 04/86] Allow loading grammars without sending RECOGNIZE with start-recognize=false parameter --- src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c index 41c0ccdaa4..a27ddf01a2 100644 --- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c +++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c @@ -26,6 +26,7 @@ * * Brian West * Christopher M. Rienzo + * Luke Dashjr (OpenMethods, LLC) * * mod_unimrcp.c -- UniMRCP module (MRCP client) * @@ -2451,6 +2452,8 @@ static switch_status_t recog_channel_set_params(speech_channel_t *schannel, mrcp if (id) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) \"%s\": \"%s\"\n", schannel->name, param_name, param_val); recog_channel_set_header(schannel, id->id, param_val, msg, recog_hdr); + } else if (!strcasecmp(param_name, "start-recognize")) { + // This parameter is used internally only, not in MRCP headers } else { /* this is probably a vendor-specific MRCP param */ apt_str_t apt_param_name = { 0 }; @@ -2782,6 +2785,7 @@ static switch_status_t recog_asr_load_grammar(switch_asr_handle_t *ah, const cha speech_channel_t *schannel = (speech_channel_t *) ah->private_info; const char *grammar_data = NULL; char *grammar_file_data = NULL; + char *start_recognize; switch_file_t *grammar_file = NULL; switch_size_t grammar_file_size = 0, to_read = 0; grammar_type_t type = GRAMMAR_TYPE_UNKNOWN; @@ -2886,7 +2890,9 @@ static switch_status_t recog_asr_load_grammar(switch_asr_handle_t *ah, const cha goto done; } - status = recog_channel_start(schannel, name); + start_recognize = (char *) switch_core_hash_find(schannel->params, "start-recognize"); + if (zstr(start_recognize) || strcasecmp(start_recognize, "false")) + status = recog_channel_start(schannel, name); done: From 4cbdfbe481d7f9b448663418dccc88b017f9ce69 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 21 Aug 2010 19:43:53 -0500 Subject: [PATCH 05/86] switch_core_asr interfaces for enable_grammar, disable_grammar, and disable_all_grammars --- src/include/switch_core.h | 24 ++++++++++++++++ src/include/switch_module_interfaces.h | 7 +++++ src/switch_core_asr.c | 40 ++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 650ffc15fb..26a048cdb2 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -24,6 +24,7 @@ * Contributor(s): * * Anthony Minessale II + * Luke Dashjr (OpenMethods, LLC) * * * switch_core.h -- Core Library @@ -1747,6 +1748,29 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_load_grammar(switch_asr_handle_t */ SWITCH_DECLARE(switch_status_t) switch_core_asr_unload_grammar(switch_asr_handle_t *ah, const char *name); +/*! + \brief Enable a grammar from an asr handle + \param ah the handle to enable the grammar from + \param name the name of the grammar to enable + \return SWITCH_STATUS_SUCCESS +*/ +SWITCH_DECLARE(switch_status_t) switch_core_asr_enable_grammar(switch_asr_handle_t *ah, const char *name); + +/*! + \brief Disable a grammar from an asr handle + \param ah the handle to disable the grammar from + \param name the name of the grammar to disable + \return SWITCH_STATUS_SUCCESS +*/ +SWITCH_DECLARE(switch_status_t) switch_core_asr_disable_grammar(switch_asr_handle_t *ah, const char *name); + +/*! + \brief Disable all grammars from an asr handle + \param ah the handle to disable the grammars from + \return SWITCH_STATUS_SUCCESS +*/ +SWITCH_DECLARE(switch_status_t) switch_core_asr_disable_all_grammars(switch_asr_handle_t *ah); + /*! \brief Pause detection on an asr handle \param ah the handle to pause diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 078b83d2fd..e0119b4d15 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -24,6 +24,7 @@ * Contributor(s): * * Anthony Minessale II + * Luke Dashjr (OpenMethods, LLC) * * * switch_module_interfaces.h -- Module Interface Definitions @@ -393,6 +394,12 @@ struct switch_asr_interface { switch_mutex_t *reflock; switch_loadable_module_interface_t *parent; struct switch_asr_interface *next; + /*! function to enable a grammar to the asr interface */ + switch_status_t (*asr_enable_grammar) (switch_asr_handle_t *ah, const char *name); + /*! function to disable a grammar to the asr interface */ + switch_status_t (*asr_disable_grammar) (switch_asr_handle_t *ah, const char *name); + /*! function to disable all grammars to the asr interface */ + switch_status_t (*asr_disable_all_grammars) (switch_asr_handle_t *ah); }; /*! an abstract representation of an asr speech interface. */ diff --git a/src/switch_core_asr.c b/src/switch_core_asr.c index fa4446ec46..691011a285 100644 --- a/src/switch_core_asr.c +++ b/src/switch_core_asr.c @@ -27,6 +27,7 @@ * Michael Jerris * Paul D. Tinsley * Christopher M. Rienzo + * Luke Dashjr (OpenMethods, LLC) * * * switch_core_asr.c -- Main Core Library (Speech Detection Interface) @@ -160,6 +161,45 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_unload_grammar(switch_asr_handle return status; } +SWITCH_DECLARE(switch_status_t) switch_core_asr_enable_grammar(switch_asr_handle_t *ah, const char *name) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + + switch_assert(ah != NULL); + + if (ah->asr_interface->asr_enable_grammar) { + status = ah->asr_interface->asr_enable_grammar(ah, name); + } + + return status; +} + +SWITCH_DECLARE(switch_status_t) switch_core_asr_disable_grammar(switch_asr_handle_t *ah, const char *name) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + + switch_assert(ah != NULL); + + if (ah->asr_interface->asr_disable_grammar) { + status = ah->asr_interface->asr_disable_grammar(ah, name); + } + + return status; +} + +SWITCH_DECLARE(switch_status_t) switch_core_asr_disable_all_grammars(switch_asr_handle_t *ah) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + + switch_assert(ah != NULL); + + if (ah->asr_interface->asr_disable_all_grammars) { + status = ah->asr_interface->asr_disable_all_grammars(ah); + } + + return status; +} + SWITCH_DECLARE(switch_status_t) switch_core_asr_pause(switch_asr_handle_t *ah) { switch_assert(ah != NULL); From 128d53c2e6a73a6136efcfffa4e880e6635e43f1 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 21 Aug 2010 19:46:35 -0500 Subject: [PATCH 06/86] Implement UniMRCP asr_enable_grammar, asr_disable_grammar, and asr_disable_all_grammars which allow for multiple grammar recognition --- src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c | 234 +++++++++++++++++++--- 1 file changed, 208 insertions(+), 26 deletions(-) diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c index a27ddf01a2..b9cecd10bc 100644 --- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c +++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c @@ -434,8 +434,8 @@ static const char *grammar_type_to_mime(grammar_type_t type, profile_t *profile) struct recognizer_data { /** the available grammars */ switch_hash_t *grammars; - /** the last grammar used (for pause/resume) */ - grammar_t *last_grammar; + /** the enabled grammars */ + switch_hash_t *enabled_grammars; /** recognize result */ char *result; /** true, if voice has started */ @@ -452,6 +452,9 @@ static switch_status_t recog_shutdown(); static switch_status_t recog_asr_open(switch_asr_handle_t *ah, const char *codec, int rate, const char *dest, switch_asr_flag_t *flags); static switch_status_t recog_asr_load_grammar(switch_asr_handle_t *ah, const char *grammar, const char *name); static switch_status_t recog_asr_unload_grammar(switch_asr_handle_t *ah, const char *name); +static switch_status_t recog_asr_enable_grammar(switch_asr_handle_t *ah, const char *name); +static switch_status_t recog_asr_disable_grammar(switch_asr_handle_t *ah, const char *name); +static switch_status_t recog_asr_disable_all_grammars(switch_asr_handle_t *ah); static switch_status_t recog_asr_close(switch_asr_handle_t *ah, switch_asr_flag_t *flags); static switch_status_t recog_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags); #if 0 @@ -472,9 +475,12 @@ static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp static apt_bool_t recog_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *frame); /* recognizer specific speech_channel_funcs */ -static switch_status_t recog_channel_start(speech_channel_t *schannel, const char *name); +static switch_status_t recog_channel_start(speech_channel_t *schannel); static switch_status_t recog_channel_load_grammar(speech_channel_t *schannel, const char *name, grammar_type_t type, const char *data); static switch_status_t recog_channel_unload_grammar(speech_channel_t *schannel, const char *name); +static switch_status_t recog_channel_enable_grammar(speech_channel_t *schannel, const char *name); +static switch_status_t recog_channel_disable_grammar(speech_channel_t *schannel, const char *name); +static switch_status_t recog_channel_disable_all_grammars(speech_channel_t *schannel); static switch_status_t recog_channel_check_results(speech_channel_t *schannel); static switch_status_t recog_channel_set_start_of_input(speech_channel_t *schannel); static switch_status_t recog_channel_start_input_timers(speech_channel_t *schannel); @@ -2056,19 +2062,24 @@ static const char *grammar_type_to_mime(grammar_type_t type, profile_t *profile) * Start RECOGNIZE request * * @param schannel the channel to start - * @param name the name of the grammar to use or NULL if to reuse the last grammar * @return SWITCH_STATUS_SUCCESS if successful */ -static switch_status_t recog_channel_start(speech_channel_t *schannel, const char *name) +static switch_status_t recog_channel_start(speech_channel_t *schannel) { switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_hash_index_t *egk; mrcp_message_t *mrcp_message; mrcp_recog_header_t *recog_header; mrcp_generic_header_t *generic_header; recognizer_data_t *r; char *start_input_timers; const char *mime_type; - grammar_t *grammar = NULL; + char *key; + switch_size_t len; + grammar_t *grammar; + switch_size_t grammar_uri_count = 0; + switch_size_t grammar_uri_list_len = 0; + char *grammar_uri_list = NULL; switch_mutex_lock(schannel->mutex); if (schannel->state != SPEECH_CHANNEL_READY) { @@ -2089,21 +2100,55 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel, const cha start_input_timers = (char *) switch_core_hash_find(schannel->params, "start-input-timers"); r->timers_started = zstr(start_input_timers) || strcasecmp(start_input_timers, "false"); - /* get the cached grammar */ - if (zstr(name)) { - grammar = r->last_grammar; - } else { - grammar = (grammar_t *) switch_core_hash_find(r->grammars, name); - r->last_grammar = grammar; - } - if (grammar == NULL) { - if (name) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Undefined grammar, %s\n", schannel->name, name); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) No grammar specified\n", schannel->name); + /* count enabled grammars */ + for (egk = switch_hash_first(NULL, r->enabled_grammars); egk; egk = switch_hash_next(egk)) { + // NOTE: This postponed type check is necessary to allow a non-URI-list grammar to execute alone + if (grammar_uri_count == 1 && grammar->type != GRAMMAR_TYPE_URI) + goto no_grammar_alone; + ++grammar_uri_count; + switch_hash_this(egk, (void *) &key, NULL, (void *) &grammar); + if (grammar->type != GRAMMAR_TYPE_URI && grammar_uri_count != 1) { + no_grammar_alone: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Grammar '%s' can only be used alone (not a URI list)\n", schannel->name, key); + status = SWITCH_STATUS_FALSE; + goto done; } + len = strlen(grammar->data); + if (!len) + continue; + grammar_uri_list_len += len; + if (grammar->data[len - 1] != '\n') + grammar_uri_list_len += 2; + } + + switch (grammar_uri_count) { + case 0: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) No grammar specified\n", schannel->name); status = SWITCH_STATUS_FALSE; goto done; + case 1: + /* grammar should already be the unique grammar */ + break; + default: + /* get the enabled grammars list */ + grammar_uri_list = switch_core_alloc(schannel->memory_pool, grammar_uri_list_len + 1); + grammar_uri_list_len = 0; + for (egk = switch_hash_first(NULL, r->enabled_grammars); egk; egk = switch_hash_next(egk)) { + switch_hash_this(egk, (void *) &key, NULL, (void *) &grammar); + len = strlen(grammar->data); + if (!len) + continue; + memcpy(&(grammar_uri_list[grammar_uri_list_len]), grammar->data, len); + grammar_uri_list_len += len; + if (grammar_uri_list[grammar_uri_list_len - 1] != '\n') + { + grammar_uri_list_len += 2; + grammar_uri_list[grammar_uri_list_len - 2] = '\r'; + grammar_uri_list[grammar_uri_list_len - 1] = '\n'; + } + } + grammar_uri_list[grammar_uri_list_len++] = '\0'; + grammar = NULL; } /* create MRCP message */ @@ -2121,7 +2166,7 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel, const cha } /* set Content-Type */ - mime_type = grammar_type_to_mime(grammar->type, schannel->profile); + mime_type = grammar_type_to_mime(grammar ? grammar->type : GRAMMAR_TYPE_URI, schannel->profile); if (zstr(mime_type)) { status = SWITCH_STATUS_FALSE; goto done; @@ -2130,7 +2175,7 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel, const cha mrcp_generic_header_property_add(mrcp_message, GENERIC_HEADER_CONTENT_TYPE); /* set Content-ID for inline grammars */ - if (grammar->type != GRAMMAR_TYPE_URI) { + if (grammar && grammar->type != GRAMMAR_TYPE_URI) { apt_string_assign(&generic_header->content_id, grammar->name, mrcp_message->pool); mrcp_generic_header_property_add(mrcp_message, GENERIC_HEADER_CONTENT_ID); } @@ -2152,7 +2197,7 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel, const cha recog_channel_set_params(schannel, mrcp_message, generic_header, recog_header); /* set message body */ - apt_string_assign(&mrcp_message->body, grammar->data, mrcp_message->pool); + apt_string_assign(&mrcp_message->body, grammar ? grammar->data : grammar_uri_list, mrcp_message->pool); /* Empty audio queue and send RECOGNIZE to MRCP server */ audio_queue_clear(schannel->audio_queue); @@ -2287,12 +2332,84 @@ static switch_status_t recog_channel_unload_grammar(speech_channel_t *schannel, } else { recognizer_data_t *r = (recognizer_data_t *) schannel->data; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Unloading grammar %s\n", schannel->name, grammar_name); + switch_core_hash_delete(r->enabled_grammars, grammar_name); switch_core_hash_delete(r->grammars, grammar_name); } return status; } +/** + * Enable speech recognition grammar + * + * @param schannel the recognizer channel + * @param grammar_name the name of the grammar to enable + * @return SWITCH_STATUS_SUCCESS if successful + */ +static switch_status_t recog_channel_enable_grammar(speech_channel_t *schannel, const char *grammar_name) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (zstr(grammar_name)) { + status = SWITCH_STATUS_FALSE; + } else { + recognizer_data_t *r = (recognizer_data_t *) schannel->data; + grammar_t *grammar; + grammar = (grammar_t *) switch_core_hash_find(r->grammars, grammar_name); + if (grammar == NULL) + { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Undefined grammar, %s\n", schannel->name, grammar_name); + status = SWITCH_STATUS_FALSE; + } + else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Enabling grammar %s\n", schannel->name, grammar_name); + switch_core_hash_insert(r->enabled_grammars, grammar_name, grammar); + } + } + + return status; +} + +/** + * Disable speech recognition grammar + * + * @param schannel the recognizer channel + * @param grammar_name the name of the grammar to disable + * @return SWITCH_STATUS_SUCCESS if successful + */ +static switch_status_t recog_channel_disable_grammar(speech_channel_t *schannel, const char *grammar_name) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (zstr(grammar_name)) { + status = SWITCH_STATUS_FALSE; + } else { + recognizer_data_t *r = (recognizer_data_t *) schannel->data; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Disabling grammar %s\n", schannel->name, grammar_name); + switch_core_hash_delete(r->enabled_grammars, grammar_name); + } + + return status; +} + +/** + * Disable all speech recognition grammars + * + * @param schannel the recognizer channel + * @return SWITCH_STATUS_SUCCESS if successful + */ +static switch_status_t recog_channel_disable_all_grammars(speech_channel_t *schannel) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + + recognizer_data_t *r = (recognizer_data_t *) schannel->data; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Disabling all grammars\n", schannel->name); + switch_core_hash_destroy(&r->enabled_grammars); + switch_core_hash_init(&r->enabled_grammars, schannel->memory_pool); + + return status; +} + /** * Check if recognition is complete * @@ -2740,6 +2857,7 @@ static switch_status_t recog_asr_open(switch_asr_handle_t *ah, const char *codec schannel->data = r; memset(r, 0, sizeof(recognizer_data_t)); switch_core_hash_init(&r->grammars, ah->memory_pool); + switch_core_hash_init(&r->enabled_grammars, ah->memory_pool); /* Open the channel */ if (zstr(profile_name)) { @@ -2892,7 +3010,17 @@ static switch_status_t recog_asr_load_grammar(switch_asr_handle_t *ah, const cha start_recognize = (char *) switch_core_hash_find(schannel->params, "start-recognize"); if (zstr(start_recognize) || strcasecmp(start_recognize, "false")) - status = recog_channel_start(schannel, name); + { + if (recog_channel_disable_all_grammars(schannel) != SWITCH_STATUS_SUCCESS) { + status = SWITCH_STATUS_FALSE; + goto done; + } + if (recog_channel_enable_grammar(schannel, name) != SWITCH_STATUS_SUCCESS) { + status = SWITCH_STATUS_FALSE; + goto done; + } + status = recog_channel_start(schannel); + } done: @@ -2920,6 +3048,57 @@ static switch_status_t recog_asr_unload_grammar(switch_asr_handle_t *ah, const c return status; } +/** + * Process asr_enable_grammar request from FreeSWITCH. + * + * FreeSWITCH sends this request to enable recognition on this grammar. + * @param ah the FreeSWITCH speech recognition handle + * @param name the grammar name. + */ +static switch_status_t recog_asr_enable_grammar(switch_asr_handle_t *ah, const char *name) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + speech_channel_t *schannel = (speech_channel_t *) ah->private_info; + if (zstr(name) || speech_channel_stop(schannel) != SWITCH_STATUS_SUCCESS || recog_channel_enable_grammar(schannel, name) != SWITCH_STATUS_SUCCESS) { + status = SWITCH_STATUS_FALSE; + } + return status; +} + +/** + * Process asr_disable_grammar request from FreeSWITCH. + * + * FreeSWITCH sends this request to disable recognition on this grammar. + * @param ah the FreeSWITCH speech recognition handle + * @param name the grammar name. + */ +static switch_status_t recog_asr_disable_grammar(switch_asr_handle_t *ah, const char *name) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + speech_channel_t *schannel = (speech_channel_t *) ah->private_info; + if (zstr(name) || speech_channel_stop(schannel) != SWITCH_STATUS_SUCCESS || recog_channel_disable_grammar(schannel, name) != SWITCH_STATUS_SUCCESS) { + status = SWITCH_STATUS_FALSE; + } + return status; +} + +/** + * Process asr_disable_all_grammars request from FreeSWITCH. + * + * FreeSWITCH sends this request to disable recognition of all grammars. + * @param ah the FreeSWITCH speech recognition handle + * @param name the grammar name. + */ +static switch_status_t recog_asr_disable_all_grammars(switch_asr_handle_t *ah) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + speech_channel_t *schannel = (speech_channel_t *) ah->private_info; + if (speech_channel_stop(schannel) != SWITCH_STATUS_SUCCESS || recog_channel_disable_all_grammars(schannel) != SWITCH_STATUS_SUCCESS) { + status = SWITCH_STATUS_FALSE; + } + return status; +} + /** * Process asr_close request from FreeSWITCH * @@ -2934,6 +3113,7 @@ static switch_status_t recog_asr_close(switch_asr_handle_t *ah, switch_asr_flag_ speech_channel_stop(schannel); speech_channel_destroy(schannel); switch_core_hash_destroy(&r->grammars); + switch_core_hash_destroy(&r->enabled_grammars); /* this lets FreeSWITCH's speech_thread know the handle is closed */ switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED); @@ -2958,14 +3138,13 @@ static switch_status_t recog_asr_feed(switch_asr_handle_t *ah, void *data, unsig /** * Process asr_start request from FreeSWITCH * @param ah the FreeSWITCH speech recognition handle - * @param name name of the grammar to use * @return SWITCH_STATUS_SUCCESS if successful */ -static switch_status_t recog_asr_start(switch_asr_handle_t *ah, const char *name) +static switch_status_t recog_asr_start(switch_asr_handle_t *ah) { switch_status_t status; speech_channel_t *schannel = (speech_channel_t *) ah->private_info; - status = recog_channel_start(schannel, name); + status = recog_channel_start(schannel); return status; } #endif @@ -2978,7 +3157,7 @@ static switch_status_t recog_asr_start(switch_asr_handle_t *ah, const char *name static switch_status_t recog_asr_resume(switch_asr_handle_t *ah) { speech_channel_t *schannel = (speech_channel_t *) ah->private_info; - return recog_channel_start(schannel, NULL); + return recog_channel_start(schannel); } /** @@ -3237,6 +3416,9 @@ static switch_status_t recog_load(switch_loadable_module_interface_t *module_int asr_interface->asr_open = recog_asr_open; asr_interface->asr_load_grammar = recog_asr_load_grammar; asr_interface->asr_unload_grammar = recog_asr_unload_grammar; + asr_interface->asr_enable_grammar = recog_asr_enable_grammar; + asr_interface->asr_disable_grammar = recog_asr_disable_grammar; + asr_interface->asr_disable_all_grammars = recog_asr_disable_all_grammars; asr_interface->asr_close = recog_asr_close; asr_interface->asr_feed = recog_asr_feed; #if 0 From 6d7e019b5c0244f53c16361d2667049b430adb55 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 22 Aug 2010 00:26:21 -0500 Subject: [PATCH 07/86] switch_ivr interfaces to enable/disable grammar: switch_ivr_detect_speech_enable_grammar, switch_ivr_detect_speech_disable_grammar, and switch_ivr_detect_speech_disable_all_grammars --- src/include/switch_ivr.h | 24 +++++++++++++++++++ src/switch_ivr_async.c | 52 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 40ba1dc16f..8641766760 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -26,6 +26,7 @@ * Anthony Minessale II * Neal Horman * Bret McDanel + * Luke Dashjr (OpenMethods, LLC) * * switch_ivr.h -- IVR Library * @@ -198,6 +199,29 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_load_grammar(switch_cor */ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_unload_grammar(switch_core_session_t *session, const char *name); +/*! + \brief Enable a grammar on a background speech detection handle + \param session The session to change the grammar on + \param name the grammar name + \return SWITCH_STATUS_SUCCESS if all is well +*/ +SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_enable_grammar(switch_core_session_t *session, const char *name); + +/*! + \brief Disable a grammar on a background speech detection handle + \param session The session to change the grammar on + \param name the grammar name + \return SWITCH_STATUS_SUCCESS if all is well +*/ +SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_disable_grammar(switch_core_session_t *session, const char *name); + +/*! + \brief Disable all grammars on a background speech detection handle + \param session The session to change the grammar on + \return SWITCH_STATUS_SUCCESS if all is well +*/ +SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_disable_all_grammars(switch_core_session_t *session); + SWITCH_DECLARE(switch_status_t) switch_ivr_set_param_detect_speech(switch_core_session_t *session, const char *name, const char *val); /*! diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 4fe5732f82..672750a4c3 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -26,6 +26,7 @@ * Anthony Minessale II * Michael Jerris * Bret McDanel + * Luke Dashjr (OpenMethods, LLC) * * switch_ivr_async.c -- IVR Library (async operations) * @@ -2745,6 +2746,57 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_unload_grammar(switch_c return SWITCH_STATUS_FALSE; } +SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_enable_grammar(switch_core_session_t *session, const char *name) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE; + struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY); + switch_status_t status; + + if (sth) { + if ((status = switch_core_asr_enable_grammar(sth->ah, name)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error enabling Grammar\n"); + switch_core_asr_close(sth->ah, &flags); + } + return status; + } + return SWITCH_STATUS_FALSE; +} + +SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_disable_grammar(switch_core_session_t *session, const char *name) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE; + struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY); + switch_status_t status; + + if (sth) { + if ((status = switch_core_asr_disable_grammar(sth->ah, name)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error disabling Grammar\n"); + switch_core_asr_close(sth->ah, &flags); + } + return status; + } + return SWITCH_STATUS_FALSE; +} + +SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_disable_all_grammars(switch_core_session_t *session) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE; + struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY); + switch_status_t status; + + if (sth) { + if ((status = switch_core_asr_disable_all_grammars(sth->ah)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error disabling all Grammars\n"); + switch_core_asr_close(sth->ah, &flags); + } + return status; + } + return SWITCH_STATUS_FALSE; +} + SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech(switch_core_session_t *session, const char *mod_name, const char *grammar, const char *name, const char *dest, switch_asr_handle_t *ah) From 0f39c8f9c3d8e8bce05c551e0168e476ce29437a Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 22 Aug 2010 18:12:18 -0500 Subject: [PATCH 08/86] expose ASR enable/disable grammar (and disable all grammars) to dialplan via mod_dptools --- src/mod/applications/mod_dptools/mod_dptools.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 5a1b8c5d14..e942bc612d 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -28,6 +28,7 @@ * Michael Murdock * Neal Horman * Bret McDanel + * Luke Dashjr (OpenMethods, LLC) * * mod_dptools.c -- Raw Audio File Streaming Application Module * @@ -95,7 +96,7 @@ SWITCH_STANDARD_DIALPLAN(inline_dialplan_hunt) return extension; } -#define DETECT_SPEECH_SYNTAX " [] OR grammar [] OR pause OR resume" +#define DETECT_SPEECH_SYNTAX " [] OR grammar [] OR pause OR resume OR grammaron/grammaroff OR grammarsalloff" SWITCH_STANDARD_APP(detect_speech_function) { char *argv[4]; @@ -108,6 +109,12 @@ SWITCH_STANDARD_APP(detect_speech_function) switch_ivr_detect_speech_load_grammar(session, argv[1], argv[2]); } else if (!strcasecmp(argv[0], "nogrammar")) { switch_ivr_detect_speech_unload_grammar(session, argv[1]); + } else if (!strcasecmp(argv[0], "grammaron")) { + switch_ivr_detect_speech_enable_grammar(session, argv[1]); + } else if (!strcasecmp(argv[0], "grammaroff")) { + switch_ivr_detect_speech_disable_grammar(session, argv[1]); + } else if (!strcasecmp(argv[0], "grammarsalloff")) { + switch_ivr_detect_speech_disable_all_grammars(session); } else if (!strcasecmp(argv[0], "pause")) { switch_ivr_pause_detect_speech(session); } else if (!strcasecmp(argv[0], "resume")) { From 15e65cfafb8a46caca8bb8a63d55edf817f17f2d Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 26 Jan 2011 14:40:35 -0600 Subject: [PATCH 09/86] MERGE: DTMF recognition via ASR modules (implemented in UniMRCP) --- src/include/switch_core.h | 9 +++ src/include/switch_module_interfaces.h | 2 + src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c | 73 ++++++++++++++++++++++- src/switch_core_asr.c | 13 ++++ src/switch_ivr_async.c | 19 ++++++ 5 files changed, 115 insertions(+), 1 deletion(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 26a048cdb2..a3d74e97b3 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1714,6 +1714,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_close(switch_asr_handle_t *ah, s */ SWITCH_DECLARE(switch_status_t) switch_core_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags); +/*! + \brief Feed DTMF to an asr handle + \param ah the handle to feed data to + \param dtmf a string of DTMF digits + \param flags flags to influence behaviour + \return SWITCH_STATUS_SUCCESS +*/ +SWITCH_DECLARE(switch_status_t) switch_core_asr_feed_dtmf(switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags); + /*! \brief Check an asr handle for results \param ah the handle to check diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index e0119b4d15..8303af75de 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -400,6 +400,8 @@ struct switch_asr_interface { switch_status_t (*asr_disable_grammar) (switch_asr_handle_t *ah, const char *name); /*! function to disable all grammars to the asr interface */ switch_status_t (*asr_disable_all_grammars) (switch_asr_handle_t *ah); + /*! function to feed DTMF to the ASR */ + switch_status_t (*asr_feed_dtmf) (switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags); }; /*! an abstract representation of an asr speech interface. */ diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c index b9cecd10bc..b3679cf516 100644 --- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c +++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c @@ -49,6 +49,7 @@ #include "mrcp_resource_loader.h" #include "mpf_engine.h" #include "mpf_codec_manager.h" +#include "mpf_dtmf_generator.h" #include "mpf_rtp_termination_factory.h" #include "mrcp_sofiasip_client_agent.h" #include "mrcp_unirtsp_client_agent.h" @@ -442,6 +443,12 @@ struct recognizer_data { int start_of_input; /** true, if input timers have started */ int timers_started; + /** UniMRCP mpf stream */ + mpf_audio_stream_t *unimrcp_stream; + /** DTMF generator */ + mpf_dtmf_generator_t *dtmf_generator; + /** true, if presently transmitting DTMF */ + char dtmf_generator_active; }; typedef struct recognizer_data recognizer_data_t; @@ -457,6 +464,7 @@ static switch_status_t recog_asr_disable_grammar(switch_asr_handle_t *ah, const static switch_status_t recog_asr_disable_all_grammars(switch_asr_handle_t *ah); static switch_status_t recog_asr_close(switch_asr_handle_t *ah, switch_asr_flag_t *flags); static switch_status_t recog_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags); +static switch_status_t recog_asr_feed_dtmf(switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags); #if 0 static switch_status_t recog_asr_start(switch_asr_handle_t *ah, const char *name); #endif @@ -472,6 +480,7 @@ static void recog_asr_float_param(switch_asr_handle_t *ah, char *param, double v /* recognizer's interface for UniMRCP */ static apt_bool_t recog_message_handler(const mrcp_app_message_t *app_message); static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_message_t *message); +static apt_bool_t recog_stream_open(mpf_audio_stream_t *stream, mpf_codec_t *codec); static apt_bool_t recog_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *frame); /* recognizer specific speech_channel_funcs */ @@ -3114,6 +3123,9 @@ static switch_status_t recog_asr_close(switch_asr_handle_t *ah, switch_asr_flag_ speech_channel_destroy(schannel); switch_core_hash_destroy(&r->grammars); switch_core_hash_destroy(&r->enabled_grammars); + if (r->dtmf_generator) { + mpf_dtmf_generator_destroy(r->dtmf_generator); + } /* this lets FreeSWITCH's speech_thread know the handle is closed */ switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED); @@ -3134,6 +3146,39 @@ static switch_status_t recog_asr_feed(switch_asr_handle_t *ah, void *data, unsig return speech_channel_write(schannel, data, &slen); } +/** + * Process asr_feed_dtmf request from FreeSWITCH + * + * @param ah the FreeSWITCH speech recognition handle + * @return SWITCH_STATUS_SUCCESS if successful + */ +static switch_status_t recog_asr_feed_dtmf(switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags) +{ + speech_channel_t *schannel = (speech_channel_t *) ah->private_info; + recognizer_data_t *r = (recognizer_data_t *) schannel->data; + char digits[2]; + + if (!r->dtmf_generator) { + if (!r->unimrcp_stream) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Cannot queue DTMF: No UniMRCP stream object open\n", schannel->name); + return SWITCH_STATUS_FALSE; + } + r->dtmf_generator = mpf_dtmf_generator_create(r->unimrcp_stream, schannel->unimrcp_session->pool); + if (!r->dtmf_generator) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Cannot queue DTMF: Failed to create DTMF generator\n", schannel->name); + return SWITCH_STATUS_FALSE; + } + } + + digits[0] = dtmf->digit; + digits[1] = '\0'; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Queued DTMF: %s\n", schannel->name, digits); + mpf_dtmf_generator_enqueue(r->dtmf_generator, digits); + r->dtmf_generator_active = 1; + + return SWITCH_STATUS_SUCCESS; +} + #if 0 /** * Process asr_start request from FreeSWITCH @@ -3379,6 +3424,23 @@ static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp return TRUE; } +/** + * UniMRCP callback requesting open for speech recognition + * + * @param stream the UniMRCP stream + * @param codec the codec + * @return TRUE + */ +static apt_bool_t recog_stream_open(mpf_audio_stream_t *stream, mpf_codec_t *codec) +{ + speech_channel_t *schannel = (speech_channel_t *) stream->obj; + recognizer_data_t *r = (recognizer_data_t *) schannel->data; + + r->unimrcp_stream = stream; + + return TRUE; +} + /** * UniMRCP callback requesting next frame for speech recognition * @@ -3389,6 +3451,7 @@ static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp static apt_bool_t recog_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *frame) { speech_channel_t *schannel = (speech_channel_t *) stream->obj; + recognizer_data_t *r = (recognizer_data_t *) schannel->data; switch_size_t to_read = frame->codec_frame.size; /* grab the data. pad it if there isn't enough */ @@ -3398,6 +3461,13 @@ static apt_bool_t recog_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *fra } frame->type |= MEDIA_FRAME_TYPE_AUDIO; } + + if (r->dtmf_generator_active) { + if (!mpf_dtmf_generator_put_frame(r->dtmf_generator, frame)) { + if (!mpf_dtmf_generator_sending(r->dtmf_generator)) + r->dtmf_generator_active = 0; + } + } return TRUE; } @@ -3421,6 +3491,7 @@ static switch_status_t recog_load(switch_loadable_module_interface_t *module_int asr_interface->asr_disable_all_grammars = recog_asr_disable_all_grammars; asr_interface->asr_close = recog_asr_close; asr_interface->asr_feed = recog_asr_feed; + asr_interface->asr_feed_dtmf = recog_asr_feed_dtmf; #if 0 asr_interface->asr_start = recog_asr_start; #endif @@ -3443,7 +3514,7 @@ static switch_status_t recog_load(switch_loadable_module_interface_t *module_int globals.recog.dispatcher.on_channel_remove = speech_on_channel_remove; globals.recog.dispatcher.on_message_receive = recog_on_message_receive; globals.recog.audio_stream_vtable.destroy = NULL; - globals.recog.audio_stream_vtable.open_rx = NULL; + globals.recog.audio_stream_vtable.open_rx = recog_stream_open; globals.recog.audio_stream_vtable.close_rx = NULL; globals.recog.audio_stream_vtable.read_frame = recog_stream_read; globals.recog.audio_stream_vtable.open_tx = NULL; diff --git a/src/switch_core_asr.c b/src/switch_core_asr.c index 691011a285..7f231ef651 100644 --- a/src/switch_core_asr.c +++ b/src/switch_core_asr.c @@ -239,6 +239,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_feed(switch_asr_handle_t *ah, vo return ah->asr_interface->asr_feed(ah, data, len, flags); } +SWITCH_DECLARE(switch_status_t) switch_core_asr_feed_dtmf(switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch_assert(ah != NULL); + + if (ah->asr_interface->asr_feed_dtmf) { + status = ah->asr_interface->asr_feed_dtmf(ah, dtmf, flags); + } + + return status; +} + SWITCH_DECLARE(switch_status_t) switch_core_asr_check_results(switch_asr_handle_t *ah, switch_asr_flag_t *flags) { switch_assert(ah != NULL); diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 66cd36963b..5df7af3bff 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -2660,6 +2660,20 @@ static switch_bool_t speech_callback(switch_media_bug_t *bug, void *user_data, s return SWITCH_TRUE; } +static switch_status_t speech_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY); + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE; + + if (switch_core_asr_feed_dtmf(sth->ah, dtmf, &flags) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Feeding DTMF\n"); + } + + return status; +} + SWITCH_DECLARE(switch_status_t) switch_ivr_stop_detect_speech(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); @@ -2875,6 +2889,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech(switch_core_session_t * return status; } + if ((status = switch_core_event_hook_add_recv_dtmf(session, speech_on_dtmf)) != SWITCH_STATUS_SUCCESS) { + switch_ivr_stop_detect_speech(session); + return status; + } + switch_channel_set_private(channel, SWITCH_SPEECH_KEY, sth); return SWITCH_STATUS_SUCCESS; From 1388ed811a2369b26778c4cce158691f285c45b4 Mon Sep 17 00:00:00 2001 From: Leon de Rooij Date: Thu, 27 Jan 2011 18:52:14 +0100 Subject: [PATCH 10/86] enter --- src/mod/languages/mod_lua/mod_lua_extra.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/languages/mod_lua/mod_lua_extra.h b/src/mod/languages/mod_lua/mod_lua_extra.h index b96adc39cd..3fca99440c 100644 --- a/src/mod/languages/mod_lua/mod_lua_extra.h +++ b/src/mod/languages/mod_lua/mod_lua_extra.h @@ -1,6 +1,8 @@ #ifndef MOD_LUA_EXTRA #define MOD_LUA_EXTRA -SWITCH_BEGIN_EXTERN_C void mod_lua_conjure_event(lua_State * L, switch_event_t *event, const char *name, int destroy_me); +SWITCH_BEGIN_EXTERN_C + +void mod_lua_conjure_event(lua_State * L, switch_event_t *event, const char *name, int destroy_me); void mod_lua_conjure_stream(lua_State * L, switch_stream_handle_t *stream, const char *name, int destroy_me); void mod_lua_conjure_session(lua_State * L, switch_core_session_t *session, const char *name, int destroy_me); From f37390f0a7f1ca636d54c23d6873510fcf26e91e Mon Sep 17 00:00:00 2001 From: Leon de Rooij Date: Thu, 27 Jan 2011 18:53:21 +0100 Subject: [PATCH 11/86] enter --- src/mod/languages/mod_lua/mod_lua_extra.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/languages/mod_lua/mod_lua_extra.c b/src/mod/languages/mod_lua/mod_lua_extra.c index 38776f93d7..821cc609e9 100644 --- a/src/mod/languages/mod_lua/mod_lua_extra.c +++ b/src/mod/languages/mod_lua/mod_lua_extra.c @@ -1,6 +1,8 @@ using namespace LUA; -SWITCH_BEGIN_EXTERN_C void mod_lua_conjure_event(lua_State * L, switch_event_t *event, const char *name, int destroy_me) +SWITCH_BEGIN_EXTERN_C + +void mod_lua_conjure_event(lua_State * L, switch_event_t *event, const char *name, int destroy_me) { Event *result = new Event(event); SWIG_NewPointerObj(L, result, SWIGTYPE_p_Event, destroy_me); From 08f494b80802aacf101705382f149ca4b028eb57 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Fri, 28 Jan 2011 20:14:10 +0100 Subject: [PATCH 12/86] typo --- src/mod/event_handlers/mod_snmp/subagent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c index 2da9ebeda6..8f08baf84c 100644 --- a/src/mod/event_handlers/mod_snmp/subagent.c +++ b/src/mod/event_handlers/mod_snmp/subagent.c @@ -109,7 +109,7 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); break; case SS_MAX_SESSIONS: - switch_core_session_ctl(SCSC_MAX_SESSIONS, &int_val);; + switch_core_session_ctl(SCSC_MAX_SESSIONS, &int_val); snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); break; case SS_CURRENT_CALLS: From f05fe55594ffca6edc8f4e74204650aa219ed1ac Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Fri, 28 Jan 2011 14:19:07 -0500 Subject: [PATCH 13/86] test --- conf/freeswitch.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml index 80e7728e0d..6ed99efb73 100644 --- a/conf/freeswitch.xml +++ b/conf/freeswitch.xml @@ -64,4 +64,3 @@ - From 9b0c16b5d48a7b9d0ea15ac429a8ca4c8eef8693 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Fri, 28 Jan 2011 14:20:21 -0500 Subject: [PATCH 14/86] test --- conf/freeswitch.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml index 6ed99efb73..5fc94024f2 100644 --- a/conf/freeswitch.xml +++ b/conf/freeswitch.xml @@ -63,4 +63,3 @@ - From 68b2756970bd4280eba700b7439afdff374fd9e3 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Fri, 28 Jan 2011 14:21:31 -0500 Subject: [PATCH 15/86] test --- conf/freeswitch.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml index 5fc94024f2..6ed99efb73 100644 --- a/conf/freeswitch.xml +++ b/conf/freeswitch.xml @@ -63,3 +63,4 @@ + From 97a2b4f9025099bdab5718a13ee36d15a6152411 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Fri, 28 Jan 2011 14:24:07 -0500 Subject: [PATCH 16/86] test --- conf/freeswitch.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml index 6ed99efb73..80e7728e0d 100644 --- a/conf/freeswitch.xml +++ b/conf/freeswitch.xml @@ -64,3 +64,4 @@ + From 9e6503a482ff533ff214b01a07c3432be14ff1ce Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Fri, 28 Jan 2011 14:33:30 -0500 Subject: [PATCH 17/86] test --- conf/freeswitch.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml index 80e7728e0d..6ed99efb73 100644 --- a/conf/freeswitch.xml +++ b/conf/freeswitch.xml @@ -64,4 +64,3 @@ - From b3ac44f555a80f8278c5f915cfb36766903905a4 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Fri, 28 Jan 2011 20:36:06 +0100 Subject: [PATCH 18/86] add support for getting current call count --- src/mod/event_handlers/mod_snmp/subagent.c | 27 +++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c index 8f08baf84c..bad3dc6ff2 100644 --- a/src/mod/event_handlers/mod_snmp/subagent.c +++ b/src/mod/event_handlers/mod_snmp/subagent.c @@ -49,6 +49,14 @@ void init_subagent(void) } +static int sql_count_callback(void *pArg, int argc, char **argv, char **columnNames) +{ + uint32_t *count = (uint32_t *) pArg; + *count = atoi(argv[0]); + return 0; +} + + int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request = NULL; @@ -113,13 +121,20 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); break; case SS_CURRENT_CALLS: - /* - * This is zero for now, since there is no convenient way to get total call - * count (not to be confused with session count), without touching the - * database. - */ - int_val = 0; + { + switch_cache_db_handle_t *dbh; + char sql[1024] = "", hostname[256] = ""; + + if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { + return SNMP_ERR_GENERR; + } + + gethostname(hostname, sizeof(hostname)); + sprintf(sql, "SELECT COUNT(*) FROM calls WHERE hostname='%s'", hostname); + switch_cache_db_execute_sql_callback(dbh, sql, sql_count_callback, &int_val, NULL); snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + switch_cache_db_release_db_handle(&dbh); + } break; case SS_SESSIONS_PER_SECOND: switch_core_session_ctl(SCSC_LAST_SPS, &int_val); From 6d3abd41cadef3a2bff8175487c094c80d7d9cf7 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Fri, 28 Jan 2011 16:11:55 -0500 Subject: [PATCH 19/86] TEST-001 --- conf/freeswitch.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml index 6ed99efb73..5fc94024f2 100644 --- a/conf/freeswitch.xml +++ b/conf/freeswitch.xml @@ -63,4 +63,3 @@ - From 068d36a5c95c5a4143f423b7c36cbe6d5cea36d5 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Fri, 28 Jan 2011 22:32:14 +0100 Subject: [PATCH 20/86] partial implementation of channel list via snmp --- .../event_handlers/mod_snmp/FREESWITCH-MIB | 84 ++++++++++ src/mod/event_handlers/mod_snmp/mod_snmp.c | 2 +- src/mod/event_handlers/mod_snmp/subagent.c | 154 ++++++++++++++++-- src/mod/event_handlers/mod_snmp/subagent.h | 22 ++- 4 files changed, 248 insertions(+), 14 deletions(-) diff --git a/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB index 9584c8bac3..11c3999c6f 100644 --- a/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB +++ b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB @@ -107,4 +107,88 @@ maxSessionsPerSecond OBJECT-TYPE "Maximum permissible sessions per second" ::= { systemStats 7 } + +ChannelEntry ::= SEQUENCE { + chanUUID DisplayString, + chanDirection DisplayString, + chanCreated DisplayString, + chanName DisplayString, + chanState DisplayString, + chanCIDName DisplayString, + chanCIDNum DisplayString +} + +channelList OBJECT-TYPE + SYNTAX SEQUENCE OF ChannelEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A table containing a list of active channels" + ::= { core 9 } + +channelEntry OBJECT-TYPE + SYNTAX ChannelEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A channel entry" + INDEX { chanIndex } + ::= { channelList 1 } + +chanUUID OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The channel UUID." + ::= { channelEntry 1 } + +chanDirection OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The channel direction." + ::= { channelEntry 2 } + +chanCreated OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel creation timestamp." + ::= { channelEntry 3 } + +chanName OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The channel name." + ::= { channelEntry 4 } + +chanState OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The channel state." + ::= { channelEntry 5 } + +chanCIDName OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The channel caller ID name." + ::= { channelEntry 6 } + +chanCIDNum OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The channel caller ID number." + ::= { channelEntry 7 } + END diff --git a/src/mod/event_handlers/mod_snmp/mod_snmp.c b/src/mod/event_handlers/mod_snmp/mod_snmp.c index 56c7be1ef6..d415d4fe1c 100644 --- a/src/mod/event_handlers/mod_snmp/mod_snmp.c +++ b/src/mod/event_handlers/mod_snmp/mod_snmp.c @@ -109,7 +109,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load) */ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL, 2); - init_subagent(); + init_subagent(pool); init_snmp("mod_snmp"); return status; diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c index bad3dc6ff2..7b9faa752b 100644 --- a/src/mod/event_handlers/mod_snmp/subagent.c +++ b/src/mod/event_handlers/mod_snmp/subagent.c @@ -36,17 +36,10 @@ #include #include "subagent.h" - -void init_subagent(void) -{ - static oid identity_oid[] = { 1,3,6,1,4,1,27880,1,1 }; - static oid systemStats_oid[] = { 1,3,6,1,4,1,27880,1,2 }; - - DEBUGMSGTL(("init_subagent", "Initializing\n")); - - netsnmp_register_scalar_group(netsnmp_create_handler_registration("identity", handle_identity, identity_oid, OID_LENGTH(identity_oid), HANDLER_CAN_RONLY), 1, 2); - netsnmp_register_scalar_group(netsnmp_create_handler_registration("systemStats", handle_systemStats, systemStats_oid, OID_LENGTH(systemStats_oid), HANDLER_CAN_RONLY), 1, 7); -} +netsnmp_table_registration_info *ch_table_info; +netsnmp_tdata *ch_table; +netsnmp_handler_registration *ch_reginfo; +uint32_t idx; static int sql_count_callback(void *pArg, int argc, char **argv, char **columnNames) @@ -57,6 +50,94 @@ static int sql_count_callback(void *pArg, int argc, char **argv, char **columnNa } +static int channelList_callback(void *pArg, int argc, char **argv, char **columnNames) +{ + chan_entry_t *entry; + netsnmp_tdata_row *row; + + switch_zmalloc(entry, sizeof(chan_entry_t)); + if (!entry) + return 0; + + row = netsnmp_tdata_create_row(); + if (!row) { + switch_safe_free(entry); + return 0; + } + row->data = entry; + + entry->idx = idx++; + strncpy(entry->uuid, argv[0], sizeof(entry->uuid)); + strncpy(entry->direction, argv[1], sizeof(entry->direction)); + strncpy(entry->created, argv[2], sizeof(entry->created)); + strncpy(entry->name, argv[4], sizeof(entry->name)); + strncpy(entry->state, argv[5], sizeof(entry->state)); + strncpy(entry->cid_name, argv[6], sizeof(entry->cid_name)); + strncpy(entry->cid_num, argv[7], sizeof(entry->cid_num)); + + netsnmp_tdata_row_add_index(row, ASN_INTEGER, &entry->idx, sizeof(entry->idx)); + netsnmp_tdata_add_row(ch_table, row); + return 0; +} + + +void channelList_free(netsnmp_cache *cache, void *magic) +{ + netsnmp_tdata_row *row = netsnmp_tdata_row_first(ch_table); + + /* Delete table rows one by one */ + while (row) { + netsnmp_tdata_remove_and_delete_row(ch_table, row); + switch_safe_free(row->data); + row = netsnmp_tdata_row_first(ch_table); + } +} + + +int channelList_load(netsnmp_cache *cache, void *vmagic) +{ + switch_cache_db_handle_t *dbh; + char sql[1024] = "", hostname[256] = ""; + + channelList_free(cache, NULL); + + if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { + return 0; + } + + idx = 1; + gethostname(hostname, sizeof(hostname)); + sprintf(sql, "SELECT * FROM channels WHERE hostname='%s' ORDER BY created_epoch", hostname); + switch_cache_db_execute_sql_callback(dbh, sql, channelList_callback, NULL, NULL); + + switch_cache_db_release_db_handle(&dbh); + + return 0; +} + + +void init_subagent(switch_memory_pool_t *pool) +{ + static oid identity_oid[] = { 1,3,6,1,4,1,27880,1,1 }; + static oid systemStats_oid[] = { 1,3,6,1,4,1,27880,1,2 }; + static oid channelList_oid[] = { 1,3,6,1,4,1,27880,1,9 }; + + DEBUGMSGTL(("init_subagent", "mod_snmp subagent initializing\n")); + + netsnmp_register_scalar_group(netsnmp_create_handler_registration("identity", handle_identity, identity_oid, OID_LENGTH(identity_oid), HANDLER_CAN_RONLY), 1, 2); + netsnmp_register_scalar_group(netsnmp_create_handler_registration("systemStats", handle_systemStats, systemStats_oid, OID_LENGTH(systemStats_oid), HANDLER_CAN_RONLY), 1, 7); + + ch_table_info = switch_core_alloc(pool, sizeof(netsnmp_table_registration_info)); + netsnmp_table_helper_add_index(ch_table_info, ASN_INTEGER); + ch_table_info->min_column = 1; + ch_table_info->max_column = 7; + ch_table = netsnmp_tdata_create_table("channelList", 0); + ch_reginfo = netsnmp_create_handler_registration("channelList", handle_channelList, channelList_oid, OID_LENGTH(channelList_oid), HANDLER_CAN_RONLY); + netsnmp_tdata_register(ch_reginfo, ch_table, ch_table_info); + netsnmp_inject_handler(ch_reginfo, netsnmp_get_cache_handler(5, channelList_load, channelList_free, channelList_oid, OID_LENGTH(channelList_oid))); +} + + int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request = NULL; @@ -97,7 +178,7 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio netsnmp_request_info *request = NULL; oid subid; switch_time_t uptime; - uint32_t int_val; + uint32_t int_val = 0; switch(reqinfo->mode) { case MODE_GET: @@ -160,6 +241,55 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio } +int handle_channelList(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) +{ + netsnmp_request_info *request; + netsnmp_table_request_info *table_info; + chan_entry_t *entry; + + switch (reqinfo->mode) { + case MODE_GET: + for (request = requests; request; request = request->next) { + table_info = netsnmp_extract_table_info(request); + entry = (chan_entry_t *) netsnmp_tdata_extract_entry(request); + + switch (table_info->colnum) { + case CH_UUID: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->uuid, strlen(entry->uuid)); + break; + case CH_DIRECTION: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->direction, strlen(entry->direction)); + break; + case CH_CREATED: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->created, strlen(entry->created)); + break; + case CH_NAME: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->name, strlen(entry->name)); + break; + case CH_STATE: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->state, strlen(entry->state)); + break; + case CH_CID_NAME: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->cid_name, strlen(entry->cid_name)); + break; + case CH_CID_NUM: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->cid_num, strlen(entry->cid_num)); + break; + default: + snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", table_info->colnum); + netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); + } + } + break; + default: + /* we should never get here, so this is a really bad error */ + snmp_log(LOG_ERR, "Unknown mode (%d) in handle_foo\n", reqinfo->mode ); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} + /* For Emacs: * Local Variables: diff --git a/src/mod/event_handlers/mod_snmp/subagent.h b/src/mod/event_handlers/mod_snmp/subagent.h index 33153780b5..0070b2c3af 100644 --- a/src/mod/event_handlers/mod_snmp/subagent.h +++ b/src/mod/event_handlers/mod_snmp/subagent.h @@ -14,9 +14,29 @@ #define SS_SESSIONS_PER_SECOND 6 #define SS_MAX_SESSIONS_PER_SECOND 7 +/* .1.3.6.1.4.1.27880.1.9 */ +#define CH_UUID 1 +#define CH_DIRECTION 2 +#define CH_CREATED 3 +#define CH_NAME 4 +#define CH_STATE 5 +#define CH_CID_NAME 6 +#define CH_CID_NUM 7 -void init_subagent(void); +typedef struct { + uint32_t idx; + char uuid[38]; + char direction[32]; + char created[128]; + char name[1024]; + char state[64]; + char cid_name[1024]; + char cid_num[256]; +} chan_entry_t; + +void init_subagent(switch_memory_pool_t *pool); Netsnmp_Node_Handler handle_identity; Netsnmp_Node_Handler handle_systemStats; +Netsnmp_Node_Handler handle_channelList; #endif /* subagent_H */ From e6e4bcea734fbfb54b901ff8b1107ddfe76b7010 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Fri, 28 Jan 2011 16:42:15 -0500 Subject: [PATCH 21/86] TEST-002 --- conf/freeswitch.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml index 5fc94024f2..6914128e55 100644 --- a/conf/freeswitch.xml +++ b/conf/freeswitch.xml @@ -61,5 +61,4 @@ - From 49a5effcdf2cea9e0ddcf146cf3fe85d1872e654 Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Sat, 29 Jan 2011 03:09:06 -0500 Subject: [PATCH 22/86] mod_callcenter: Add error response for queue load and queue reload (FS-2988) --- src/mod/applications/mod_callcenter/mod_callcenter.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index d1de632ee6..61305bbbb5 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -2625,8 +2625,10 @@ SWITCH_STANDARD_API(cc_config_api_function) cc_queue_t *queue = NULL; if ((queue = get_queue(queue_name))) { queue_rwunlock(queue); + stream->write_function(stream, "%s", "+OK\n"); + } else { + stream->write_function(stream, "%s", "-ERR Invalid Queue not found!\n"); } - stream->write_function(stream, "%s", "+OK\n"); } } else if (action && !strcasecmp(action, "unload")) { if (argc-initial_argc < 1) { @@ -2648,8 +2650,10 @@ SWITCH_STANDARD_API(cc_config_api_function) destroy_queue(queue_name, SWITCH_FALSE); if ((queue = get_queue(queue_name))) { queue_rwunlock(queue); + stream->write_function(stream, "%s", "+OK\n"); + } else { + stream->write_function(stream, "%s", "-ERR Invalid Queue not found!\n"); } - stream->write_function(stream, "%s", "+OK\n"); } } else if (action && !strcasecmp(action, "list")) { if (argc-initial_argc < 1) { @@ -2671,7 +2675,6 @@ SWITCH_STANDARD_API(cc_config_api_function) goto done; } else { const char *queue_name = argv[0 + initial_argc]; - struct list_result cbt; cbt.row_process = 0; cbt.stream = stream; From 2ad81ac82f3c3c989e4d7d11f788c43c2c6f20d8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 29 Jan 2011 13:43:59 -0600 Subject: [PATCH 23/86] fix || where it should be or in sql stmt that may cause stray records in the calls table --- src/switch_core_sqldb.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 4167b4a89c..35311c9b0f 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1160,15 +1160,14 @@ static void core_event_handler(switch_event_t *event) case SWITCH_EVENT_CHANNEL_DESTROY: { const char *uuid = switch_event_get_header(event, "unique-id"); - const char *sig = switch_event_get_header(event, "signal_bridge"); if (uuid) { new_sql() = switch_mprintf("delete from channels where uuid='%q' and hostname='%q'", uuid, switch_core_get_variable("hostname")); - if (switch_true(sig)) { - new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' || callee_uuid='%q') and hostname='%q'", - uuid, uuid, switch_core_get_variable("hostname")); - } + + new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q') and hostname='%q'", + uuid, uuid, switch_core_get_variable("hostname")); + } } break; @@ -1410,7 +1409,7 @@ static void core_event_handler(switch_event_t *event) } break; case SWITCH_EVENT_CHANNEL_UNBRIDGE: - new_sql() = switch_mprintf("delete from calls where caller_uuid='%s' and hostname='%q'", + new_sql() = switch_mprintf("delete from calls where (caller_uuid='%s' or callee_uuid='%q') and hostname='%q'", switch_event_get_header_nil(event, "caller-unique-id"), switch_core_get_variable("hostname")); break; case SWITCH_EVENT_SHUTDOWN: From c8f5c66c3520ecda8f8dbc07dc01f1d4035058e4 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Mon, 31 Jan 2011 15:41:58 +0100 Subject: [PATCH 24/86] mostly complete implementation of channel list via SNMP --- .../event_handlers/mod_snmp/FREESWITCH-MIB | 175 +++++++++++++++--- src/mod/event_handlers/mod_snmp/subagent.c | 105 +++++++++-- src/mod/event_handlers/mod_snmp/subagent.h | 51 ++++- 3 files changed, 289 insertions(+), 42 deletions(-) diff --git a/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB index 11c3999c6f..84485269f9 100644 --- a/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB +++ b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB @@ -3,11 +3,14 @@ FREESWITCH-MIB DEFINITIONS ::= BEGIN IMPORTS OBJECT-TYPE, MODULE-IDENTITY, Integer32, Gauge32, Counter32, Counter64, TimeTicks, - enterprises, + enterprises FROM SNMPv2-SMI - DisplayString + DisplayString, DateAndTime FROM SNMPv2-TC + + InetAddressType, InetAddress + FROM INET-ADDRESS-MIB ; @@ -109,13 +112,27 @@ maxSessionsPerSecond OBJECT-TYPE ChannelEntry ::= SEQUENCE { - chanUUID DisplayString, - chanDirection DisplayString, - chanCreated DisplayString, - chanName DisplayString, - chanState DisplayString, - chanCIDName DisplayString, - chanCIDNum DisplayString + chanIndex Integer32, + chanUUID DisplayString, + chanDirection DisplayString, + chanCreated DateAndTime, + chanName DisplayString, + chanState DisplayString, + chanCIDName DisplayString, + chanCIDNum DisplayString, + chanInetAddressType InetAddressType, + chanInetAddress InetAddress, + chanDest DisplayString, + chanApplication DisplayString, + chanAppData DisplayString, + chanDialplan DisplayString, + chanContext DisplayString, + chanReadCodec DisplayString, + chanReadRate Gauge32, + chanReadBitRate Gauge32, + chanWriteCodec DisplayString, + chanWriteRate Gauge32, + chanWriteBitRate Gauge32 } channelList OBJECT-TYPE @@ -135,60 +152,172 @@ channelEntry OBJECT-TYPE INDEX { chanIndex } ::= { channelList 1 } +chanIndex OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel SNMP index." + ::= { channelEntry 1 } + chanUUID OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION - "The channel UUID." - ::= { channelEntry 1 } + "Channel UUID." + ::= { channelEntry 2 } chanDirection OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION - "The channel direction." - ::= { channelEntry 2 } + "Channel direction." + ::= { channelEntry 3 } chanCreated OBJECT-TYPE - SYNTAX DisplayString + SYNTAX DateAndTime MAX-ACCESS read-only STATUS current DESCRIPTION "Channel creation timestamp." - ::= { channelEntry 3 } + ::= { channelEntry 4 } chanName OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION - "The channel name." - ::= { channelEntry 4 } + "Channel name." + ::= { channelEntry 5 } chanState OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION - "The channel state." - ::= { channelEntry 5 } + "Channel state." + ::= { channelEntry 6 } chanCIDName OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION - "The channel caller ID name." - ::= { channelEntry 6 } + "Channel caller ID name." + ::= { channelEntry 7 } chanCIDNum OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION - "The channel caller ID number." - ::= { channelEntry 7 } + "Channel caller ID number." + ::= { channelEntry 8 } + +chanInetAddressType OBJECT-TYPE + SYNTAX InetAddressType + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel originator's IP address type (IPv4 or IPv6)." + ::= { channelEntry 9 } + +chanInetAddress OBJECT-TYPE + SYNTAX InetAddress + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel originator's IP address." + ::= { channelEntry 10 } + +chanDest OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel destination." + ::= { channelEntry 11 } + +chanApplication OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel application." + ::= { channelEntry 12 } + +chanAppData OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel application data." + ::= { channelEntry 13 } + +chanDialplan OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel dialplan." + ::= { channelEntry 14 } + +chanContext OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel dialplan context." + ::= { channelEntry 15 } + +chanReadCodec OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel read codec." + ::= { channelEntry 16 } + +chanReadRate OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel read samples per second." + ::= { channelEntry 17 } + +chanReadBitRate OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel read bits per second." + ::= { channelEntry 18 } + +chanWriteCodec OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel write codec." + ::= { channelEntry 19 } + +chanWriteRate OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel write samples per second." + ::= { channelEntry 20 } + +chanWriteBitRate OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Channel write bits per second." + ::= { channelEntry 21 } END diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c index 7b9faa752b..43975ee4e0 100644 --- a/src/mod/event_handlers/mod_snmp/subagent.c +++ b/src/mod/event_handlers/mod_snmp/subagent.c @@ -42,6 +42,17 @@ netsnmp_handler_registration *ch_reginfo; uint32_t idx; +static void time_t_to_datetime(time_t epoch, char *buf, switch_size_t buflen) +{ + struct tm *dt; + uint16_t year; + + dt = gmtime(&epoch); + year = dt->tm_year + 1900; + switch_snprintf(buf, buflen, "%c%c%c%c%c%c%c%c+%c%c", year >> 8, year & 0xff, dt->tm_mon + 1, dt->tm_mday, dt->tm_hour, dt->tm_min, dt->tm_sec, 0, 0, 0); +} + + static int sql_count_callback(void *pArg, int argc, char **argv, char **columnNames) { uint32_t *count = (uint32_t *) pArg; @@ -69,11 +80,31 @@ static int channelList_callback(void *pArg, int argc, char **argv, char **column entry->idx = idx++; strncpy(entry->uuid, argv[0], sizeof(entry->uuid)); strncpy(entry->direction, argv[1], sizeof(entry->direction)); - strncpy(entry->created, argv[2], sizeof(entry->created)); + entry->created_epoch = atoi(argv[3]); strncpy(entry->name, argv[4], sizeof(entry->name)); strncpy(entry->state, argv[5], sizeof(entry->state)); strncpy(entry->cid_name, argv[6], sizeof(entry->cid_name)); strncpy(entry->cid_num, argv[7], sizeof(entry->cid_num)); + strncpy(entry->dest, argv[9], sizeof(entry->dest)); + strncpy(entry->application, argv[10], sizeof(entry->application)); + strncpy(entry->application_data, argv[11], sizeof(entry->application_data)); + strncpy(entry->dialplan, argv[12], sizeof(entry->dialplan)); + strncpy(entry->context, argv[13], sizeof(entry->context)); + strncpy(entry->read_codec, argv[14], sizeof(entry->read_codec)); + entry->read_rate = atoi(argv[15]); + entry->read_bitrate = atoi(argv[16]); + strncpy(entry->write_codec, argv[17], sizeof(entry->write_codec)); + entry->write_rate = atoi(argv[18]); + entry->write_bitrate = atoi(argv[19]); + + memset(&entry->ip_addr, 0, sizeof(entry->ip_addr)); + if (strchr(argv[8], ':')) { + switch_inet_pton(AF_INET6, argv[8], &entry->ip_addr); + entry->addr_family = AF_INET6; + } else { + switch_inet_pton(AF_INET, argv[8], &entry->ip_addr); + entry->addr_family = AF_INET; + } netsnmp_tdata_row_add_index(row, ASN_INTEGER, &entry->idx, sizeof(entry->idx)); netsnmp_tdata_add_row(ch_table, row); @@ -128,9 +159,9 @@ void init_subagent(switch_memory_pool_t *pool) netsnmp_register_scalar_group(netsnmp_create_handler_registration("systemStats", handle_systemStats, systemStats_oid, OID_LENGTH(systemStats_oid), HANDLER_CAN_RONLY), 1, 7); ch_table_info = switch_core_alloc(pool, sizeof(netsnmp_table_registration_info)); - netsnmp_table_helper_add_index(ch_table_info, ASN_INTEGER); - ch_table_info->min_column = 1; - ch_table_info->max_column = 7; + netsnmp_table_helper_add_indexes(ch_table_info, ASN_INTEGER, 0); + ch_table_info->min_column = CH_INDEX; + ch_table_info->max_column = CH_WRITE_BITRATE; ch_table = netsnmp_tdata_create_table("channelList", 0); ch_reginfo = netsnmp_create_handler_registration("channelList", handle_channelList, channelList_oid, OID_LENGTH(channelList_oid), HANDLER_CAN_RONLY); netsnmp_tdata_register(ch_reginfo, ch_table, ch_table_info); @@ -191,15 +222,15 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio break; case SS_SESSIONS_SINCE_STARTUP: int_val = switch_core_session_id() - 1; - snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, (u_char *) &int_val, sizeof(int_val)); + snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER, int_val); break; case SS_CURRENT_SESSIONS: int_val = switch_core_session_count(); - snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + snmp_set_var_typed_integer(requests->requestvb, ASN_GAUGE, int_val); break; case SS_MAX_SESSIONS: switch_core_session_ctl(SCSC_MAX_SESSIONS, &int_val); - snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + snmp_set_var_typed_integer(requests->requestvb, ASN_GAUGE, int_val); break; case SS_CURRENT_CALLS: { @@ -213,17 +244,17 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio gethostname(hostname, sizeof(hostname)); sprintf(sql, "SELECT COUNT(*) FROM calls WHERE hostname='%s'", hostname); switch_cache_db_execute_sql_callback(dbh, sql, sql_count_callback, &int_val, NULL); - snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + snmp_set_var_typed_integer(requests->requestvb, ASN_GAUGE, int_val); switch_cache_db_release_db_handle(&dbh); } break; case SS_SESSIONS_PER_SECOND: switch_core_session_ctl(SCSC_LAST_SPS, &int_val); - snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + snmp_set_var_typed_integer(requests->requestvb, ASN_GAUGE, int_val); break; case SS_MAX_SESSIONS_PER_SECOND: switch_core_session_ctl(SCSC_SPS, &int_val); - snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + snmp_set_var_typed_integer(requests->requestvb, ASN_GAUGE, int_val); break; default: snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid); @@ -246,6 +277,7 @@ int handle_channelList(netsnmp_mib_handler *handler, netsnmp_handler_registratio netsnmp_request_info *request; netsnmp_table_request_info *table_info; chan_entry_t *entry; + char dt_str[12]; switch (reqinfo->mode) { case MODE_GET: @@ -254,6 +286,9 @@ int handle_channelList(netsnmp_mib_handler *handler, netsnmp_handler_registratio entry = (chan_entry_t *) netsnmp_tdata_extract_entry(request); switch (table_info->colnum) { + case CH_INDEX: + snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->idx); + break; case CH_UUID: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->uuid, strlen(entry->uuid)); break; @@ -261,7 +296,8 @@ int handle_channelList(netsnmp_mib_handler *handler, netsnmp_handler_registratio snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->direction, strlen(entry->direction)); break; case CH_CREATED: - snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->created, strlen(entry->created)); + time_t_to_datetime(entry->created_epoch, (char *) &dt_str, sizeof(dt_str)); + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) &dt_str, sizeof(dt_str)); break; case CH_NAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->name, strlen(entry->name)); @@ -275,6 +311,53 @@ int handle_channelList(netsnmp_mib_handler *handler, netsnmp_handler_registratio case CH_CID_NUM: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->cid_num, strlen(entry->cid_num)); break; + case CH_IP_ADDR_TYPE: + if (entry->addr_family == AF_INET6) { + snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, INETADDRESSTYPE_IPV6); + } else { + snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, INETADDRESSTYPE_IPV4); + } + break; + case CH_IP_ADDR: + if (entry->addr_family == AF_INET6) { + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) &entry->ip_addr.v6, sizeof(entry->ip_addr.v6)); + } else { + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) &entry->ip_addr.v4, sizeof(entry->ip_addr.v4)); + } + break; + case CH_DEST: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->dest, strlen(entry->dest)); + break; + case CH_APPLICATION: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->application, strlen(entry->application)); + break; + case CH_APPLICATION_DATA: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->application_data, strlen(entry->application_data)); + break; + case CH_DIALPLAN: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->dialplan, strlen(entry->dialplan)); + break; + case CH_CONTEXT: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->context, strlen(entry->context)); + break; + case CH_READ_CODEC: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->read_codec, strlen(entry->read_codec)); + break; + case CH_READ_RATE: + snmp_set_var_typed_value(request->requestvb, ASN_GAUGE, (u_char *) &entry->read_rate, sizeof(entry->read_rate)); + break; + case CH_READ_BITRATE: + snmp_set_var_typed_value(request->requestvb, ASN_GAUGE, (u_char *) &entry->read_bitrate, sizeof(entry->read_bitrate)); + break; + case CH_WRITE_CODEC: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *) entry->write_codec, strlen(entry->write_codec)); + break; + case CH_WRITE_RATE: + snmp_set_var_typed_value(request->requestvb, ASN_GAUGE, (u_char *) &entry->write_rate, sizeof(entry->write_rate)); + break; + case CH_WRITE_BITRATE: + snmp_set_var_typed_value(request->requestvb, ASN_GAUGE, (u_char *) &entry->write_bitrate, sizeof(entry->write_bitrate)); + break; default: snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", table_info->colnum); netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); diff --git a/src/mod/event_handlers/mod_snmp/subagent.h b/src/mod/event_handlers/mod_snmp/subagent.h index 0070b2c3af..5da87a6c4e 100644 --- a/src/mod/event_handlers/mod_snmp/subagent.h +++ b/src/mod/event_handlers/mod_snmp/subagent.h @@ -15,23 +15,58 @@ #define SS_MAX_SESSIONS_PER_SECOND 7 /* .1.3.6.1.4.1.27880.1.9 */ -#define CH_UUID 1 -#define CH_DIRECTION 2 -#define CH_CREATED 3 -#define CH_NAME 4 -#define CH_STATE 5 -#define CH_CID_NAME 6 -#define CH_CID_NUM 7 +#define CH_INDEX 1 +#define CH_UUID 2 +#define CH_DIRECTION 3 +#define CH_CREATED 4 +#define CH_NAME 5 +#define CH_STATE 6 +#define CH_CID_NAME 7 +#define CH_CID_NUM 8 +#define CH_IP_ADDR_TYPE 9 +#define CH_IP_ADDR 10 +#define CH_DEST 11 +#define CH_APPLICATION 12 +#define CH_APPLICATION_DATA 13 +#define CH_DIALPLAN 14 +#define CH_CONTEXT 15 +#define CH_READ_CODEC 16 +#define CH_READ_RATE 17 +#define CH_READ_BITRATE 18 +#define CH_WRITE_CODEC 19 +#define CH_WRITE_RATE 20 +#define CH_WRITE_BITRATE 21 + +/* Why aren't these in net-snmp-includes.h ? */ +#define INETADDRESSTYPE_UNKNOWN 0 +#define INETADDRESSTYPE_IPV4 1 +#define INETADDRESSTYPE_IPV6 2 +#define INETADDRESSTYPE_IPV4Z 3 +#define INETADDRESSTYPE_IPV6Z 4 +#define INETADDRESSTYPE_DNS 16 typedef struct { uint32_t idx; char uuid[38]; char direction[32]; - char created[128]; + time_t created_epoch; char name[1024]; char state[64]; char cid_name[1024]; char cid_num[256]; + ip_t ip_addr; + uint8_t addr_family; + char dest[1024]; + char application[128]; + char application_data[4096]; + char dialplan[128]; + char context[128]; + char read_codec[128]; + uint32_t read_rate; + uint32_t read_bitrate; + char write_codec[128]; + uint32_t write_rate; + uint32_t write_bitrate; } chan_entry_t; void init_subagent(switch_memory_pool_t *pool); From 256a82dbf2d7f4b4e1d7527f1e6a15d8d0d38a21 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 31 Jan 2011 10:12:28 -0600 Subject: [PATCH 25/86] OPENZAP-140 VS2010 build cleanup --- libs/freetdm/msvc/testboost/testboost.2010.vcxproj | 6 +++--- .../msvc/testboost/testsangomaboost.2010.vcxproj | 6 +++--- .../ftmod_sangoma_boost.2010.vcxproj | 12 ++++++------ .../ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libs/freetdm/msvc/testboost/testboost.2010.vcxproj b/libs/freetdm/msvc/testboost/testboost.2010.vcxproj index 62061485c2..314440bf9f 100644 --- a/libs/freetdm/msvc/testboost/testboost.2010.vcxproj +++ b/libs/freetdm/msvc/testboost/testboost.2010.vcxproj @@ -105,7 +105,7 @@ 4100;%(DisableSpecificWarnings) - ..\..\debug\freetdm.lib;%(AdditionalDependencies) + %(AdditionalDependencies) true Console false @@ -162,7 +162,7 @@ 4100;%(DisableSpecificWarnings) - freetdm.lib;%(AdditionalDependencies) + %(AdditionalDependencies) true Console false @@ -199,7 +199,7 @@ MachineX64 - freetdm.lib;%(AdditionalDependencies) + %(AdditionalDependencies) ../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) diff --git a/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj b/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj index 5994da6f1a..4077a60aba 100644 --- a/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj +++ b/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj @@ -105,7 +105,7 @@ 4100;%(DisableSpecificWarnings) - ..\..\debug\freetdm.lib;%(AdditionalDependencies) + %(AdditionalDependencies) true Console false @@ -162,7 +162,7 @@ 4100;%(DisableSpecificWarnings) - freetdm.lib;%(AdditionalDependencies) + %(AdditionalDependencies) true Console false @@ -199,7 +199,7 @@ MachineX64 - freetdm.lib;%(AdditionalDependencies) + %(AdditionalDependencies) ../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj index 78689c36db..684e4326cb 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj @@ -61,11 +61,11 @@ <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ true - $(SolutionDir)$(Configuration)\ - $(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ false $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ @@ -102,7 +102,7 @@ 4100;%(DisableSpecificWarnings) - freetdm.lib;%(AdditionalDependencies) + %(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) true Windows @@ -151,7 +151,7 @@ 4100;%(DisableSpecificWarnings) - freetdm.lib;%(AdditionalDependencies) + %(AdditionalDependencies) $(OutDir);%(AdditionalLibraryDirectories) true Windows diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj index 40d0a73a5b..a21be2232f 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj @@ -61,14 +61,14 @@ <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ true $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ true - $(SolutionDir)$(Configuration)\ - $(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ false $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ From 766f2d61651f161b074fad2f987b4f10532a9a7a Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 31 Jan 2011 18:24:08 +0000 Subject: [PATCH 26/86] fix typo: cant -> can't --- src/mod/applications/mod_spy/mod_spy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_spy/mod_spy.c b/src/mod/applications/mod_spy/mod_spy.c index 9986703f66..e0a9317c2a 100644 --- a/src/mod/applications/mod_spy/mod_spy.c +++ b/src/mod/applications/mod_spy/mod_spy.c @@ -201,14 +201,14 @@ static void event_handler(switch_event_t *event) } if (!(peer_session = switch_core_session_locate(peer_uuid))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cant locate peer session for uuid %s\n", peer_uuid); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't locate peer session for uuid %s\n", peer_uuid); return; } peer_channel = switch_core_session_get_channel(peer_session); if (switch_event_create(&peer_event, SWITCH_EVENT_CHANNEL_BRIDGE) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cant create bridge event for peer channel %s\n", peer_uuid); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't create bridge event for peer channel %s\n", peer_uuid); goto end; } @@ -249,7 +249,7 @@ SWITCH_STANDARD_APP(userspy_function) status = switch_core_hash_insert(globals.spy_hash, argv[0], (void *) uuid); if ((status != SWITCH_STATUS_SUCCESS)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cant insert to spy hash\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't insert to spy hash\n"); switch_channel_hangup(channel, SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED); switch_thread_rwlock_unlock(globals.spy_hash_lock); return; From 1f1541b474c549d6a13b6a943d13f046d463751a Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 31 Jan 2011 18:34:24 +0000 Subject: [PATCH 27/86] lower log-level of a mod_spy message When a session loses a race to bridge a call, the CHANNEL_BRIDGE event handler is still run, yet session_locate is going to return null as it won't get a read-lock on the peer's session. Since this is a normal and common condition, let's log this as a debug message rather than as an error condition. --- src/mod/applications/mod_spy/mod_spy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_spy/mod_spy.c b/src/mod/applications/mod_spy/mod_spy.c index e0a9317c2a..1797539cf0 100644 --- a/src/mod/applications/mod_spy/mod_spy.c +++ b/src/mod/applications/mod_spy/mod_spy.c @@ -201,7 +201,7 @@ static void event_handler(switch_event_t *event) } if (!(peer_session = switch_core_session_locate(peer_uuid))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't locate peer session for uuid %s\n", peer_uuid); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Can't locate peer session for uuid %s\n", peer_uuid); return; } From 9470e70057c549598d6d5e768d6cb08a2ba82104 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 31 Jan 2011 17:58:15 -0600 Subject: [PATCH 28/86] swigall --- .../languages/mod_managed/freeswitch_wrap.cxx | 200 ++++++++++++++++++ src/mod/languages/mod_managed/managed/swig.cs | 162 ++++++++++++++ 2 files changed, 362 insertions(+) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index 3ee6ff62fd..e91de6df46 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -9238,6 +9238,22 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_feed(void * jarg1, void * jarg } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_feed_dtmf(void * jarg1, void * jarg2, void * jarg3) { + int jresult ; + switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ; + switch_dtmf_t *arg2 = (switch_dtmf_t *) 0 ; + switch_asr_flag_t *arg3 = (switch_asr_flag_t *) 0 ; + switch_status_t result; + + arg1 = (switch_asr_handle_t *)jarg1; + arg2 = (switch_dtmf_t *)jarg2; + arg3 = (switch_asr_flag_t *)jarg3; + result = (switch_status_t)switch_core_asr_feed_dtmf(arg1,(switch_dtmf_t const *)arg2,arg3); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_check_results(void * jarg1, void * jarg2) { int jresult ; switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ; @@ -9298,6 +9314,46 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_unload_grammar(void * jarg1, c } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_enable_grammar(void * jarg1, char * jarg2) { + int jresult ; + switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_asr_handle_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_core_asr_enable_grammar(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_disable_grammar(void * jarg1, char * jarg2) { + int jresult ; + switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_asr_handle_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_core_asr_disable_grammar(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_disable_all_grammars(void * jarg1) { + int jresult ; + switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ; + switch_status_t result; + + arg1 = (switch_asr_handle_t *)jarg1; + result = (switch_status_t)switch_core_asr_disable_all_grammars(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_pause(void * jarg1) { int jresult ; switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ; @@ -18820,6 +18876,98 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_next_get(void * jarg1) } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_enable_grammar_set(void * jarg1, void * jarg2) { + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*arg2)(switch_asr_handle_t *,char const *) = (switch_status_t (*)(switch_asr_handle_t *,char const *)) 0 ; + + arg1 = (switch_asr_interface *)jarg1; + arg2 = (switch_status_t (*)(switch_asr_handle_t *,char const *))jarg2; + if (arg1) (arg1)->asr_enable_grammar = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_enable_grammar_get(void * jarg1) { + void * jresult ; + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*result)(switch_asr_handle_t *,char const *) = 0 ; + + arg1 = (switch_asr_interface *)jarg1; + result = (switch_status_t (*)(switch_asr_handle_t *,char const *)) ((arg1)->asr_enable_grammar); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_grammar_set(void * jarg1, void * jarg2) { + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*arg2)(switch_asr_handle_t *,char const *) = (switch_status_t (*)(switch_asr_handle_t *,char const *)) 0 ; + + arg1 = (switch_asr_interface *)jarg1; + arg2 = (switch_status_t (*)(switch_asr_handle_t *,char const *))jarg2; + if (arg1) (arg1)->asr_disable_grammar = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_grammar_get(void * jarg1) { + void * jresult ; + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*result)(switch_asr_handle_t *,char const *) = 0 ; + + arg1 = (switch_asr_interface *)jarg1; + result = (switch_status_t (*)(switch_asr_handle_t *,char const *)) ((arg1)->asr_disable_grammar); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_all_grammars_set(void * jarg1, void * jarg2) { + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*arg2)(switch_asr_handle_t *) = (switch_status_t (*)(switch_asr_handle_t *)) 0 ; + + arg1 = (switch_asr_interface *)jarg1; + arg2 = (switch_status_t (*)(switch_asr_handle_t *))jarg2; + if (arg1) (arg1)->asr_disable_all_grammars = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_all_grammars_get(void * jarg1) { + void * jresult ; + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*result)(switch_asr_handle_t *) = 0 ; + + arg1 = (switch_asr_interface *)jarg1; + result = (switch_status_t (*)(switch_asr_handle_t *)) ((arg1)->asr_disable_all_grammars); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_feed_dtmf_set(void * jarg1, void * jarg2) { + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*arg2)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *) = (switch_status_t (*)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *)) 0 ; + + arg1 = (switch_asr_interface *)jarg1; + arg2 = (switch_status_t (*)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *))jarg2; + if (arg1) (arg1)->asr_feed_dtmf = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_feed_dtmf_get(void * jarg1) { + void * jresult ; + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*result)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *) = 0 ; + + arg1 = (switch_asr_interface *)jarg1; + result = (switch_status_t (*)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *)) ((arg1)->asr_feed_dtmf); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_asr_interface() { void * jresult ; switch_asr_interface *result = 0 ; @@ -27013,6 +27161,46 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_unload_grammar(void * } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_enable_grammar(void * jarg1, char * jarg2) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_ivr_detect_speech_enable_grammar(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_disable_grammar(void * jarg1, char * jarg2) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_ivr_detect_speech_disable_grammar(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_disable_all_grammars(void * jarg1) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + result = (switch_status_t)switch_ivr_detect_speech_disable_all_grammars(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_set_param_detect_speech(void * jarg1, char * jarg2, char * jarg3) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; @@ -27029,6 +27217,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_set_param_detect_speech(void * jarg } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_start_input_timers(void * jarg1) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + result = (switch_status_t)switch_ivr_detect_speech_start_input_timers(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_record_session(void * jarg1, char * jarg2, unsigned long jarg3, void * jarg4) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 48d585e334..1f02c3f9ee 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -1990,6 +1990,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_core_asr_feed_dtmf(switch_asr_handle ah, switch_dtmf_t dtmf, SWIGTYPE_p_unsigned_long flags) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_feed_dtmf(switch_asr_handle.getCPtr(ah), switch_dtmf_t.getCPtr(dtmf), SWIGTYPE_p_unsigned_long.getCPtr(flags)); + return ret; + } + public static switch_status_t switch_core_asr_check_results(switch_asr_handle ah, SWIGTYPE_p_unsigned_long flags) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_check_results(switch_asr_handle.getCPtr(ah), SWIGTYPE_p_unsigned_long.getCPtr(flags)); return ret; @@ -2010,6 +2015,21 @@ public class freeswitch { return ret; } + public static switch_status_t switch_core_asr_enable_grammar(switch_asr_handle ah, string name) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_enable_grammar(switch_asr_handle.getCPtr(ah), name); + return ret; + } + + public static switch_status_t switch_core_asr_disable_grammar(switch_asr_handle ah, string name) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_disable_grammar(switch_asr_handle.getCPtr(ah), name); + return ret; + } + + public static switch_status_t switch_core_asr_disable_all_grammars(switch_asr_handle ah) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_disable_all_grammars(switch_asr_handle.getCPtr(ah)); + return ret; + } + public static switch_status_t switch_core_asr_pause(switch_asr_handle ah) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_pause(switch_asr_handle.getCPtr(ah)); return ret; @@ -4060,11 +4080,31 @@ public class freeswitch { return ret; } + public static switch_status_t switch_ivr_detect_speech_enable_grammar(SWIGTYPE_p_switch_core_session session, string name) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_enable_grammar(SWIGTYPE_p_switch_core_session.getCPtr(session), name); + return ret; + } + + public static switch_status_t switch_ivr_detect_speech_disable_grammar(SWIGTYPE_p_switch_core_session session, string name) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_disable_grammar(SWIGTYPE_p_switch_core_session.getCPtr(session), name); + return ret; + } + + public static switch_status_t switch_ivr_detect_speech_disable_all_grammars(SWIGTYPE_p_switch_core_session session) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_disable_all_grammars(SWIGTYPE_p_switch_core_session.getCPtr(session)); + return ret; + } + public static switch_status_t switch_ivr_set_param_detect_speech(SWIGTYPE_p_switch_core_session session, string name, string val) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_set_param_detect_speech(SWIGTYPE_p_switch_core_session.getCPtr(session), name, val); return ret; } + public static switch_status_t switch_ivr_detect_speech_start_input_timers(SWIGTYPE_p_switch_core_session session) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_start_input_timers(SWIGTYPE_p_switch_core_session.getCPtr(session)); + return ret; + } + public static switch_status_t switch_ivr_record_session(SWIGTYPE_p_switch_core_session session, string file, uint limit, switch_file_handle fh) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_record_session(SWIGTYPE_p_switch_core_session.getCPtr(session), file, limit, switch_file_handle.getCPtr(fh)); return ret; @@ -7893,6 +7933,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_feed")] public static extern int switch_core_asr_feed(HandleRef jarg1, HandleRef jarg2, uint jarg3, HandleRef jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_feed_dtmf")] + public static extern int switch_core_asr_feed_dtmf(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_check_results")] public static extern int switch_core_asr_check_results(HandleRef jarg1, HandleRef jarg2); @@ -7905,6 +7948,15 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_unload_grammar")] public static extern int switch_core_asr_unload_grammar(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_enable_grammar")] + public static extern int switch_core_asr_enable_grammar(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_disable_grammar")] + public static extern int switch_core_asr_disable_grammar(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_disable_all_grammars")] + public static extern int switch_core_asr_disable_all_grammars(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_pause")] public static extern int switch_core_asr_pause(HandleRef jarg1); @@ -10182,6 +10234,30 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_next_get")] public static extern IntPtr switch_asr_interface_next_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_enable_grammar_set")] + public static extern void switch_asr_interface_asr_enable_grammar_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_enable_grammar_get")] + public static extern IntPtr switch_asr_interface_asr_enable_grammar_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_grammar_set")] + public static extern void switch_asr_interface_asr_disable_grammar_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_grammar_get")] + public static extern IntPtr switch_asr_interface_asr_disable_grammar_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_all_grammars_set")] + public static extern void switch_asr_interface_asr_disable_all_grammars_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_all_grammars_get")] + public static extern IntPtr switch_asr_interface_asr_disable_all_grammars_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_feed_dtmf_set")] + public static extern void switch_asr_interface_asr_feed_dtmf_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_feed_dtmf_get")] + public static extern IntPtr switch_asr_interface_asr_feed_dtmf_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_asr_interface")] public static extern IntPtr new_switch_asr_interface(); @@ -12126,9 +12202,21 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_unload_grammar")] public static extern int switch_ivr_detect_speech_unload_grammar(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_enable_grammar")] + public static extern int switch_ivr_detect_speech_enable_grammar(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_disable_grammar")] + public static extern int switch_ivr_detect_speech_disable_grammar(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_disable_all_grammars")] + public static extern int switch_ivr_detect_speech_disable_all_grammars(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_set_param_detect_speech")] public static extern int switch_ivr_set_param_detect_speech(HandleRef jarg1, string jarg2, string jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_start_input_timers")] + public static extern int switch_ivr_detect_speech_start_input_timers(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_record_session")] public static extern int switch_ivr_record_session(HandleRef jarg1, string jarg2, uint jarg3, HandleRef jarg4); @@ -14943,6 +15031,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_switch_asr_handle_p_unsigned_long__switch_status_t { private HandleRef swigCPtr; @@ -19959,6 +20077,50 @@ public class switch_asr_interface : IDisposable { } } + public SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t asr_enable_grammar { + set { + freeswitchPINVOKE.switch_asr_interface_asr_enable_grammar_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_enable_grammar_get(swigCPtr); + SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t(cPtr, false); + return ret; + } + } + + public SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t asr_disable_grammar { + set { + freeswitchPINVOKE.switch_asr_interface_asr_disable_grammar_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_disable_grammar_get(swigCPtr); + SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t(cPtr, false); + return ret; + } + } + + public SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t asr_disable_all_grammars { + set { + freeswitchPINVOKE.switch_asr_interface_asr_disable_all_grammars_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_disable_all_grammars_get(swigCPtr); + SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t(cPtr, false); + return ret; + } + } + + public SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t asr_feed_dtmf { + set { + freeswitchPINVOKE.switch_asr_interface_asr_feed_dtmf_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_feed_dtmf_get(swigCPtr); + SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t(cPtr, false); + return ret; + } + } + public switch_asr_interface() : this(freeswitchPINVOKE.new_switch_asr_interface(), true) { } From 86d5e441da872719faf72e24afdda85d8491406b Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 31 Jan 2011 19:38:57 -0500 Subject: [PATCH 29/86] add more details to xml_curl errors --- src/mod/xml_int/mod_xml_curl/mod_xml_curl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c b/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c index 9bf837e1e4..bc143d7e48 100644 --- a/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c +++ b/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c @@ -293,12 +293,12 @@ static switch_xml_t xml_url_fetch(const char *section, const char *tag_name, con } if (config_data.err) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error encountered!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error encountered! [%s]\ndata: [%s]\n", binding->url, data); xml = NULL; } else { if (httpRes == 200) { if (!(xml = switch_xml_parse_file(filename))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing Result!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing Result! [%s]\ndata: [%s]\n", binding->url, data); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received HTTP error %ld trying to fetch %s\ndata: [%s]\n", httpRes, binding->url, From e88b9639624cef4f35901146241f515730b3b118 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 31 Jan 2011 22:08:37 -0600 Subject: [PATCH 30/86] vs2010 reswig --- .../mod_managed/freeswitch_wrap.2010.cxx | 196 ++++++++++++++++++ .../mod_managed/managed/swig.2010.cs | 168 ++++++++++++++- 2 files changed, 362 insertions(+), 2 deletions(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index 9ebd6ff9df..808d548bdf 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -8947,6 +8947,22 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_feed(void * jarg1, void * jarg } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_feed_dtmf(void * jarg1, void * jarg2, void * jarg3) { + int jresult ; + switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ; + switch_dtmf_t *arg2 = (switch_dtmf_t *) 0 ; + switch_asr_flag_t *arg3 = (switch_asr_flag_t *) 0 ; + switch_status_t result; + + arg1 = (switch_asr_handle_t *)jarg1; + arg2 = (switch_dtmf_t *)jarg2; + arg3 = (switch_asr_flag_t *)jarg3; + result = (switch_status_t)switch_core_asr_feed_dtmf(arg1,(switch_dtmf_t const *)arg2,arg3); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_check_results(void * jarg1, void * jarg2) { int jresult ; switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ; @@ -9007,6 +9023,46 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_unload_grammar(void * jarg1, c } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_enable_grammar(void * jarg1, char * jarg2) { + int jresult ; + switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_asr_handle_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_core_asr_enable_grammar(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_disable_grammar(void * jarg1, char * jarg2) { + int jresult ; + switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_asr_handle_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_core_asr_disable_grammar(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_disable_all_grammars(void * jarg1) { + int jresult ; + switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ; + switch_status_t result; + + arg1 = (switch_asr_handle_t *)jarg1; + result = (switch_status_t)switch_core_asr_disable_all_grammars(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_asr_pause(void * jarg1) { int jresult ; switch_asr_handle_t *arg1 = (switch_asr_handle_t *) 0 ; @@ -18313,6 +18369,94 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_next_get(void * jarg1) } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_enable_grammar_set(void * jarg1, void * jarg2) { + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*arg2)(switch_asr_handle_t *,char const *) = (switch_status_t (*)(switch_asr_handle_t *,char const *)) 0 ; + + arg1 = (switch_asr_interface *)jarg1; + arg2 = (switch_status_t (*)(switch_asr_handle_t *,char const *))jarg2; + if (arg1) (arg1)->asr_enable_grammar = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_enable_grammar_get(void * jarg1) { + void * jresult ; + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*result)(switch_asr_handle_t *,char const *) = 0 ; + + arg1 = (switch_asr_interface *)jarg1; + result = (switch_status_t (*)(switch_asr_handle_t *,char const *)) ((arg1)->asr_enable_grammar); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_grammar_set(void * jarg1, void * jarg2) { + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*arg2)(switch_asr_handle_t *,char const *) = (switch_status_t (*)(switch_asr_handle_t *,char const *)) 0 ; + + arg1 = (switch_asr_interface *)jarg1; + arg2 = (switch_status_t (*)(switch_asr_handle_t *,char const *))jarg2; + if (arg1) (arg1)->asr_disable_grammar = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_grammar_get(void * jarg1) { + void * jresult ; + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*result)(switch_asr_handle_t *,char const *) = 0 ; + + arg1 = (switch_asr_interface *)jarg1; + result = (switch_status_t (*)(switch_asr_handle_t *,char const *)) ((arg1)->asr_disable_grammar); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_all_grammars_set(void * jarg1, void * jarg2) { + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*arg2)(switch_asr_handle_t *) = (switch_status_t (*)(switch_asr_handle_t *)) 0 ; + + arg1 = (switch_asr_interface *)jarg1; + arg2 = (switch_status_t (*)(switch_asr_handle_t *))jarg2; + if (arg1) (arg1)->asr_disable_all_grammars = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_disable_all_grammars_get(void * jarg1) { + void * jresult ; + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*result)(switch_asr_handle_t *) = 0 ; + + arg1 = (switch_asr_interface *)jarg1; + result = (switch_status_t (*)(switch_asr_handle_t *)) ((arg1)->asr_disable_all_grammars); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_interface_asr_feed_dtmf_set(void * jarg1, void * jarg2) { + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*arg2)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *) = (switch_status_t (*)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *)) 0 ; + + arg1 = (switch_asr_interface *)jarg1; + arg2 = (switch_status_t (*)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *))jarg2; + if (arg1) (arg1)->asr_feed_dtmf = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_interface_asr_feed_dtmf_get(void * jarg1) { + void * jresult ; + switch_asr_interface *arg1 = (switch_asr_interface *) 0 ; + switch_status_t (*result)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *) = 0 ; + + arg1 = (switch_asr_interface *)jarg1; + result = (switch_status_t (*)(switch_asr_handle_t *,switch_dtmf_t const *,switch_asr_flag_t *)) ((arg1)->asr_feed_dtmf); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_asr_interface() { void * jresult ; switch_asr_interface *result = 0 ; @@ -26320,6 +26464,46 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_unload_grammar(void * } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_enable_grammar(void * jarg1, char * jarg2) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_ivr_detect_speech_enable_grammar(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_disable_grammar(void * jarg1, char * jarg2) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_ivr_detect_speech_disable_grammar(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_disable_all_grammars(void * jarg1) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + result = (switch_status_t)switch_ivr_detect_speech_disable_all_grammars(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_set_param_detect_speech(void * jarg1, char * jarg2, char * jarg3) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; @@ -26336,6 +26520,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_set_param_detect_speech(void * jarg } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_detect_speech_start_input_timers(void * jarg1) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + result = (switch_status_t)switch_ivr_detect_speech_start_input_timers(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_record_session(void * jarg1, char * jarg2, unsigned long jarg3, void * jarg4) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.2010.cs b/src/mod/languages/mod_managed/managed/swig.2010.cs index 059fb89a1c..61c0a4e462 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -2000,6 +2000,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_core_asr_feed_dtmf(switch_asr_handle ah, switch_dtmf_t dtmf, SWIGTYPE_p_unsigned_long flags) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_feed_dtmf(switch_asr_handle.getCPtr(ah), switch_dtmf_t.getCPtr(dtmf), SWIGTYPE_p_unsigned_long.getCPtr(flags)); + return ret; + } + public static switch_status_t switch_core_asr_check_results(switch_asr_handle ah, SWIGTYPE_p_unsigned_long flags) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_check_results(switch_asr_handle.getCPtr(ah), SWIGTYPE_p_unsigned_long.getCPtr(flags)); return ret; @@ -2020,6 +2025,21 @@ public class freeswitch { return ret; } + public static switch_status_t switch_core_asr_enable_grammar(switch_asr_handle ah, string name) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_enable_grammar(switch_asr_handle.getCPtr(ah), name); + return ret; + } + + public static switch_status_t switch_core_asr_disable_grammar(switch_asr_handle ah, string name) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_disable_grammar(switch_asr_handle.getCPtr(ah), name); + return ret; + } + + public static switch_status_t switch_core_asr_disable_all_grammars(switch_asr_handle ah) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_disable_all_grammars(switch_asr_handle.getCPtr(ah)); + return ret; + } + public static switch_status_t switch_core_asr_pause(switch_asr_handle ah) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_asr_pause(switch_asr_handle.getCPtr(ah)); return ret; @@ -4070,11 +4090,31 @@ public class freeswitch { return ret; } + public static switch_status_t switch_ivr_detect_speech_enable_grammar(SWIGTYPE_p_switch_core_session session, string name) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_enable_grammar(SWIGTYPE_p_switch_core_session.getCPtr(session), name); + return ret; + } + + public static switch_status_t switch_ivr_detect_speech_disable_grammar(SWIGTYPE_p_switch_core_session session, string name) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_disable_grammar(SWIGTYPE_p_switch_core_session.getCPtr(session), name); + return ret; + } + + public static switch_status_t switch_ivr_detect_speech_disable_all_grammars(SWIGTYPE_p_switch_core_session session) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_disable_all_grammars(SWIGTYPE_p_switch_core_session.getCPtr(session)); + return ret; + } + public static switch_status_t switch_ivr_set_param_detect_speech(SWIGTYPE_p_switch_core_session session, string name, string val) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_set_param_detect_speech(SWIGTYPE_p_switch_core_session.getCPtr(session), name, val); return ret; } + public static switch_status_t switch_ivr_detect_speech_start_input_timers(SWIGTYPE_p_switch_core_session session) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_detect_speech_start_input_timers(SWIGTYPE_p_switch_core_session.getCPtr(session)); + return ret; + } + public static switch_status_t switch_ivr_record_session(SWIGTYPE_p_switch_core_session session, string file, uint limit, switch_file_handle fh) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_record_session(SWIGTYPE_p_switch_core_session.getCPtr(session), file, limit, switch_file_handle.getCPtr(fh)); return ret; @@ -7907,6 +7947,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_feed")] public static extern int switch_core_asr_feed(HandleRef jarg1, HandleRef jarg2, uint jarg3, HandleRef jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_feed_dtmf")] + public static extern int switch_core_asr_feed_dtmf(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_check_results")] public static extern int switch_core_asr_check_results(HandleRef jarg1, HandleRef jarg2); @@ -7919,6 +7962,15 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_unload_grammar")] public static extern int switch_core_asr_unload_grammar(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_enable_grammar")] + public static extern int switch_core_asr_enable_grammar(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_disable_grammar")] + public static extern int switch_core_asr_disable_grammar(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_disable_all_grammars")] + public static extern int switch_core_asr_disable_all_grammars(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_asr_pause")] public static extern int switch_core_asr_pause(HandleRef jarg1); @@ -10196,6 +10248,30 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_next_get")] public static extern IntPtr switch_asr_interface_next_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_enable_grammar_set")] + public static extern void switch_asr_interface_asr_enable_grammar_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_enable_grammar_get")] + public static extern IntPtr switch_asr_interface_asr_enable_grammar_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_grammar_set")] + public static extern void switch_asr_interface_asr_disable_grammar_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_grammar_get")] + public static extern IntPtr switch_asr_interface_asr_disable_grammar_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_all_grammars_set")] + public static extern void switch_asr_interface_asr_disable_all_grammars_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_disable_all_grammars_get")] + public static extern IntPtr switch_asr_interface_asr_disable_all_grammars_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_feed_dtmf_set")] + public static extern void switch_asr_interface_asr_feed_dtmf_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_interface_asr_feed_dtmf_get")] + public static extern IntPtr switch_asr_interface_asr_feed_dtmf_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_asr_interface")] public static extern IntPtr new_switch_asr_interface(); @@ -12140,9 +12216,21 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_unload_grammar")] public static extern int switch_ivr_detect_speech_unload_grammar(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_enable_grammar")] + public static extern int switch_ivr_detect_speech_enable_grammar(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_disable_grammar")] + public static extern int switch_ivr_detect_speech_disable_grammar(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_disable_all_grammars")] + public static extern int switch_ivr_detect_speech_disable_all_grammars(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_set_param_detect_speech")] public static extern int switch_ivr_set_param_detect_speech(HandleRef jarg1, string jarg2, string jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_detect_speech_start_input_timers")] + public static extern int switch_ivr_detect_speech_start_input_timers(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_record_session")] public static extern int switch_ivr_record_session(HandleRef jarg1, string jarg2, uint jarg3, HandleRef jarg4); @@ -14967,6 +15055,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_switch_asr_handle_p_unsigned_long__switch_status_t { private HandleRef swigCPtr; @@ -19993,6 +20111,50 @@ public class switch_asr_interface : IDisposable { } } + public SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t asr_enable_grammar { + set { + freeswitchPINVOKE.switch_asr_interface_asr_enable_grammar_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_enable_grammar_get(swigCPtr); + SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t(cPtr, false); + return ret; + } + } + + public SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t asr_disable_grammar { + set { + freeswitchPINVOKE.switch_asr_interface_asr_disable_grammar_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_disable_grammar_get(swigCPtr); + SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__char__switch_status_t(cPtr, false); + return ret; + } + } + + public SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t asr_disable_all_grammars { + set { + freeswitchPINVOKE.switch_asr_interface_asr_disable_all_grammars_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_disable_all_grammars_get(swigCPtr); + SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle__switch_status_t(cPtr, false); + return ret; + } + } + + public SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t asr_feed_dtmf { + set { + freeswitchPINVOKE.switch_asr_interface_asr_feed_dtmf_set(swigCPtr, SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_asr_feed_dtmf_get(swigCPtr); + SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_asr_handle_p_q_const__switch_dtmf_t_p_unsigned_long__switch_status_t(cPtr, false); + return ret; + } + } + public switch_asr_interface() : this(freeswitchPINVOKE.new_switch_asr_interface(), true) { } @@ -28589,7 +28751,8 @@ public enum switch_rtp_bug_flag_t { RTP_BUG_IGNORE_MARK_BIT = (1 << 2), RTP_BUG_SEND_LINEAR_TIMESTAMPS = (1 << 3), RTP_BUG_START_SEQ_AT_ZERO = (1 << 4), - RTP_BUG_NEVER_SEND_MARKER = (1 << 5) + RTP_BUG_NEVER_SEND_MARKER = (1 << 5), + RTP_BUG_IGNORE_DTMF_DURATION = (1 << 6) } } @@ -30446,7 +30609,7 @@ public enum switch_status_t { SWITCH_STATUS_FALSE, SWITCH_STATUS_TIMEOUT, SWITCH_STATUS_RESTART, - SWITCH_STATUS_TERM, + SWITCH_STATUS_INTR, SWITCH_STATUS_NOTIMPL, SWITCH_STATUS_MEMERR, SWITCH_STATUS_NOOP, @@ -30463,6 +30626,7 @@ public enum switch_status_t { SWITCH_STATUS_TOO_SMALL, SWITCH_STATUS_FOUND, SWITCH_STATUS_CONTINUE, + SWITCH_STATUS_TERM, SWITCH_STATUS_NOT_INITALIZED } From 2d6161e889fdaf8b03608fefdd7ef480a56ddf8b Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Tue, 1 Feb 2011 01:33:08 -0500 Subject: [PATCH 31/86] switch_xml: Fix a lock on reloadxml when stderr write is blocked. Also remove an error parsing print since reason generated were wrong and duplicate. --- src/switch_xml.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/switch_xml.c b/src/switch_xml.c index fe6a19949d..964a7694b2 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -1286,9 +1286,7 @@ static int preprocess_glob(const char *cwd, const char *pattern, int write_fd, i } if (glob(pattern, GLOB_NOCHECK, NULL, &glob_data) != 0) { - if (stderr) { - fprintf(stderr, "Error including %s\n", pattern); - } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error including %s\n", pattern); goto end; } @@ -1299,11 +1297,9 @@ static int preprocess_glob(const char *cwd, const char *pattern, int write_fd, i *e = '\0'; } if (preprocess(dir_path, glob_data.gl_pathv[n], write_fd, rlevel) < 0) { - const char *reason = strerror(errno); if (rlevel > 100) { - reason = "Maximum recursion limit reached"; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error including %s (Maximum recursion limit reached)\n", pattern); } - fprintf(stderr, "Error including %s (%s)\n", pattern, reason); } free(dir_path); } From 33848eb01c327b04ad3c34bb5165bb1e01891863 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Tue, 1 Feb 2011 08:54:53 +0100 Subject: [PATCH 32/86] Skinny: handle Enbloc messages --- .../endpoints/mod_skinny/skinny_protocol.h | 8 ++++++ src/mod/endpoints/mod_skinny/skinny_server.c | 25 +++++++++++++++++++ src/mod/endpoints/mod_skinny/skinny_tables.c | 1 + src/mod/endpoints/mod_skinny/skinny_tables.h | 2 +- 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index 20e7d7f92f..1a26558ffc 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -68,6 +68,13 @@ struct PACKED keypad_button_message { uint32_t call_id; }; +/* EnblocCallMessage */ +#define ENBLOC_CALL_MESSAGE 0x0004 +struct PACKED enbloc_call_message { + char called_party[24]; + uint32_t line_instance; +}; + /* StimulusMessage */ #define STIMULUS_MESSAGE 0x0005 struct PACKED stimulus_message { @@ -562,6 +569,7 @@ union skinny_data { struct register_message reg; struct port_message port; struct keypad_button_message keypad_button; + struct enbloc_call_message enbloc_call; struct stimulus_message stimulus; struct off_hook_message off_hook; struct on_hook_message on_hook; diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index 5874be4c6c..e7c761dfca 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -1171,6 +1171,29 @@ switch_status_t skinny_handle_keypad_button_message(listener_t *listener, skinny return SWITCH_STATUS_SUCCESS; } +switch_status_t skinny_handle_enbloc_call_message(listener_t *listener, skinny_message_t *request) +{ + uint32_t line_instance = 1; + switch_core_session_t *session = NULL; + + skinny_check_data_length(request, sizeof(request->data.enbloc_call.called_party)); + + if(skinny_check_data_length_soft(request, sizeof(request->data.enbloc_call))) { + if (request->data.enbloc_call.line_instance > 0) { + line_instance = request->data.enbloc_call.line_instance; + } + } + + session = skinny_profile_find_session(listener->profile, listener, &line_instance, 0); + + if(session) { + skinny_session_process_dest(session, listener, line_instance, request->data.enbloc_call.called_party, '\0', 0); + switch_core_session_rwunlock(session); + } + + return SWITCH_STATUS_SUCCESS; +} + switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_message_t *request) { switch_status_t status = SWITCH_STATUS_SUCCESS; @@ -2004,6 +2027,8 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re return skinny_handle_port_message(listener, request); case KEYPAD_BUTTON_MESSAGE: return skinny_handle_keypad_button_message(listener, request); + case ENBLOC_CALL_MESSAGE: + return skinny_handle_enbloc_call_message(listener, request); case STIMULUS_MESSAGE: return skinny_handle_stimulus_message(listener, request); case OFF_HOOK_MESSAGE: diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c index 053b350b46..466a70538d 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.c +++ b/src/mod/endpoints/mod_skinny/skinny_tables.c @@ -39,6 +39,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { {"RegisterMessage", REGISTER_MESSAGE}, {"PortMessage", PORT_MESSAGE}, {"KeypadButtonMessage", KEYPAD_BUTTON_MESSAGE}, + {"EnblocCallMessage", ENBLOC_CALL_MESSAGE}, {"StimulusMessage", STIMULUS_MESSAGE}, {"OffHookMessage", OFF_HOOK_MESSAGE}, {"OnHookMessage", ON_HOOK_MESSAGE}, diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h index c119e1f141..bc92f9f4bf 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.h +++ b/src/mod/endpoints/mod_skinny/skinny_tables.h @@ -87,7 +87,7 @@ uint32_t func(const char *str)\ } -extern struct skinny_table SKINNY_MESSAGE_TYPES[66]; +extern struct skinny_table SKINNY_MESSAGE_TYPES[67]; const char *skinny_message_type2str(uint32_t id); uint32_t skinny_str2message_type(const char *str); #define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES) From 52bf0423e2231e7e16126baa13b8fef14132ac57 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Feb 2011 11:23:32 -0600 Subject: [PATCH 33/86] try to fix SOA problem with early and answer audio with dissimilar sdp --- src/mod/endpoints/mod_sofia/mod_sofia.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 6c91ce1274..8bceb3bba5 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -707,11 +707,20 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) cid = generate_pai_str(tech_pvt); - if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) && tech_pvt->early_sdp && strcmp(tech_pvt->early_sdp, tech_pvt->local_sdp_str)) { - /* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless - we do so in this case we will abandon the SOA rules and go rogue. - */ - sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA); + if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) && tech_pvt->early_sdp) { + char *a, *b; + + /* start at the s= line to avoid some devices who update the o= between messages */ + a = strstr(tech_pvt->early_sdp, "s="); + b = strstr(tech_pvt->local_sdp_str, "s="); + + if (!a || !b || strcmp(a, b)) { + + /* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless + we do so in this case we will abandon the SOA rules and go rogue. + */ + sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA); + } } if (sofia_use_soa(tech_pvt)) { From 45b3adda57a9281d0dd4389884d2a42eebc7dbba Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Feb 2011 11:43:02 -0600 Subject: [PATCH 34/86] revert 02d1af647bac6b937de02608d53ea1831f51b968 --- src/mod/endpoints/mod_loopback/mod_loopback.c | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index aa57668718..f875f6b804 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -77,11 +77,11 @@ struct private_object { switch_frame_t cng_frame; unsigned char cng_databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; + switch_timer_t timer; switch_caller_profile_t *caller_profile; int32_t bowout_frame_count; char *other_uuid; switch_queue_t *frame_queue; - switch_codec_implementation_t read_impl; }; typedef struct private_object private_t; @@ -111,6 +111,7 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses int interval = 20; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_channel_t *channel = switch_core_session_get_channel(session); + const switch_codec_implementation_t *read_impl; if (codec) { iananame = codec->implementation->iananame; @@ -165,7 +166,15 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses switch_core_session_set_read_codec(session, &tech_pvt->read_codec); switch_core_session_set_write_codec(session, &tech_pvt->write_codec); - tech_pvt->read_impl = *tech_pvt->read_codec.implementation; + if (tech_pvt->flag_mutex) { + switch_core_timer_destroy(&tech_pvt->timer); + } + + read_impl = tech_pvt->read_codec.implementation; + + switch_core_timer_init(&tech_pvt->timer, "soft", + read_impl->microseconds_per_packet / 1000, read_impl->samples_per_packet * 4, switch_core_session_get_pool(session)); + if (!tech_pvt->flag_mutex) { switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); @@ -367,6 +376,7 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session) tech_pvt = switch_core_session_get_private(session); if (tech_pvt) { + switch_core_timer_destroy(&tech_pvt->timer); if (switch_core_codec_ready(&tech_pvt->read_codec)) { switch_core_codec_destroy(&tech_pvt->read_codec); @@ -558,10 +568,12 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch goto end; } + switch_core_timer_next(&tech_pvt->timer); + mutex = tech_pvt->mutex; + switch_mutex_lock(mutex); - - if (switch_queue_pop_timeout(tech_pvt->frame_queue, &pop, tech_pvt->read_impl.microseconds_per_packet) == SWITCH_STATUS_SUCCESS && pop) { + if (switch_queue_trypop(tech_pvt->frame_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { if (tech_pvt->write_frame) { switch_frame_free(&tech_pvt->write_frame); } @@ -573,8 +585,6 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch switch_set_flag(tech_pvt, TFLAG_CNG); } - switch_mutex_lock(mutex); - if (switch_test_flag(tech_pvt, TFLAG_CNG)) { unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE]; uint32_t flag = 0; @@ -765,6 +775,8 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s switch_frame_free(&frame); } + switch_core_timer_sync(&tech_pvt->timer); + } break; default: From 2404dd295aa0b6ef2e9da1598a4b3d479ee6317f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Feb 2011 11:46:15 -0600 Subject: [PATCH 35/86] try another approach to previous mod_loopback fix ... FS-3011 --- src/mod/endpoints/mod_loopback/mod_loopback.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index f875f6b804..727de27138 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -608,9 +608,9 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch if (encode_status != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); } - + } else { + switch_set_flag((&tech_pvt->cng_frame), SFF_CNG); } - //switch_set_flag((&tech_pvt->cng_frame), SFF_CNG); switch_clear_flag_locked(tech_pvt, TFLAG_CNG); } @@ -642,7 +642,10 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); - if (switch_test_flag(frame, SFF_CNG) || switch_test_flag(tech_pvt, TFLAG_CNG) || (switch_test_flag(tech_pvt, TFLAG_BOWOUT) && switch_test_flag(tech_pvt, TFLAG_BOWOUT_USED))) { + if (switch_test_flag(frame, SFF_CNG) || + switch_test_flag(tech_pvt, TFLAG_CNG) || (switch_test_flag(tech_pvt, TFLAG_BOWOUT) && switch_test_flag(tech_pvt, TFLAG_BOWOUT_USED))) { + switch_core_timer_sync(&tech_pvt->timer); + switch_core_timer_sync(&tech_pvt->other_tech_pvt->timer); return SWITCH_STATUS_SUCCESS; } From d72cde9b76a856cf002366300bea02c26db44ffb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Feb 2011 13:39:36 -0600 Subject: [PATCH 36/86] only execute execute_on_[answer|media|ring] async when its expressed in app::arg form vs 'app arg form' --- src/switch_channel.c | 47 +++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/src/switch_channel.c b/src/switch_channel.c index de472a91d5..70b1879274 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2595,14 +2595,15 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_ring_ready_value(swi if (var) { char *arg = NULL; app = switch_core_session_strdup(channel->session, var); - if ((arg = strchr(app, ' '))) { - *arg++ = '\0'; - } - if (switch_core_session_in_thread(channel->session)) { - switch_core_session_execute_application(channel->session, app, arg); - } else { + if (strstr(app, "::")) { switch_core_session_execute_application_async(channel->session, app, arg); + } else { + if ((arg = strchr(app, ' '))) { + *arg++ = '\0'; + } + + switch_core_session_execute_application(channel->session, app, arg); } } @@ -2653,14 +2654,16 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_ (var = switch_channel_get_variable(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE))) && !zstr(var)) { char *arg = NULL; app = switch_core_session_strdup(channel->session, var); - if ((arg = strchr(app, ' '))) { - *arg++ = '\0'; - } - if (switch_core_session_in_thread(channel->session)) { - switch_core_session_execute_application(channel->session, app, arg); - } else { + + if (strstr(app, "::")) { switch_core_session_execute_application_async(channel->session, app, arg); + } else { + if ((arg = strchr(app, ' '))) { + *arg++ = '\0'; + } + + switch_core_session_execute_application(channel->session, app, arg); } } @@ -2825,27 +2828,17 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_chan (!switch_channel_test_flag(channel, CF_EARLY_MEDIA) && (var = switch_channel_get_variable(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE)))) && !zstr(var)) { char *arg = NULL; - char *colon = NULL; app = switch_core_session_strdup(channel->session, var); - arg = strchr(app, ' '); - colon = strchr(app, ':'); - if (colon && (!arg || arg > colon) && *(colon + 1) == ':') { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s execute on answer: %s (BROADCAST)\n", channel->name, app); - switch_ivr_broadcast(switch_core_session_get_uuid(channel->session), app, SMF_NONE); + if (strstr(app, "::")) { + switch_core_session_execute_application_async(channel->session, app, arg); } else { - if (arg) { + if ((arg = strchr(app, ' '))) { *arg++ = '\0'; } - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s execute on answer: %s(%s)\n", channel->name, app, - switch_str_nil(arg)); - - if (switch_core_session_in_thread(channel->session)) { - switch_core_session_execute_application(channel->session, app, arg); - } else { - switch_core_session_execute_application_async(channel->session, app, arg); - } + + switch_core_session_execute_application(channel->session, app, arg); } } From 6a524a1d567f9e73d10d14067212bda5f67b7ffb Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 1 Feb 2011 14:54:53 -0500 Subject: [PATCH 37/86] chlog: freetdm: Fix for only checking first progress indicator for early-media flag --- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index 0b52011d42..578677a39f 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -385,8 +385,12 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_DIALING: case FTDM_CHANNEL_STATE_PROCEED: case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_RINGING: - if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) { + case FTDM_CHANNEL_STATE_RINGING: + if ((cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) || + (cnStEvnt->progInd1.eh.pres && cnStEvnt->progInd1.progDesc.val == IN_PD_IBAVAIL) || + (cnStEvnt->progInd2.eh.pres && cnStEvnt->progInd2.progDesc.val == IN_PD_IBAVAIL) || + (cnStEvnt->progInd3.eh.pres && cnStEvnt->progInd3.progDesc.val == IN_PD_IBAVAIL)) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media available\n"); sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); } else { From ae4b2873b0e56090658953f503157166825b66bc Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 1 Feb 2011 15:41:23 -0500 Subject: [PATCH 38/86] chlog: freetdm: isdn: fix for 5ESS call clearing procedures --- .../src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index df528ae9c1..97984fbfab 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -683,8 +683,8 @@ static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdm if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) { /* By default, we do not send a progress indicator in the proceed */ ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID}; - sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED); + sngisdn_snd_proceed(ftdmchan, prog_ind); } } @@ -800,6 +800,15 @@ static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdm /* If we never received a PROCEED/ALERT/PROGRESS/CONNECT on an outgoing call, we need to send release instead of disconnect */ sngisdn_snd_release(ftdmchan, 0); break; + case FTDM_CHANNEL_STATE_PROCEED: + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) && + ((sngisdn_span_data_t*)(ftdmchan->span->signal_data))->switchtype == SNGISDN_SWITCH_5ESS) { + + /* When using 5ESS, if the user wants to clear an inbound call, the correct procedure is to send a PROGRESS with in-band info available, and play tones. Then send a DISCONNECT. If we reached this point, it means user did not try to play-tones, so send a RELEASE because remote side does not expect DISCONNECT in state 3 */ + sngisdn_snd_release(ftdmchan, 0); + break; + } + /* fall-through */ default: sngisdn_snd_disconnect(ftdmchan); break; From fb66abfab4a74055c38cdc67da83e6e0175a4a0b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Feb 2011 16:22:36 -0600 Subject: [PATCH 39/86] more loopback improvements --- src/mod/endpoints/mod_loopback/mod_loopback.c | 29 ++++--------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 727de27138..be9b4994d6 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -82,6 +82,7 @@ struct private_object { int32_t bowout_frame_count; char *other_uuid; switch_queue_t *frame_queue; + int64_t packet_count; }; typedef struct private_object private_t; @@ -577,40 +578,22 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch if (tech_pvt->write_frame) { switch_frame_free(&tech_pvt->write_frame); } - + tech_pvt->write_frame = (switch_frame_t *) pop; tech_pvt->write_frame->codec = &tech_pvt->read_codec; *frame = tech_pvt->write_frame; + tech_pvt->packet_count++; + switch_clear_flag_locked(tech_pvt, TFLAG_CNG); + switch_clear_flag(tech_pvt->write_frame, SFF_CNG); } else { switch_set_flag(tech_pvt, TFLAG_CNG); } if (switch_test_flag(tech_pvt, TFLAG_CNG)) { - unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE]; - uint32_t flag = 0; - switch_status_t encode_status; - uint32_t rate = tech_pvt->read_codec.implementation->actual_samples_per_second; - *frame = &tech_pvt->cng_frame; tech_pvt->cng_frame.codec = &tech_pvt->read_codec; tech_pvt->cng_frame.datalen = tech_pvt->read_codec.implementation->decoded_bytes_per_packet; - - memset(tech_pvt->cng_frame.data, 0, tech_pvt->cng_frame.datalen); - memset(&data, 0, tech_pvt->read_codec.implementation->decoded_bytes_per_packet); - - if (strcasecmp(tech_pvt->read_codec.implementation->iananame, "L16")) { - encode_status = switch_core_codec_encode(&tech_pvt->read_codec, - NULL, - data, - tech_pvt->read_codec.implementation->decoded_bytes_per_packet, - tech_pvt->read_codec.implementation->actual_samples_per_second, - tech_pvt->cng_frame.data, &tech_pvt->cng_frame.datalen, &rate, &flag); - if (encode_status != SWITCH_STATUS_SUCCESS) { - switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - } - } else { - switch_set_flag((&tech_pvt->cng_frame), SFF_CNG); - } + switch_set_flag((&tech_pvt->cng_frame), SFF_CNG); switch_clear_flag_locked(tech_pvt, TFLAG_CNG); } From 43dd776c3616f3735bd8b73d965f81e9d16dab79 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 1 Feb 2011 16:35:53 -0600 Subject: [PATCH 40/86] sigh --- libs/openzap/mod_openzap/mod_openzap.c | 30 ++++++++++++++------------ 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/libs/openzap/mod_openzap/mod_openzap.c b/libs/openzap/mod_openzap/mod_openzap.c index 3e5227ea90..d52149c657 100644 --- a/libs/openzap/mod_openzap/mod_openzap.c +++ b/libs/openzap/mod_openzap/mod_openzap.c @@ -135,7 +135,9 @@ void dump_chan_xml(zap_span_t *span, uint32_t chan_id, switch_stream_handle_t *s static void zap_set_npi(const char *npi_string, uint8_t *target) { - if (!strcasecmp(npi_string, "isdn") || !strcasecmp(npi_string, "e164")) { + if (switch_is_number(npi_string)) { + *target = (uint8_t)atoi(npi_string); + } else if (!strcasecmp(npi_string, "isdn") || !strcasecmp(npi_string, "e164")) { *target = ZAP_NPI_ISDN; } else if (!strcasecmp(npi_string, "data")) { *target = ZAP_NPI_DATA; @@ -157,7 +159,9 @@ static void zap_set_npi(const char *npi_string, uint8_t *target) static void zap_set_ton(const char *ton_string, uint8_t *target) { - if (!strcasecmp(ton_string, "national")) { + if (switch_is_number(ton_string)) { + *target = (uint8_t)atoi(ton_string); + } else if (!strcasecmp(ton_string, "national")) { *target = ZAP_TON_NATIONAL; } else if (!strcasecmp(ton_string, "international")) { *target = ZAP_TON_INTERNATIONAL; @@ -1231,15 +1235,8 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi } if ((var = switch_event_get_header(var_event, "openzap_outbound_ton")) || (var = switch_core_get_variable("openzap_outbound_ton"))) { - if (!strcasecmp(var, "national")) { - caller_data.ani.type = ZAP_TON_NATIONAL; - } else if (!strcasecmp(var, "international")) { - caller_data.ani.type = ZAP_TON_INTERNATIONAL; - } else if (!strcasecmp(var, "local")) { - caller_data.ani.type = ZAP_TON_SUBSCRIBER_NUMBER; - } else if (!strcasecmp(var, "unknown")) { - caller_data.ani.type = ZAP_TON_UNKNOWN; - } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting TON to: %s\n", var); + zap_set_ton(var, &caller_data.ani.type); } else { caller_data.ani.type = outbound_profile->destination_number_ton; } @@ -1248,9 +1245,14 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi zap_set_string((char *)caller_data.raw_data, var); caller_data.raw_data_len = strlen(var); } - - caller_data.ani.plan = outbound_profile->destination_number_numplan; - + + if ((var = switch_event_get_header(var_event, "openzap_outbound_npi")) || (var = switch_core_get_variable("openzap_outbound_npi"))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting NPI to: %s\n", var); + zap_set_npi(var, &caller_data.ani.plan); + } else { + caller_data.ani.plan = outbound_profile->destination_number_numplan; + } + /* blindly copy data from outbound_profile. They will be overwritten * by calling zap_caller_data if needed after */ caller_data.cid_num.type = outbound_profile->caller_ton; From 10d696ebacedde5416e99f03911c928eea8889d1 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 2 Feb 2011 00:01:38 -0500 Subject: [PATCH 41/86] Added conference UUID to xml_list --- src/mod/applications/mod_conference/mod_conference.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 12b3193363..961a140342 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -3778,6 +3778,7 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer switch_xml_set_attr_d(x_conference, "member-count", ival); switch_snprintf(i, sizeof(i), "%u", conference->rate); switch_xml_set_attr_d(x_conference, "rate", ival); + switch_xml_set_attr_d(x_conference, "uuid", conference->uuid_str); if (switch_test_flag(conference, CFLAG_LOCKED)) { switch_xml_set_attr_d(x_conference, "locked", "true"); From 57b0710bacb7cc58dee4262fe0c915048e47b7bc Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 2 Feb 2011 11:35:38 -0500 Subject: [PATCH 42/86] freetdm: Fix for typo in print --- libs/freetdm/mod_freetdm/mod_freetdm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 92cf9e54b9..563a203a70 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1570,8 +1570,8 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI2", "%s", channel_caller_data->aniII); switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS", "%s", channel_caller_data->dnis.digits); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS-TON", "%s", channel_caller_data->dnis.type); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS-Plan", "%s", channel_caller_data->dnis.plan); + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS-TON", "%d", channel_caller_data->dnis.type); + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS-Plan", "%d", channel_caller_data->dnis.plan); switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS", "%s", channel_caller_data->rdnis.digits); switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-TON", "%d", channel_caller_data->rdnis.type); From 83dea0ee45a1eed53fe6c7bcac96410229c2fe3c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 2 Feb 2011 10:53:33 -0600 Subject: [PATCH 43/86] FS-3024 --- src/switch_core_sqldb.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 35311c9b0f..2db2a0dd46 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1409,9 +1409,13 @@ static void core_event_handler(switch_event_t *event) } break; case SWITCH_EVENT_CHANNEL_UNBRIDGE: - new_sql() = switch_mprintf("delete from calls where (caller_uuid='%s' or callee_uuid='%q') and hostname='%q'", - switch_event_get_header_nil(event, "caller-unique-id"), switch_core_get_variable("hostname")); - break; + { + char *uuid = switch_event_get_header_nil(event, "caller-unique-id"); + + new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q') and hostname='%q'", + uuid, uuid, switch_core_get_variable("hostname")); + break; + } case SWITCH_EVENT_SHUTDOWN: new_sql() = switch_mprintf("delete from channels where hostname='%q';" "delete from interfaces where hostname='%q';" From 89c5f3bf8226bf605336b66e7761fd9f753d935a Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 2 Feb 2011 11:04:39 -0600 Subject: [PATCH 44/86] FS-3023 --- src/include/switch_cpp.h | 4 ++++ .../languages/mod_managed/freeswitch_wrap.cxx | 24 +++++++++++++++++++ src/mod/languages/mod_managed/managed/swig.cs | 8 +++++++ src/switch_cpp.cpp | 7 ++++++ 4 files changed, 43 insertions(+) diff --git a/src/include/switch_cpp.h b/src/include/switch_cpp.h index 0bd2a8b2b0..f4a0922e58 100644 --- a/src/include/switch_cpp.h +++ b/src/include/switch_cpp.h @@ -68,6 +68,10 @@ Note that the first parameter to the new operator is implicitly handled by c++.. SWITCH_DECLARE(void) consoleLog(char *level_str, char *msg); SWITCH_DECLARE(void) consoleCleanLog(char *msg); +SWITCH_DECLARE(bool) email(char *to, char *from, char *headers = NULL, char *body = NULL, + char *file = NULL, char *convert_cmd = NULL, char *convert_ext = NULL); + + class CoreSession; class IVRMenu { diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index e91de6df46..71e9f99819 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -33352,6 +33352,30 @@ SWIGEXPORT void SWIGSTDCALL CSharp_consoleCleanLog(char * jarg1) { } +SWIGEXPORT unsigned int SWIGSTDCALL CSharp_email(char * jarg1, char * jarg2, char * jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7) { + unsigned int jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) NULL ; + char *arg4 = (char *) NULL ; + char *arg5 = (char *) NULL ; + char *arg6 = (char *) NULL ; + char *arg7 = (char *) NULL ; + bool result; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + arg4 = (char *)jarg4; + arg5 = (char *)jarg5; + arg6 = (char *)jarg6; + arg7 = (char *)jarg7; + result = (bool)email(arg1,arg2,arg3,arg4,arg5,arg6,arg7); + jresult = result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_IvrMenu(void * jarg1, char * jarg2, char * jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10, int jarg11, int jarg12, int jarg13, int jarg14, int jarg15, int jarg16) { void * jresult ; IVRMenu *arg1 = (IVRMenu *) 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 1f02c3f9ee..c640199353 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -5364,6 +5364,11 @@ public class freeswitch { freeswitchPINVOKE.consoleCleanLog(msg); } + public static bool email(string to, string from, string headers, string body, string file, string convert_cmd, string convert_ext) { + bool ret = freeswitchPINVOKE.email(to, from, headers, body, file, convert_cmd, convert_ext); + return ret; + } + public static void console_log(string level_str, string msg) { freeswitchPINVOKE.console_log(level_str, msg); } @@ -13588,6 +13593,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_consoleCleanLog")] public static extern void consoleCleanLog(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_email")] + public static extern bool email(string jarg1, string jarg2, string jarg3, string jarg4, string jarg5, string jarg6, string jarg7); + [DllImport("mod_managed", EntryPoint="CSharp_new_IvrMenu")] public static extern IntPtr new_IvrMenu(HandleRef jarg1, string jarg2, string jarg3, string jarg4, string jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10, int jarg11, int jarg12, int jarg13, int jarg14, int jarg15, int jarg16); diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index bbcd05d21c..c62946b760 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -1195,6 +1195,13 @@ SWITCH_DECLARE(void) console_clean_log(char *msg) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN,SWITCH_LOG_DEBUG, "%s", switch_str_nil(msg)); } +SWITCH_DECLARE(bool) email(char *to, char *from, char *headers, char *body, char *file, char *convert_cmd, char *convert_ext) +{ + if (switch_simple_email(to, from, headers, body, file, convert_cmd, convert_ext) == SWITCH_TRUE) { + return true; + } + return false; +} SWITCH_DECLARE(void) msleep(unsigned ms) { From 4ae8282e6c6df0e296113e9b4b4a1383e1af8ad7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 2 Feb 2011 15:43:26 -0600 Subject: [PATCH 45/86] fix possible bad pointer in global vars (please test) --- src/include/private/switch_core_pvt.h | 1 + src/include/switch_core.h | 3 + src/include/switch_nat.h | 2 +- .../applications/mod_commands/mod_commands.c | 29 +++++++--- .../applications/mod_dptools/mod_dptools.c | 17 +++--- src/mod/applications/mod_redis/mod_redis.c | 10 ++-- .../mod_voicemail/mod_voicemail.c | 6 +- .../mod_dialplan_asterisk.c | 2 +- .../endpoints/mod_dingaling/mod_dingaling.c | 4 +- src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp | 3 +- src/mod/endpoints/mod_sofia/mod_sofia.c | 4 +- src/mod/endpoints/mod_sofia/sofia.c | 11 ++-- .../mod_event_socket/mod_event_socket.c | 4 +- .../formats/mod_file_string/mod_file_string.c | 2 +- .../mod_spidermonkey/mod_spidermonkey.c | 3 +- src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c | 6 +- src/switch_channel.c | 11 ++-- src/switch_console.c | 32 +++++------ src/switch_core.c | 47 ++++++++++++++-- src/switch_core_file.c | 2 +- src/switch_core_sqldb.c | 56 +++++++++---------- src/switch_event.c | 6 +- src/switch_nat.c | 7 +++ src/switch_rtp.c | 4 +- src/switch_utils.c | 10 +++- src/switch_xml.c | 3 +- 26 files changed, 185 insertions(+), 100 deletions(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 30690b1848..05cd24d230 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -246,6 +246,7 @@ struct switch_runtime { int sql_buffer_len; int max_sql_buffer_len; switch_dbtype_t odbc_dbtype; + char hostname[256]; }; extern struct switch_runtime runtime; diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 109a16901b..69b06420a3 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -759,6 +759,9 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_force_locate(_In_z_ \return the value of the desired variable */ SWITCH_DECLARE(char *) switch_core_get_variable(_In_z_ const char *varname); +SWITCH_DECLARE(char *) switch_core_get_variable_dup(_In_z_ const char *varname); +SWITCH_DECLARE(char *) switch_core_get_variable_pdup(_In_z_ const char *varname, switch_memory_pool_t *pool); +SWITCH_DECLARE(const char *) switch_core_get_hostname(void); /*! \brief Add a global variable to the core diff --git a/src/include/switch_nat.h b/src/include/switch_nat.h index bdbd51b592..9e40546345 100644 --- a/src/include/switch_nat.h +++ b/src/include/switch_nat.h @@ -49,7 +49,7 @@ typedef enum { SWITCH_NAT_TCP } switch_nat_ip_proto_t; - +SWITCH_DECLARE(const char *) switch_nat_get_type(void); /*! \brief Initilize the NAT Traversal System diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 7771b0996c..807770ac15 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -349,7 +349,7 @@ SWITCH_STANDARD_API(timer_test_function) SWITCH_STANDARD_API(group_call_function) { - char *domain; + char *domain, *dup_domain = NULL; char *group_name = NULL; char *flags; int ok = 0; @@ -392,7 +392,9 @@ SWITCH_STANDARD_API(group_call_function) if (domain) { *domain++ = '\0'; } else { - domain = switch_core_get_variable("domain"); + if ((dup_domain = switch_core_get_variable_dup("domain"))) { + domain = dup_domain; + } } if (!zstr(domain)) { @@ -544,13 +546,14 @@ SWITCH_STANDARD_API(group_call_function) } end: - + switch_safe_free(group_name); + switch_safe_free(dup_domain); if (!ok) { stream->write_function(stream, "error/NO_ROUTE_DESTINATION"); } - + return SWITCH_STATUS_SUCCESS; } @@ -559,7 +562,7 @@ SWITCH_STANDARD_API(in_group_function) { switch_xml_t x_domain, xml = NULL, x_user = NULL, x_group; int argc; - char *mydata = NULL, *argv[2], *user, *domain; + char *mydata = NULL, *argv[2], *user, *domain, *dup_domain = NULL; char delim = ','; switch_event_t *params = NULL; const char *rval = "false"; @@ -579,7 +582,9 @@ SWITCH_STANDARD_API(in_group_function) if ((domain = strchr(user, '@'))) { *domain++ = '\0'; } else { - domain = switch_core_get_variable("domain"); + if ((dup_domain = switch_core_get_variable_dup("domain"))) { + domain = dup_domain; + } } switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); @@ -601,6 +606,7 @@ SWITCH_STANDARD_API(in_group_function) switch_xml_free(xml); switch_safe_free(mydata); + switch_safe_free(dup_domain); switch_event_destroy(¶ms); return SWITCH_STATUS_SUCCESS; @@ -610,7 +616,7 @@ SWITCH_STANDARD_API(user_data_function) { switch_xml_t x_domain, xml = NULL, x_user = NULL, x_group = NULL, x_param, x_params; int argc; - char *mydata = NULL, *argv[3], *key = NULL, *type = NULL, *user, *domain; + char *mydata = NULL, *argv[3], *key = NULL, *type = NULL, *user, *domain, *dup_domain = NULL; char delim = ' '; const char *container = "params", *elem = "param"; const char *result = NULL; @@ -631,7 +637,9 @@ SWITCH_STANDARD_API(user_data_function) if ((domain = strchr(user, '@'))) { *domain++ = '\0'; } else { - if (!(domain = switch_core_get_variable("domain"))) { + if ((dup_domain = switch_core_get_variable("domain"))) { + domain = dup_domain; + } else { domain = "cluecon.com"; } } @@ -694,6 +702,7 @@ SWITCH_STANDARD_API(user_data_function) } switch_xml_free(xml); switch_safe_free(mydata); + switch_safe_free(dup_domain); switch_event_destroy(¶ms); return SWITCH_STATUS_SUCCESS; @@ -4375,7 +4384,9 @@ SWITCH_STANDARD_API(global_getvar_function) if (zstr(cmd)) { switch_core_dump_variables(stream); } else { - stream->write_function(stream, "%s", switch_str_nil(switch_core_get_variable(cmd))); + char *var = switch_core_get_variable_dup(cmd); + stream->write_function(stream, "%s", switch_str_nil(var)); + switch_safe_free(var); } return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 928a9b8549..4be2a64f61 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -2787,7 +2787,7 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session if ((domain = strchr(group, '@'))) { *domain++ = '\0'; } else { - domain = switch_core_get_variable("domain"); + domain = switch_core_get_variable_pdup("domain", switch_core_session_get_pool(session)); } if (!domain) { @@ -2908,7 +2908,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, if ((domain = strchr(user, '@'))) { *domain++ = '\0'; } else { - domain = switch_core_get_variable("domain"); + domain = switch_core_get_variable_pdup("domain", switch_core_session_get_pool(session)); } if (!domain) { @@ -3193,10 +3193,11 @@ static switch_status_t event_chat_send(const char *proto, const char *from, cons if (body) switch_event_add_body(event, "%s", body); if (to) { - const char *v; + char *v; switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "To", to); - if ((v = switch_core_get_variable(to))) { + if ((v = switch_core_get_variable_dup(to))) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Command", v); + free(v); } } @@ -3214,15 +3215,15 @@ static switch_status_t api_chat_send(const char *proto, const char *from, const const char *body, const char *type, const char *hint) { if (to) { - const char *v; + char *v = NULL; switch_stream_handle_t stream = { 0 }; char *cmd = NULL, *arg; - if (!(v = switch_core_get_variable(to))) { - v = to; + if (!(v = switch_core_get_variable_dup(to))) { + v = strdup(to); } - cmd = strdup(v); + cmd = v; switch_assert(cmd); switch_url_decode(cmd); diff --git a/src/mod/applications/mod_redis/mod_redis.c b/src/mod/applications/mod_redis/mod_redis.c index 1e999675b1..ebf2a9e324 100755 --- a/src/mod/applications/mod_redis/mod_redis.c +++ b/src/mod/applications/mod_redis/mod_redis.c @@ -89,7 +89,7 @@ SWITCH_LIMIT_INCR(limit_incr_redis) } /* Get the keys for redis server */ - uuid_rediskey = switch_core_session_sprintf(session,"%s_%s_%s", switch_core_get_variable("hostname"), realm, resource); + uuid_rediskey = switch_core_session_sprintf(session,"%s_%s_%s", switch_core_get_hostname(), realm, resource); rediskey = switch_core_session_sprintf(session, "%s_%s", realm, resource); if ((pvt = switch_channel_get_private(channel, "limit_redis"))) { @@ -179,7 +179,7 @@ SWITCH_LIMIT_RELEASE(limit_release_redis) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Couldn't decrement value corresponding to %s\n", (char *)p_key); switch_goto_status(SWITCH_STATUS_FALSE, end); } - p_uuid_key = switch_core_session_sprintf(session, "%s_%s", switch_core_get_variable("hostname"), (char *)p_key); + p_uuid_key = switch_core_session_sprintf(session, "%s_%s", switch_core_get_hostname(), (char *)p_key); if (credis_decr(redis,p_uuid_key,&uuid_val) != 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Couldn't decrement value corresponding to %s\n", p_uuid_key); switch_goto_status(SWITCH_STATUS_FALSE, end); @@ -193,7 +193,7 @@ SWITCH_LIMIT_RELEASE(limit_release_redis) } else { rediskey = switch_core_session_sprintf(session, "%s_%s", realm, resource); - uuid_rediskey = switch_core_session_sprintf(session, "%s_%s_%s", switch_core_get_variable("hostname"), realm, resource); + uuid_rediskey = switch_core_session_sprintf(session, "%s_%s_%s", switch_core_get_hostname(), realm, resource); switch_core_hash_delete(pvt->hash, (const char *) rediskey); if (credis_decr(redis, rediskey, &val) != 0) { @@ -249,13 +249,13 @@ SWITCH_LIMIT_RESET(limit_reset_redis) { REDIS redis; if (redis_factory(&redis) == SWITCH_STATUS_SUCCESS) { - char *rediskey = switch_mprintf("%s_*", switch_core_get_variable("hostname")); + char *rediskey = switch_mprintf("%s_*", switch_core_get_hostname()); int dec = 0, val = 0, keyc; char *uuids[2000]; if ((keyc = credis_keys(redis, rediskey, uuids, switch_arraylen(uuids))) > 0) { int i = 0; - int hostnamelen = strlen(switch_core_get_variable("hostname"))+1; + int hostnamelen = strlen(switch_core_get_hostname())+1; for (i = 0; i < keyc && uuids[i]; i++){ const char *key = uuids[i] + hostnamelen; diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 76870f75b9..80b011e189 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -2734,6 +2734,7 @@ static switch_status_t voicemail_inject(const char *data, switch_core_session_t switch_memory_pool_t *pool = NULL; char *forwarded_by = NULL; char *read_flags = NORMAL_FLAG_STRING; + char *dup_domain = NULL; if (zstr(data)) { status = SWITCH_STATUS_FALSE; @@ -2781,7 +2782,9 @@ static switch_status_t voicemail_inject(const char *data, switch_core_session_t } if (zstr(domain)) { - domain = switch_core_get_variable("domain"); + if ((dup_domain = switch_core_get_variable_dup("domain"))) { + domain = dup_domain; + } profile_name = domain; } @@ -2915,6 +2918,7 @@ static switch_status_t voicemail_inject(const char *data, switch_core_session_t end: switch_safe_free(dup); + switch_safe_free(dup_domain); return status; } diff --git a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c index 5869d14c3a..43534dadba 100644 --- a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c +++ b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c @@ -313,7 +313,7 @@ static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, if (session) { profile = switch_channel_get_variable(switch_core_session_get_channel(session), "sip_profile"); } else { - profile = switch_core_get_variable("sip_profile"); + profile = switch_core_get_variable_pdup("sip_profile", switch_core_session_get_pool(session)); } if (zstr(profile)) { profile = "default"; diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 66f62b2295..9fb1f39e11 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -2049,7 +2049,7 @@ static void set_profile_val(mdl_profile_t *profile, char *var, char *val) } else if (!strcasecmp(var, "ext-rtp-ip")) { char *ip = globals.guess_ip; if (val && !strcasecmp(val, "auto-nat")) { - ip = globals.auto_nat ? switch_core_get_variable("nat_public_addr") : globals.guess_ip; + ip = globals.auto_nat ? switch_core_get_variable_pdup("nat_public_addr", module_pool) : globals.guess_ip; } else if (val && !strcasecmp(val, "auto")) { globals.auto_nat = 0; ip = globals.guess_ip; @@ -2523,7 +2523,7 @@ static switch_status_t load_config(void) memset(&globals, 0, sizeof(globals)); globals.running = 1; - globals.auto_nat = (switch_core_get_variable("nat_type") ? 1 : 0); + globals.auto_nat = (switch_nat_get_type() ? 1 : 0); switch_find_local_ip(globals.guess_ip, sizeof(globals.guess_ip), NULL, AF_INET); diff --git a/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp b/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp index 1b126eb277..15009f2286 100644 --- a/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp +++ b/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp @@ -1625,9 +1625,10 @@ bool Board::KhompPvt::setCollectCall() DBG(FUNC, PVT_FMT(_target, "option drop collect call is '%s'") % (Opt::_options._drop_collect_call() ? "yes" : "no")); // get global filter configuration value - tmp_var = switch_core_get_variable("KDropCollectCall"); + tmp_var = switch_core_get_variable_dup("KDropCollectCall"); confvalues.push_back(getTriStateValue(tmp_var)); DBG(FUNC, PVT_FMT(_target, "global KDropCollectCall was '%s'") % (tmp_var ? tmp_var : "(empty)")); + switch_safe_free(tmp_var); try { diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 8bceb3bba5..c78aac7933 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -3501,7 +3501,7 @@ SWITCH_STANDARD_API(sofia_contact_function) } if (zstr(domain)) { - domain = switch_core_get_variable("domain"); + domain = switch_core_get_variable_pdup("domain", switch_core_session_get_pool(session)); } if (!user) goto end; @@ -4776,7 +4776,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) mod_sofia_globals.running = 1; switch_mutex_unlock(mod_sofia_globals.mutex); - mod_sofia_globals.auto_nat = (switch_core_get_variable("nat_type") ? 1 : 0); + mod_sofia_globals.auto_nat = (switch_nat_get_type() ? 1 : 0); switch_queue_create(&mod_sofia_globals.presence_queue, SOFIA_QUEUE_SIZE, mod_sofia_globals.pool); switch_queue_create(&mod_sofia_globals.mwi_queue, SOFIA_QUEUE_SIZE, mod_sofia_globals.pool); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 47f94b151a..825d1bf46e 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1459,7 +1459,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void supported = switch_core_sprintf(profile->pool, "%s%sprecondition, path, replaces", use_100rel ? "100rel, " : "", use_timer ? "timer, " : ""); - if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && switch_core_get_variable("nat_type")) { + if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && switch_nat_get_type()) { if (switch_nat_add_mapping(profile->sip_port, SWITCH_NAT_UDP, NULL, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created UDP nat mapping for %s port %d\n", profile->name, profile->sip_port); } @@ -1676,7 +1676,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void switch_event_fire(&s_event); } - if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && switch_core_get_variable("nat_type")) { + if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && switch_nat_get_type()) { if (switch_nat_del_mapping(profile->sip_port, SWITCH_NAT_UDP) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleted UDP nat mapping for %s port %d\n", profile->name, profile->sip_port); } @@ -3741,9 +3741,9 @@ switch_status_t config_sofia(int reload, char *profile_name) if (!profile->rtpip[0]) { profile->rtpip[profile->rtpip_index++] = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip); } - - if (switch_core_get_variable("nat_type")) { - const char *ip = switch_core_get_variable("nat_public_addr"); + + if (switch_nat_get_type()) { + char *ip = switch_core_get_variable_dup("nat_public_addr"); if (ip && !strchr(profile->sipip, ':')) { if (!profile->extrtpip) { profile->extrtpip = switch_core_strdup(profile->pool, ip); @@ -3754,6 +3754,7 @@ switch_status_t config_sofia(int reload, char *profile_name) sofia_set_pflag(profile, PFLAG_AUTO_NAT); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "NAT detected setting external ip to %s\n", ip); } + switch_safe_free(ip); } if (profile->nonce_ttl < 60) { diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index f3a2c92eb3..1462e4ec54 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -2642,7 +2642,7 @@ static int config(void) } else if (!strcmp(var, "debug")) { globals.debug = atoi(val); } else if (!strcmp(var, "nat-map")) { - if (switch_true(val) && switch_core_get_variable("nat_type")) { + if (switch_true(val) && switch_nat_get_type()) { prefs.nat_map = 1; } } else if (!strcmp(var, "listen-port")) { @@ -2795,7 +2795,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime) close_socket(&listen_list.sock); - if (prefs.nat_map && switch_core_get_variable("nat_type")) { + if (prefs.nat_map && switch_nat_get_type()) { switch_nat_del_mapping(prefs.port, SWITCH_NAT_TCP); } diff --git a/src/mod/formats/mod_file_string/mod_file_string.c b/src/mod/formats/mod_file_string/mod_file_string.c index ca86cbdfcf..7e36c720aa 100644 --- a/src/mod/formats/mod_file_string/mod_file_string.c +++ b/src/mod/formats/mod_file_string/mod_file_string.c @@ -77,7 +77,7 @@ static int next_file(switch_file_handle_t *handle) if (!prefix) { - if (!(prefix = switch_core_get_variable("sound_prefix"))) { + if (!(prefix = switch_core_get_variable_pdup("sound_prefix", handle->memory_pool))) { prefix = SWITCH_GLOBAL_dirs.sounds_dir; } } diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c index 9eb2636f4a..1d6ee8d679 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c @@ -3378,8 +3378,9 @@ static JSBool js_global_get(JSContext * cx, JSObject * obj, uintN argc, jsval * if (argc > 0) { var_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0])); - val = switch_core_get_variable(var_name); + val = switch_core_get_variable_dup(var_name); *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, val)); + free(val); return JS_TRUE; } diff --git a/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c b/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c index 468190d887..9e61312417 100644 --- a/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c +++ b/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c @@ -322,6 +322,7 @@ static abyss_bool http_directory_auth(TSession * r, char *domain_name) int at = 0; char *dp; abyss_bool rval = FALSE; + char *dup_domain = NULL; p = RequestHeaderValue(r, "authorization"); @@ -354,7 +355,9 @@ static abyss_bool http_directory_auth(TSession * r, char *domain_name) if (globals.default_domain) { domain_name = globals.default_domain; } else { - domain_name = switch_core_get_variable("domain"); + if ((dup_domain = switch_core_get_variable_dup("domain"))) { + domain_name = dup_domain; + } } } } @@ -465,6 +468,7 @@ static abyss_bool http_directory_auth(TSession * r, char *domain_name) switch_safe_free(mypass1); switch_safe_free(mypass2); switch_safe_free(box); + switch_safe_free(dup_domain); return rval; } diff --git a/src/switch_channel.c b/src/switch_channel.c index 70b1879274..f750496323 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -672,7 +672,7 @@ SWITCH_DECLARE(const char *) switch_channel_get_hold_music_partner(switch_channe SWITCH_DECLARE(const char *) switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup) { - const char *v = NULL, *r = NULL; + const char *v = NULL, *r = NULL, *vdup = NULL; switch_assert(channel != NULL); switch_mutex_lock(channel->profile_mutex); @@ -690,13 +690,16 @@ SWITCH_DECLARE(const char *) switch_channel_get_variable_dup(switch_channel_t *c } if (!cp || !(v = switch_caller_get_field_by_name(cp, varname))) { - v = switch_core_get_variable(varname); + if ((vdup = switch_core_get_variable_pdup(varname, switch_core_session_get_pool(channel->session)))) { + v = vdup; + } } } - if (dup) { - if (v) + if (dup && v != vdup) { + if (v) { r = switch_core_session_strdup(channel->session, v); + } } else { r = v; } diff --git a/src/switch_console.c b/src/switch_console.c index 41bbb91ad0..c5d601b9a2 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -643,9 +643,9 @@ SWITCH_DECLARE_NONSTD(switch_status_t) switch_console_list_uuid(const char *line if (!zstr(cursor)) { sql = switch_mprintf("select distinct uuid from channels where uuid like '%q%%' and hostname='%q' order by uuid", - cursor, switch_core_get_variable("hostname")); + cursor, switch_core_get_hostname()); } else { - sql = switch_mprintf("select distinct uuid from channels where hostname='%q' order by uuid", switch_core_get_variable("hostname")); + sql = switch_mprintf("select distinct uuid from channels where hostname='%q' order by uuid", switch_core_get_hostname()); } switch_cache_db_execute_sql_callback(db, sql, uuid_callback, &h, &errmsg); @@ -764,7 +764,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch if (h.words == 0) { sql = switch_mprintf("select distinct name from interfaces where type='api' and name like '%q%%' and hostname='%q' order by name", - buf, switch_core_get_variable("hostname")); + buf, switch_core_get_hostname()); } if (sql) { @@ -792,7 +792,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch if (h.words == 0) { stream.write_function(&stream, "select distinct a1 from complete where " "a1 not in (select name from interfaces where hostname='%s') %s ", - switch_core_get_variable("hostname"), argc ? "and" : ""); + switch_core_get_hostname(), argc ? "and" : ""); } else { if (db->type == SCDB_TYPE_CORE_DB) { stream.write_function(&stream, "select distinct a%d,'%q','%q' from complete where ", h.words + 1, switch_str_nil(dup), switch_str_nil(lp)); @@ -821,7 +821,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch } } - stream.write_function(&stream, " and hostname='%s' order by a%d", switch_core_get_variable("hostname"), h.words + 1); + stream.write_function(&stream, " and hostname='%s' order by a%d", switch_core_get_hostname(), h.words + 1); switch_cache_db_execute_sql_callback(db, stream.data, comp_callback, &h, &errmsg); @@ -1794,7 +1794,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) } } } - mystream.write_function(&mystream, " '%s')", switch_core_get_variable("hostname")); + mystream.write_function(&mystream, " '%s')", switch_core_get_hostname()); switch_cache_db_persistant_execute(db, mystream.data, 5); status = SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(argv[0], "add")) { @@ -1810,7 +1810,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) } } } - mystream.write_function(&mystream, " '%s')", switch_core_get_variable("hostname")); + mystream.write_function(&mystream, " '%s')", switch_core_get_hostname()); switch_cache_db_persistant_execute(db, mystream.data, 5); status = SWITCH_STATUS_SUCCESS; @@ -1827,7 +1827,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) mystream.write_function(&mystream, "a%d = '%w'%w", x + 1, switch_str_nil(argv[x + 1]), x == argc - 2 ? "" : " and "); } } - mystream.write_function(&mystream, " and hostname='%s'", switch_core_get_variable("hostname")); + mystream.write_function(&mystream, " and hostname='%s'", switch_core_get_hostname()); switch_cache_db_persistant_execute(db, mystream.data, 1); } status = SWITCH_STATUS_SUCCESS; @@ -1863,38 +1863,38 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string) } if (!strcasecmp(argv[0], "stickyadd") && argc == 3) { - sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_variable("hostname")); + sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_hostname()); switch_cache_db_persistant_execute(db, sql, 5); switch_safe_free(sql); if (db->type == SCDB_TYPE_CORE_DB) { sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (1, '%q','%q','%q')", - argv[1], argv[2], switch_core_get_variable("hostname")); + argv[1], argv[2], switch_core_get_hostname()); } else { sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (1, '%w','%w','%w')", - argv[1], argv[2], switch_core_get_variable("hostname")); + argv[1], argv[2], switch_core_get_hostname()); } switch_cache_db_persistant_execute(db, sql, 5); status = SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(argv[0], "add") && argc == 3) { - sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_variable("hostname")); + sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_hostname()); switch_cache_db_persistant_execute(db, sql, 5); switch_safe_free(sql); if (db->type == SCDB_TYPE_CORE_DB) { sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (0, '%q','%q','%q')", - argv[1], argv[2], switch_core_get_variable("hostname")); + argv[1], argv[2], switch_core_get_hostname()); } else { sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (0, '%w','%w','%w')", - argv[1], argv[2], switch_core_get_variable("hostname")); + argv[1], argv[2], switch_core_get_hostname()); } switch_cache_db_persistant_execute(db, sql, 5); status = SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(argv[0], "del") && argc == 2) { char *what = argv[1]; if (!strcasecmp(what, "*")) { - sql = switch_mprintf("delete from aliases where hostname='%q'", switch_core_get_variable("hostname")); + sql = switch_mprintf("delete from aliases where hostname='%q'", switch_core_get_hostname()); switch_cache_db_persistant_execute(db, sql, 1); } else { - sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_variable("hostname")); + sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_hostname()); switch_cache_db_persistant_execute(db, sql, 5); } status = SWITCH_STATUS_SUCCESS; diff --git a/src/switch_core.c b/src/switch_core.c index 43fb36d705..87543050b2 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -261,6 +261,11 @@ SWITCH_DECLARE(void) switch_core_dump_variables(switch_stream_handle_t *stream) switch_mutex_unlock(runtime.global_mutex); } +SWITCH_DECLARE(const char *) switch_core_get_hostname(void) +{ + return runtime.hostname; +} + SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname) { char *val; @@ -270,6 +275,32 @@ SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname) return val; } +SWITCH_DECLARE(char *) switch_core_get_variable_dup(const char *varname) +{ + char *val = NULL, *v; + + switch_mutex_lock(runtime.global_var_mutex); + if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { + val = strdup(v); + } + switch_mutex_unlock(runtime.global_var_mutex); + + return val; +} + +SWITCH_DECLARE(char *) switch_core_get_variable_pdup(const char *varname, switch_memory_pool_t *pool) +{ + char *val = NULL, *v; + + switch_mutex_lock(runtime.global_var_mutex); + if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { + val = switch_core_strdup(pool, v); + } + switch_mutex_unlock(runtime.global_var_mutex); + + return val; +} + static void switch_core_unset_variables(void) { switch_mutex_lock(runtime.global_var_mutex); @@ -1202,12 +1233,18 @@ static void switch_core_set_serial(void) if ((fd = open(path, O_RDONLY, 0)) < 0) { - char *ip = switch_core_get_variable("local_ip_v4"); + char *ip = switch_core_get_variable_dup("local_ip_v4"); uint32_t ipi = 0; switch_byte_t *byte; int i = 0; - switch_inet_pton(AF_INET, ip, &ipi); + if (ip) { + switch_inet_pton(AF_INET, ip, &ipi); + free(ip); + ip = NULL; + } + + byte = (switch_byte_t *) & ipi; for (i = 0; i < 8; i += 2) { @@ -1237,7 +1274,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc char guess_ip[256]; int mask = 0; struct in_addr in; - char hostname[256] = ""; + if (runtime.runlevel > 0) { /* one per customer */ @@ -1310,8 +1347,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc runtime.console = stdout; } - gethostname(hostname, sizeof(hostname)); - switch_core_set_variable("hostname", hostname); + gethostname(runtime.hostname, sizeof(runtime.hostname)); + switch_core_set_variable("hostname", runtime.hostname); switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET); switch_core_set_variable("local_ip_v4", guess_ip); diff --git a/src/switch_core_file.c b/src/switch_core_file.c index 19f23546f0..fc7d223b5b 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -102,7 +102,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, } if (!spool_path) { - spool_path = switch_core_get_variable(SWITCH_AUDIO_SPOOL_PATH_VARIABLE); + spool_path = switch_core_get_variable_pdup(SWITCH_AUDIO_SPOOL_PATH_VARIABLE, fh->memory_pool); } file_path = fh->file_path; diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 2db2a0dd46..73890a1e4f 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1134,7 +1134,7 @@ static void core_event_handler(switch_event_t *event) new_sql() = switch_mprintf("insert into tasks values(%q,'%q','%q',%q, '%q')", id, switch_event_get_header_nil(event, "task-desc"), - switch_event_get_header_nil(event, "task-group"), manager ? manager : "0", switch_core_get_variable("hostname") + switch_event_get_header_nil(event, "task-group"), manager ? manager : "0", switch_core_get_hostname() ); } } @@ -1142,7 +1142,7 @@ static void core_event_handler(switch_event_t *event) case SWITCH_EVENT_DEL_SCHEDULE: case SWITCH_EVENT_EXE_SCHEDULE: new_sql() = switch_mprintf("delete from tasks where task_id=%q and hostname='%q'", - switch_event_get_header_nil(event, "task-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "task-id"), switch_core_get_hostname()); break; case SWITCH_EVENT_RE_SCHEDULE: { @@ -1153,7 +1153,7 @@ static void core_event_handler(switch_event_t *event) new_sql() = switch_mprintf("update tasks set task_desc='%q',task_group='%q', task_sql_manager=%q where task_id=%q and hostname='%q'", switch_event_get_header_nil(event, "task-desc"), switch_event_get_header_nil(event, "task-group"), manager ? manager : "0", id, - switch_core_get_variable("hostname")); + switch_core_get_hostname()); } } break; @@ -1163,10 +1163,10 @@ static void core_event_handler(switch_event_t *event) if (uuid) { new_sql() = switch_mprintf("delete from channels where uuid='%q' and hostname='%q'", - uuid, switch_core_get_variable("hostname")); + uuid, switch_core_get_hostname()); new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q') and hostname='%q'", - uuid, uuid, switch_core_get_variable("hostname")); + uuid, uuid, switch_core_get_hostname()); } } @@ -1178,12 +1178,12 @@ static void core_event_handler(switch_event_t *event) "update calls set callee_uuid='%q' where callee_uuid='%q' and hostname='%q'", switch_event_get_header_nil(event, "unique-id"), switch_event_get_header_nil(event, "old-unique-id"), - switch_core_get_variable("hostname"), + switch_core_get_hostname(), switch_event_get_header_nil(event, "unique-id"), switch_event_get_header_nil(event, "old-unique-id"), - switch_core_get_variable("hostname"), + switch_core_get_hostname(), switch_event_get_header_nil(event, "unique-id"), - switch_event_get_header_nil(event, "old-unique-id"), switch_core_get_variable("hostname") + switch_event_get_header_nil(event, "old-unique-id"), switch_core_get_hostname() ); break; } @@ -1198,7 +1198,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-state"), switch_event_get_header_nil(event, "channel-call-state"), switch_event_get_header_nil(event, "caller-dialplan"), - switch_event_get_header_nil(event, "caller-context"), switch_core_get_variable("hostname") + switch_event_get_header_nil(event, "caller-context"), switch_core_get_hostname() ); break; case SWITCH_EVENT_CODEC: @@ -1211,7 +1211,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-write-codec-name"), switch_event_get_header_nil(event, "channel-write-codec-rate"), switch_event_get_header_nil(event, "channel-write-codec-bit-rate"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); break; case SWITCH_EVENT_CHANNEL_HOLD: case SWITCH_EVENT_CHANNEL_UNHOLD: @@ -1223,7 +1223,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "application-data"), switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname") + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname() ); } @@ -1238,7 +1238,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-presence-data"), switch_event_get_header_nil(event, "channel-call-uuid"), extra_cols, - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); free(extra_cols); } else { new_sql() = switch_mprintf("update channels set " @@ -1246,7 +1246,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), switch_event_get_header_nil(event, "channel-call-uuid"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); } } @@ -1281,7 +1281,7 @@ static void core_event_handler(switch_event_t *event) switch_str_nil(name), switch_str_nil(number), switch_event_get_header_nil(event, "direction"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); name = switch_event_get_header(event, "callee-name"); number = switch_event_get_header(event, "callee-number"); @@ -1298,7 +1298,7 @@ static void core_event_handler(switch_event_t *event) { new_sql() = switch_mprintf("update channels set callstate='%q' where uuid='%q' and hostname='%q'", switch_event_get_header_nil(event, "channel-call-state"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); } break; @@ -1330,7 +1330,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), extra_cols, - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); free(extra_cols); } else { new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q'," @@ -1345,13 +1345,13 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "caller-context"), switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); } break; default: new_sql() = switch_mprintf("update channels set state='%s' where uuid='%s' and hostname='%q'", switch_event_get_header_nil(event, "channel-state"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); break; } @@ -1377,7 +1377,7 @@ static void core_event_handler(switch_event_t *event) new_sql() = switch_mprintf("update channels set call_uuid='%q' where uuid='%s' and hostname='%q'", switch_event_get_header_nil(event, "channel-call-uuid"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { func_name = "function"; @@ -1404,7 +1404,7 @@ static void core_event_handler(switch_event_t *event) callee_cid_num, switch_event_get_header_nil(event, "Other-Leg-destination-number"), switch_event_get_header_nil(event, "Other-Leg-channel-name"), - switch_event_get_header_nil(event, "Other-Leg-unique-id"), switch_core_get_variable("hostname") + switch_event_get_header_nil(event, "Other-Leg-unique-id"), switch_core_get_hostname() ); } break; @@ -1413,14 +1413,14 @@ static void core_event_handler(switch_event_t *event) char *uuid = switch_event_get_header_nil(event, "caller-unique-id"); new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q') and hostname='%q'", - uuid, uuid, switch_core_get_variable("hostname")); + uuid, uuid, switch_core_get_hostname()); break; } case SWITCH_EVENT_SHUTDOWN: new_sql() = switch_mprintf("delete from channels where hostname='%q';" "delete from interfaces where hostname='%q';" "delete from calls where hostname='%q'", - switch_core_get_variable("hostname"), switch_core_get_variable("hostname"), switch_core_get_variable("hostname") + switch_core_get_hostname(), switch_core_get_hostname(), switch_core_get_hostname() ); break; case SWITCH_EVENT_LOG: @@ -1438,7 +1438,7 @@ static void core_event_handler(switch_event_t *event) switch_mprintf ("insert into interfaces (type,name,description,syntax,ikey,filename,hostname) values('%q','%q','%q','%q','%q','%q','%q')", type, name, switch_str_nil(description), switch_str_nil(syntax), switch_str_nil(key), switch_str_nil(filename), - switch_core_get_variable("hostname") + switch_core_get_hostname() ); } break; @@ -1449,7 +1449,7 @@ static void core_event_handler(switch_event_t *event) const char *name = switch_event_get_header_nil(event, "name"); if (!zstr(type) && !zstr(name)) { new_sql() = switch_mprintf("delete from interfaces where type='%q' and name='%q' and hostname='%q'", type, name, - switch_core_get_variable("hostname")); + switch_core_get_hostname()); } break; } @@ -1461,7 +1461,7 @@ static void core_event_handler(switch_event_t *event) break; } new_sql() = switch_mprintf("update channels set secure='%s' where uuid='%s' and hostname='%q'", - type, switch_event_get_header_nil(event, "caller-unique-id"), switch_core_get_variable("hostname") + type, switch_event_get_header_nil(event, "caller-unique-id"), switch_core_get_hostname() ); break; } @@ -1472,12 +1472,12 @@ static void core_event_handler(switch_event_t *event) if (!strcmp("add", op)) { new_sql() = switch_mprintf("insert into nat (port, proto, sticky, hostname) values (%s, %s, %d,'%q')", switch_event_get_header_nil(event, "port"), - switch_event_get_header_nil(event, "proto"), sticky, switch_core_get_variable("hostname") + switch_event_get_header_nil(event, "proto"), sticky, switch_core_get_hostname() ); } else if (!strcmp("del", op)) { new_sql() = switch_mprintf("delete from nat where port=%s and proto=%s and hostname='%q'", switch_event_get_header_nil(event, "port"), - switch_event_get_header_nil(event, "proto"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "proto"), switch_core_get_hostname()); } else if (!strcmp("status", op)) { /* call show nat api */ } else if (!strcmp("status_response", op)) { @@ -1664,7 +1664,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ char sql[512] = ""; char *tables[] = { "channels", "calls", "interfaces", "tasks", NULL }; int i; - const char *hostname = switch_core_get_variable("hostname"); + const char *hostname = switch_core_get_hostname(); for (i = 0; tables[i]; i++) { switch_snprintf(sql, sizeof(sql), "delete from %s where hostname='%s'", tables[i], hostname); diff --git a/src/switch_event.c b/src/switch_event.c index 003fc82296..3e12ea115f 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -1673,6 +1673,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const int offset = 0; int ooffset = 0; char *ptr; + char *gvar = NULL; if ((expanded = switch_event_expand_headers(event, (char *) vname)) == vname) { expanded = NULL; @@ -1689,7 +1690,9 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const } if (!(sub_val = switch_event_get_header(event, vname))) { - sub_val = switch_core_get_variable(vname); + if ((gvar = switch_core_get_variable_dup(vname))) { + sub_val = gvar; + } } if (offset || ooffset) { @@ -1710,6 +1713,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const } } + switch_safe_free(gvar); switch_safe_free(expanded); } else { switch_stream_handle_t stream = { 0 }; diff --git a/src/switch_nat.c b/src/switch_nat.c index 536baeedff..85b0247d6d 100644 --- a/src/switch_nat.c +++ b/src/switch_nat.c @@ -45,6 +45,7 @@ typedef struct { switch_nat_type_t nat_type; + char nat_type_str[5]; struct UPNPUrls urls; struct IGDdatas data; char *descURL; @@ -420,6 +421,7 @@ SWITCH_DECLARE(void) switch_nat_init(switch_memory_pool_t *pool) switch_core_set_variable("nat_public_addr", nat_globals.pub_addr); switch_core_set_variable("nat_private_addr", nat_globals.pvt_addr); switch_core_set_variable("nat_type", nat_globals.nat_type == SWITCH_NAT_TYPE_PMP ? "pmp" : "upnp"); + strncpy(nat_globals.nat_type_str, nat_globals.nat_type == SWITCH_NAT_TYPE_PMP ? "pmp" : "upnp", sizeof(nat_globals.nat_type_str) - 1); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "NAT detected type: %s, ExtIP: '%s'\n", nat_globals.nat_type == SWITCH_NAT_TYPE_PMP ? "pmp" : "upnp", nat_globals.pub_addr); @@ -564,6 +566,11 @@ static switch_status_t switch_nat_del_mapping_upnp(switch_port_t port, switch_na return status; } +SWITCH_DECLARE(const char *) switch_nat_get_type(void) +{ + return nat_globals.nat_type_str; +} + SWITCH_DECLARE(switch_status_t) switch_nat_add_mapping_internal(switch_port_t port, switch_nat_ip_proto_t proto, switch_port_t * external_port, switch_bool_t sticky, switch_bool_t publish) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 4acadfe2ff..e8d7558bce 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -791,8 +791,8 @@ static void zrtp_logger(int level, const char *data, int len, int offset) SWITCH_DECLARE(void) switch_rtp_init(switch_memory_pool_t *pool) { #ifdef ENABLE_ZRTP - const char *zid_string = switch_core_get_variable("switch_serial"); - const char *zrtp_enabled = switch_core_get_variable("zrtp_enabled"); + const char *zid_string = switch_core_get_variable_pdup("switch_serial", pool); + const char *zrtp_enabled = switch_core_get_variable_pdup("zrtp_enabled", pool); zrtp_config_t zrtp_config; char zrtp_cache_path[256] = ""; zrtp_on = zrtp_enabled ? switch_true(zrtp_enabled) : 0; diff --git a/src/switch_utils.c b/src/switch_utils.c index 850b07f51d..eb5ed7f830 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -1154,8 +1154,8 @@ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int *ma { switch_status_t status = SWITCH_STATUS_FALSE; char *base; - const char *force_local_ip_v4 = switch_core_get_variable("force_local_ip_v4"); - const char *force_local_ip_v6 = switch_core_get_variable("force_local_ip_v6"); + char *force_local_ip_v4 = switch_core_get_variable_dup("force_local_ip_v4"); + char *force_local_ip_v6 = switch_core_get_variable_dup("force_local_ip_v6"); #ifdef WIN32 SOCKET tmp_socket; @@ -1176,14 +1176,20 @@ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int *ma case AF_INET: if (force_local_ip_v4) { switch_copy_string(buf, force_local_ip_v4, len); + switch_safe_free(force_local_ip_v4); + switch_safe_free(force_local_ip_v6); return SWITCH_STATUS_SUCCESS; } case AF_INET6: if (force_local_ip_v6) { switch_copy_string(buf, force_local_ip_v6, len); + switch_safe_free(force_local_ip_v4); + switch_safe_free(force_local_ip_v6); return SWITCH_STATUS_SUCCESS; } default: + switch_safe_free(force_local_ip_v4); + switch_safe_free(force_local_ip_v6); break; } diff --git a/src/switch_xml.c b/src/switch_xml.c index 964a7694b2..4c30d986a6 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -1208,11 +1208,12 @@ static char *expand_vars(char *buf, char *ebuf, switch_size_t elen, switch_size_ var = rp; *e++ = '\0'; rp = e; - if ((val = switch_core_get_variable(var))) { + if ((val = switch_core_get_variable_dup(var))) { char *p; for (p = val; p && *p && wp <= ep; p++) { *wp++ = *p; } + free(val); } continue; } else if (err) { From 257bf9a46c44f76d8b38c90f288f364bcf1c6398 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 2 Feb 2011 16:05:51 -0600 Subject: [PATCH 46/86] fix possible bad pointer in global vars (please test) --- libs/freetdm/mod_freetdm/mod_freetdm.c | 7 +++++++ libs/openzap/mod_openzap/mod_openzap.c | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 970cb5b993..2ef21cc186 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1067,9 +1067,16 @@ static const char* channel_get_variable(switch_core_session_t *session, switch_e return variable; } } + + + // This is unsafe, I don't see anywhere in the whole code where this is called with NULL session anyway. + // There is a new switch_core_get_variable_dup that will strdup it for you and then you must free it. + // That messes up the abstraction completely so I am just commenting it out for you..... + /* if ((variable = switch_core_get_variable(variable_name))) { return variable; } + */ return NULL; } diff --git a/libs/openzap/mod_openzap/mod_openzap.c b/libs/openzap/mod_openzap/mod_openzap.c index d52149c657..ef346b8eea 100644 --- a/libs/openzap/mod_openzap/mod_openzap.c +++ b/libs/openzap/mod_openzap/mod_openzap.c @@ -1234,19 +1234,19 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi zap_set_string(caller_data.ani.digits, dest); } - if ((var = switch_event_get_header(var_event, "openzap_outbound_ton")) || (var = switch_core_get_variable("openzap_outbound_ton"))) { + if ((var = switch_event_get_header(var_event, "openzap_outbound_ton"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting TON to: %s\n", var); zap_set_ton(var, &caller_data.ani.type); } else { caller_data.ani.type = outbound_profile->destination_number_ton; } - if ((var = switch_event_get_header(var_event, "openzap_custom_call_data")) || (var = switch_core_get_variable("openzap_custom_call_data"))) { + if ((var = switch_event_get_header(var_event, "openzap_custom_call_data"))) { zap_set_string((char *)caller_data.raw_data, var); caller_data.raw_data_len = strlen(var); } - if ((var = switch_event_get_header(var_event, "openzap_outbound_npi")) || (var = switch_core_get_variable("openzap_outbound_npi"))) { + if ((var = switch_event_get_header(var_event, "openzap_outbound_npi"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting NPI to: %s\n", var); zap_set_npi(var, &caller_data.ani.plan); } else { From 85913b70b43483d4d3d840d128549ddba75b56a6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 2 Feb 2011 16:05:57 -0600 Subject: [PATCH 47/86] only pass publish on when you have a subscription --- src/mod/endpoints/mod_sofia/sofia_presence.c | 62 +++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 19125c600b..a38a61eab8 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -2570,6 +2570,19 @@ static int sofia_counterpath_crutch(void *pArg, int argc, char **argv, char **co return 0; } + +uint32_t sofia_presence_contact_count(sofia_profile_t *profile, const char *contact_str) +{ + char buf[32] = ""; + char *sql; + + sql = switch_mprintf("select count(*) from sip_subscriptions where profile_name='%q' and contact_str='%q'", profile->name, contact_str); + + sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf)); + switch_safe_free(sql); + return atoi(buf); +} + void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]) { @@ -2584,7 +2597,7 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n char expstr[30] = ""; long exp = 0, exp_delta = 3600; char *pd_dup = NULL; - int count = 1; + int count = 1, sub_count = 0; char *contact_str; int open = 1; @@ -2667,24 +2680,25 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n count = sofia_reg_reg_count(profile, from_user, from_host); } + sub_count = sofia_presence_contact_count(profile, contact_str); /* if (count > 1) let's not and say we did or all the clients who subscribe to their own presence will think they selves is offline */ event_type = sip_header_as_string(profile->home, (void *) sip->sip_event); if (count < 2) { - if ((sql = - switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' " - " and profile_name='%q' and hostname='%q'", from_user, from_host, profile->name, mod_sofia_globals.hostname))) { + if ((sql = switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' " + " and profile_name='%q' and hostname='%q'", + from_user, from_host, profile->name, mod_sofia_globals.hostname))) { sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } - if ((sql = - switch_mprintf("insert into sip_presence (sip_user, sip_host, status, rpid, expires, user_agent," - " profile_name, hostname, open_closed) " - "values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q')", - from_user, from_host, note_txt, rpid, exp, full_agent, profile->name, mod_sofia_globals.hostname, open_closed))) { - + if (sub_count > 0 && (sql = switch_mprintf("insert into sip_presence (sip_user, sip_host, status, rpid, expires, user_agent," + " profile_name, hostname, open_closed) " + "values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q')", + from_user, from_host, note_txt, rpid, exp, full_agent, profile->name, + mod_sofia_globals.hostname, open_closed))) { + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } @@ -2696,16 +2710,17 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n switch_safe_free(sql); } - - if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user-agent", full_agent); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", note_txt); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", event_type); - switch_event_fire(&event); + if (sub_count > 0) { + if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user-agent", full_agent); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", note_txt); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", event_type); + switch_event_fire(&event); + } } if (event_type) { @@ -2728,7 +2743,12 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n switch_snprintf(expstr, sizeof(expstr), "%d", exp_delta); switch_stun_random_string(etag, 8, NULL); - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), SIPTAG_ETAG_STR(etag), SIPTAG_EXPIRES_STR(expstr), TAG_END()); + + if (sub_count > 0) { + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), SIPTAG_ETAG_STR(etag), SIPTAG_EXPIRES_STR(expstr), TAG_END()); + } else { + nua_respond(nh, SIP_404_NOT_FOUND, NUTAG_WITH_THIS(nua), TAG_END()); + } switch_safe_free(contact_str); } From f60fdf653dd2d7f8d3eaa6a9086e1f68bd993c59 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 2 Feb 2011 16:22:43 -0600 Subject: [PATCH 48/86] fix possible bad pointer in global vars (please test) --- fscomm/widgets/codecwidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fscomm/widgets/codecwidget.cpp b/fscomm/widgets/codecwidget.cpp index 42b10febfd..2f82e1a8cc 100644 --- a/fscomm/widgets/codecwidget.cpp +++ b/fscomm/widgets/codecwidget.cpp @@ -131,6 +131,8 @@ void CodecWidget::setCodecString(QString codecList) QStringList parsed = codecList.split("{"); QString var = parsed.at(1); var = var.split("}").at(0); + // warning switch_core_get_Variable may return an unsafe pointer in some cases. + // revise to use switch_core_get_variable_dup, and then free it after you are done. var = switch_core_get_variable(var.toAscii().data()); if ( ! var.isEmpty() ) { codecList = var; From b55b4eeaeea1d1cebc5a44ffdd88b224898d5d8a Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 3 Feb 2011 10:04:25 -0600 Subject: [PATCH 49/86] VS2010 fix minor build order problem --- libs/win32/sofia/libsofia_sip_ua_static.2010.vcxproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libs/win32/sofia/libsofia_sip_ua_static.2010.vcxproj b/libs/win32/sofia/libsofia_sip_ua_static.2010.vcxproj index d841b89c0a..be91504cc2 100644 --- a/libs/win32/sofia/libsofia_sip_ua_static.2010.vcxproj +++ b/libs/win32/sofia/libsofia_sip_ua_static.2010.vcxproj @@ -508,6 +508,12 @@ if not exist "$(ProjectDir)$(IntDir)\auth_client.obj" "autogen.cmd" {8b3b4c4c-13c2-446c-beb0-f412cc2cfb9a} false + + {d331904d-a00a-4694-a5a3-fcff64ab5dbe} + + + {b4b62169-5ad4-4559-8707-3d933ac5db39} + {df018947-0fff-4eb3-bdee-441dc81da7a4} false From 74a0cfd1e101413a3941c41d04ee01d8df2ae418 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 Feb 2011 10:19:04 -0600 Subject: [PATCH 50/86] FS-3027 --- src/mod/endpoints/mod_sofia/sofia_glue.c | 25 +++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index dfd6a76974..8b2f470980 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -4071,15 +4071,22 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s greedy = !!sofia_test_pflag(tech_pvt->profile, PFLAG_GREEDY); scrooge = !!sofia_test_pflag(tech_pvt->profile, PFLAG_SCROOGE); - if (!greedy || !scrooge) { - if ((val = switch_channel_get_variable(channel, "sip_codec_negotiation"))) { - if (!strcasecmp(val, "greedy")) { - greedy = 1; - } else if (!strcasecmp(val, "scrooge")) { - scrooge = 1; - greedy = 1; - } - } + if ((val = switch_channel_get_variable(channel, "sip_codec_negotiation"))) { + if (!strcasecmp(val, "generous")) { + greedy = 0; + scrooge = 0; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sip_codec_negotiation overriding sofia inbound-codec-negotiation : generous\n" ); + } else if (!strcasecmp(val, "greedy")) { + greedy = 1; + scrooge = 0; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sip_codec_negotiation overriding sofia inbound-codec-negotiation : greedy\n" ); + } else if (!strcasecmp(val, "scrooge")) { + scrooge = 1; + greedy = 1; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sip_codec_negotiation overriding sofia inbound-codec-negotiation : scrooge\n" ); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sip_codec_negotiation ignored invalid value : '%s' \n", val ); + } } if ((tech_pvt->origin = switch_core_session_strdup(session, (char *) sdp->sdp_origin->o_username))) { From e5fb456f3bfddbf1e379c77030e8e4dd5549d12a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 Feb 2011 11:19:24 -0600 Subject: [PATCH 51/86] doh regression --- src/switch_event.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/switch_event.c b/src/switch_event.c index 3e12ea115f..b626d5b846 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -1561,6 +1561,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const char *cloned_sub_val = NULL; char *func_val = NULL; int nv = 0; + char *gvar = NULL; nv = switch_string_var_check_const(in) || switch_string_has_escaped_data(in); @@ -1673,7 +1674,6 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const int offset = 0; int ooffset = 0; char *ptr; - char *gvar = NULL; if ((expanded = switch_event_expand_headers(event, (char *) vname)) == vname) { expanded = NULL; @@ -1690,6 +1690,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const } if (!(sub_val = switch_event_get_header(event, vname))) { + switch_safe_free(gvar); if ((gvar = switch_core_get_variable_dup(vname))) { sub_val = gvar; } @@ -1713,7 +1714,6 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const } } - switch_safe_free(gvar); switch_safe_free(expanded); } else { switch_stream_handle_t stream = { 0 }; @@ -1789,6 +1789,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const } } free(indup); + switch_safe_free(gvar); return data; } From 68d08547f36777e2c091008b5e1207ca5b15e9e2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 Feb 2011 16:27:22 -0600 Subject: [PATCH 52/86] try to improve iLBC compat --- src/mod/endpoints/mod_sofia/sofia_glue.c | 2 +- src/switch_core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 8b2f470980..a0b7fca2ff 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -4480,7 +4480,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s match = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1; } - if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate) { + if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate && strcasecmp(map->rm_encoding, "ilbc")) { /* nevermind */ match = 0; } diff --git a/src/switch_core.c b/src/switch_core.c index 87543050b2..0eb51ccab3 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1486,7 +1486,7 @@ static void switch_load_core_config(const char *file) { switch_xml_t xml = NULL, cfg = NULL; - //switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30); + switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30); switch_core_hash_insert(runtime.ptimes, "G723", &d_30); if ((xml = switch_xml_open_cfg(file, &cfg, NULL))) { From 33b74ca8c710a58d245ea8903f98e0e86cffe164 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 Feb 2011 17:06:18 -0600 Subject: [PATCH 53/86] FS-3006 --- .../endpoints/mod_portaudio/mod_portaudio.c | 1054 +++++++++++------ 1 file changed, 716 insertions(+), 338 deletions(-) diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c index 8978b85fc2..baa33d456e 100644 --- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c +++ b/src/mod/endpoints/mod_portaudio/mod_portaudio.c @@ -40,6 +40,8 @@ #define MY_EVENT_RINGING "portaudio::ringing" #define MY_EVENT_MAKE_CALL "portaudio::makecall" +#define MY_EVENT_CALL_HELD "portaudio::callheld" +#define MY_EVENT_CALL_RESUMED "portaudio::callresumed" #define MY_EVENT_ERROR_AUDIO_DEV "portaudio::audio_dev_error" #define SWITCH_PA_CALL_ID_VARIABLE "pa_call_id" @@ -90,12 +92,20 @@ struct private_object { switch_file_handle_t *hfh; switch_frame_t hold_frame; unsigned char holdbuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - switch_codec_t write_codec; struct private_object *next; }; typedef struct private_object private_t; +struct audio_stream { + int indev; + int outdev; + PABLIO_Stream *stream; + switch_timer_t write_timer; + struct audio_stream *next; +}; +typedef struct audio_stream audio_stream_t; + static struct { int debug; int port; @@ -113,12 +123,13 @@ static struct { switch_hash_t *call_hash; switch_mutex_t *device_lock; switch_mutex_t *pvt_lock; + switch_mutex_t *streams_lock; switch_mutex_t *flag_mutex; switch_mutex_t *pa_mutex; int sample_rate; int codec_ms; - PABLIO_Stream *audio_stream; - PABLIO_Stream *ring_stream; + audio_stream_t *main_stream; + audio_stream_t *ring_stream; switch_codec_t read_codec; switch_codec_t write_codec; switch_frame_t read_frame; @@ -126,13 +137,20 @@ static struct { unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; unsigned char cngbuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; private_t *call_list; + audio_stream_t *stream_list; int ring_interval; GFLAGS flags; switch_timer_t read_timer; - switch_timer_t write_timer; + switch_timer_t readfile_timer; switch_timer_t hold_timer; int dual_streams; time_t deactivate_timer; + int live_stream_switch; + int no_auto_resume_call; + int no_ring_during_call; + int codecs_inited; + int stream_in_use; //only really used by playdev + int destroying_streams; } globals; @@ -164,9 +182,22 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id); static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); -static switch_status_t engage_device(int restart); -static switch_status_t engage_ring_device(void); -static void deactivate_ring_device(void); + +static switch_status_t create_codecs(int restart); +static void create_hold_event(private_t *tech_pvt, int unhold); +static audio_stream_t * find_audio_stream(int indev, int outdev, int already_locked); +static audio_stream_t * get_audio_stream(int indev, int outdev); +static audio_stream_t * create_audio_stream(int indev, int outdev); +PaError open_audio_stream(PABLIO_Stream **stream, const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters); +static switch_status_t switch_audio_stream(); +static void add_stream(audio_stream_t *stream, int already_locked); +static void remove_stream(audio_stream_t *stream, int already_locked); +static switch_status_t destroy_audio_stream(int indev, int outdev); +static switch_status_t destroy_actual_stream(audio_stream_t *stream); +static void destroy_audio_streams(); +static switch_status_t validate_main_audio_stream(); +static switch_status_t validate_ring_audio_stream(); + static int dump_info(int verbose); static switch_status_t load_config(void); static int get_dev_by_name(char *name, int in); @@ -212,9 +243,8 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) if (hold_file) { tech_pvt->hold_file = switch_core_session_strdup(session, hold_file); } - - if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { - if (engage_device(0) != SWITCH_STATUS_SUCCESS) { + if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { + if (validate_main_audio_stream() != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); return SWITCH_STATUS_FALSE; } @@ -238,7 +268,7 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) globals.read_codec.implementation->actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) { - if (engage_ring_device() != SWITCH_STATUS_SUCCESS) { + if (validate_ring_audio_stream() != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Ring Error!\n"); switch_core_file_close(&fh); @@ -263,7 +293,7 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) } while (switch_channel_get_state(channel) == CS_ROUTING && !switch_test_flag(tech_pvt, TFLAG_ANSWER)) { - switch_size_t olen = globals.read_timer.samples; + switch_size_t olen = globals.readfile_timer.samples; if (switch_micro_time_now() - last >= waitsec) { char buf[512]; @@ -273,7 +303,8 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_RINGING) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_info", buf); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call_id", tech_pvt->call_id); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call_id", tech_pvt->call_id); /* left behind for backwards compatability */ + switch_channel_set_variable(channel, SWITCH_PA_CALL_ID_VARIABLE, tech_pvt->call_id); switch_channel_event_set_data(channel, event); switch_event_fire(&event); } @@ -282,7 +313,7 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) } if (ring_file) { - if (switch_core_timer_next(&globals.read_timer) != SWITCH_STATUS_SUCCESS) { + if (switch_core_timer_next(&globals.readfile_timer) != SWITCH_STATUS_SUCCESS) { switch_core_file_close(&fh); break; } @@ -292,8 +323,9 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) switch_core_file_seek(&fh, &pos, 0, SEEK_SET); } - if (globals.ring_stream) { - WriteAudioStream(globals.ring_stream, abuf, (long) olen, &globals.write_timer); + if (globals.ring_stream && (! switch_test_flag(globals.call_list, TFLAG_MASTER) || + ( !globals.no_ring_during_call && globals.main_stream != globals.ring_stream)) ) { //if there is a ring stream and not an active call or if there is an active call and we are allowed to ring during it AND the ring stream is not the main stream + WriteAudioStream(globals.ring_stream->stream, abuf, (long) olen, &globals.ring_stream->write_timer); } } else { switch_yield(10000); @@ -303,7 +335,6 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) } if (ring_file) { - deactivate_ring_device(); switch_core_file_close(&fh); } @@ -329,27 +360,130 @@ static switch_status_t channel_on_execute(switch_core_session_t *session) return SWITCH_STATUS_SUCCESS; } -static void deactivate_audio_device(void) +static audio_stream_t* find_audio_stream(int indev, int outdev, int already_locked) { - if (!globals.audio_stream) { - return; + audio_stream_t *cur_stream; + + if (! globals.stream_list) { + return NULL; } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Stop audio device.\n"); + if (! already_locked) { + switch_mutex_lock(globals.streams_lock); + } + cur_stream = globals.stream_list; - switch_mutex_lock(globals.device_lock); - /* LOCKED ************************************************************************************************** */ - - if (globals.audio_stream) { - if (globals.ring_stream == globals.audio_stream) { - globals.ring_stream = NULL; + while (cur_stream != NULL) { + if (cur_stream->outdev == outdev) { + if (indev == -1 || cur_stream->indev == indev) { + if (! already_locked) { + switch_mutex_unlock(globals.streams_lock); + } + return cur_stream; + } } - CloseAudioStream(globals.audio_stream); - globals.audio_stream = NULL; + cur_stream = cur_stream->next; + } + if (! already_locked) { + switch_mutex_unlock(globals.streams_lock); + } + return NULL; +} +static void destroy_audio_streams() +{ + int close_wait = 4; + globals.destroying_streams = 1; + + while (globals.stream_in_use && close_wait--) { + switch_yield(250000); + } + while (globals.stream_list != NULL) { + destroy_audio_stream(globals.stream_list->indev, globals.stream_list->outdev); + } + globals.destroying_streams = 0; +} +static switch_status_t validate_main_audio_stream() +{ + if (globals.read_timer.timer_interface) { + switch_core_timer_sync(&globals.read_timer); } - /* UNLOCKED ************************************************************************************************* */ - switch_mutex_unlock(globals.device_lock); + if (globals.main_stream) { + if (globals.main_stream->write_timer.timer_interface) { + switch_core_timer_sync(&(globals.main_stream->write_timer)); + } + + return SWITCH_STATUS_SUCCESS; + } + + globals.main_stream = get_audio_stream(globals.indev, globals.outdev); + + if (globals.main_stream) { + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + +static switch_status_t validate_ring_audio_stream() +{ + if (globals.ringdev == -1) { + return SWITCH_STATUS_SUCCESS; + } + if (globals.ring_stream) { + if (globals.ring_stream->write_timer.timer_interface) { + switch_core_timer_sync(&(globals.ring_stream->write_timer)); + } + return SWITCH_STATUS_SUCCESS; + } + globals.ring_stream = get_audio_stream(-1, globals.ringdev); + if (globals.ring_stream) { + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + +static switch_status_t destroy_actual_stream(audio_stream_t *stream) +{ + if (stream == NULL) { + return SWITCH_STATUS_FALSE; + } + + if (globals.main_stream == stream) { + globals.main_stream = NULL; + } + + if (globals.ring_stream == stream) { + globals.ring_stream = NULL; + } + + CloseAudioStream(stream->stream); + stream->stream = NULL; + + if (stream->write_timer.timer_interface) { + switch_core_timer_destroy(&stream->write_timer); + } + + switch_safe_free(stream); + return SWITCH_STATUS_SUCCESS; +} +static switch_status_t destroy_audio_stream(int indev, int outdev) +{ + audio_stream_t *stream; + + switch_mutex_lock(globals.streams_lock); + stream = find_audio_stream(indev, outdev,1); + if (stream == NULL) { + switch_mutex_unlock(globals.streams_lock); + return SWITCH_STATUS_FALSE; + } + + remove_stream(stream, 1); + switch_mutex_unlock(globals.streams_lock); + + destroy_actual_stream(stream); + return SWITCH_STATUS_SUCCESS; } @@ -368,34 +502,69 @@ static void destroy_codecs(void) switch_core_timer_destroy(&globals.read_timer); } - if (globals.write_timer.timer_interface) { - switch_core_timer_destroy(&globals.write_timer); + if (globals.readfile_timer.timer_interface) { + switch_core_timer_destroy(&globals.readfile_timer); } if (globals.hold_timer.timer_interface) { switch_core_timer_destroy(&globals.hold_timer); } - - + globals.codecs_inited = 0; } -static void deactivate_ring_device(void) +static void create_hold_event(private_t *tech_pvt, int unhold) { - if (!globals.ring_stream) { - return; + switch_event_t *event; + char * event_id; + + if (unhold) { + event_id = MY_EVENT_CALL_RESUMED; + } else { + event_id = MY_EVENT_CALL_HELD; } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Stop ring device.\n"); - switch_mutex_lock(globals.device_lock); - if (globals.ring_stream && globals.ring_stream != globals.audio_stream) { - CloseAudioStream(globals.ring_stream); + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, event_id) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(switch_core_session_get_channel(tech_pvt->session), event); + switch_event_fire(&event); } - globals.ring_stream = NULL; - switch_mutex_unlock(globals.device_lock); } +static void add_stream(audio_stream_t * stream, int already_locked) +{ + audio_stream_t *last; + if (! already_locked) { + switch_mutex_lock(globals.streams_lock); + } + for (last = globals.stream_list; last && last->next; last = last->next); + if (last == NULL) { + globals.stream_list = stream; + } else { + last->next = stream; + } + if (! already_locked) { + switch_mutex_unlock(globals.streams_lock); + } +} +static void remove_stream(audio_stream_t * stream, int already_locked) +{ + audio_stream_t *previous; + if (! already_locked) { + switch_mutex_lock(globals.streams_lock); + } + if (globals.stream_list == stream) { + globals.stream_list = stream->next; + } else { + for (previous = globals.stream_list; previous && previous->next && previous->next != stream; previous = previous->next) { + ; + } + previous->next = stream->next; + } + if (! already_locked) { + switch_mutex_unlock(globals.streams_lock); + } +} static void add_pvt(private_t *tech_pvt, int master) { @@ -418,8 +587,9 @@ static void add_pvt(private_t *tech_pvt, int master) if (tp == tech_pvt) { in_list = 1; } - if (master) { + if (master && switch_test_flag(tp, TFLAG_MASTER) ) { switch_clear_flag_locked(tp, TFLAG_MASTER); + create_hold_event(tp,0); } } @@ -446,11 +616,16 @@ static void add_pvt(private_t *tech_pvt, int master) static void remove_pvt(private_t *tech_pvt) { private_t *tp, *last = NULL; + int was_master = 0; switch_mutex_lock(globals.pvt_lock); for (tp = globals.call_list; tp; tp = tp->next) { - switch_clear_flag_locked(tp, TFLAG_MASTER); + if (tp == tech_pvt) { + if (switch_test_flag(tp, TFLAG_MASTER)) { + switch_clear_flag_locked(tp, TFLAG_MASTER); + was_master = 1; + } if (last) { last->next = tp->next; } else { @@ -461,10 +636,13 @@ static void remove_pvt(private_t *tech_pvt) } if (globals.call_list) { - switch_set_flag_locked(globals.call_list, TFLAG_MASTER); + if (was_master && ! globals.no_auto_resume_call) { + switch_set_flag_locked(globals.call_list, TFLAG_MASTER); + create_hold_event(globals.call_list, 1); + } } else { globals.deactivate_timer = switch_epoch_time_now(NULL) + 2; - deactivate_audio_device(); + destroy_audio_streams(); } switch_mutex_unlock(globals.pvt_lock); @@ -555,8 +733,8 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch int samples = 0; switch_status_t status = SWITCH_STATUS_FALSE; switch_assert(tech_pvt != NULL); - - if (!globals.audio_stream) { + + if (!globals.main_stream) { goto normal_return; } @@ -618,7 +796,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch } switch_mutex_lock(globals.device_lock); - samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, &globals.read_timer); + samples = ReadAudioStream(globals.main_stream->stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, &globals.read_timer); switch_mutex_unlock(globals.device_lock); if (samples) { @@ -635,7 +813,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch goto cng_nowait; } - normal_return: +normal_return: return status; cng_nowait: @@ -655,7 +833,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc private_t *tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); - if (!globals.audio_stream) { + if (!globals.main_stream) { return SWITCH_STATUS_FALSE; } @@ -667,9 +845,9 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc return SWITCH_STATUS_SUCCESS; } - if (globals.audio_stream) { + if (globals.main_stream) { if (switch_test_flag((&globals), GFLAG_EAR)) { - WriteAudioStream(globals.audio_stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)), &globals.write_timer); + WriteAudioStream(globals.main_stream->stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)), &(globals.main_stream->write_timer)); } status = SWITCH_STATUS_SUCCESS; } @@ -747,7 +925,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi channel = switch_core_session_get_channel(*new_session); switch_core_session_set_private(*new_session, tech_pvt); tech_pvt->session = *new_session; - globals.flags = GFLAG_EAR | GFLAG_MOUTH; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); switch_core_session_destroy(new_session); @@ -796,16 +973,17 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load) switch_core_hash_init(&globals.call_hash, module_pool); switch_mutex_init(&globals.device_lock, SWITCH_MUTEX_NESTED, module_pool); switch_mutex_init(&globals.pvt_lock, SWITCH_MUTEX_NESTED, module_pool); + switch_mutex_init(&globals.streams_lock, SWITCH_MUTEX_NESTED, module_pool); switch_mutex_init(&globals.flag_mutex, SWITCH_MUTEX_NESTED, module_pool); switch_mutex_init(&globals.pa_mutex, SWITCH_MUTEX_NESTED, module_pool); - + globals.codecs_inited=0; globals.read_frame.data = globals.databuf; globals.read_frame.buflen = sizeof(globals.databuf); globals.cng_frame.data = globals.cngbuf; globals.cng_frame.buflen = sizeof(globals.cngbuf); globals.cng_frame.datalen = switch_samples_per_packet(globals.sample_rate, globals.codec_ms) * 2; switch_set_flag((&globals.cng_frame), SFF_CNG); - + globals.flags = GFLAG_EAR | GFLAG_MOUTH; /* dual streams makes portaudio on solaris choke */ #if defined(sun) || defined(__sun) globals.dual_streams = 0; @@ -834,6 +1012,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); return SWITCH_STATUS_GENERR; } + if (switch_event_reserve_subclass(MY_EVENT_CALL_HELD) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); + return SWITCH_STATUS_GENERR; + } + if (switch_event_reserve_subclass(MY_EVENT_CALL_RESUMED) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); + return SWITCH_STATUS_GENERR; + } if (switch_event_reserve_subclass(MY_EVENT_ERROR_AUDIO_DEV) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); @@ -861,9 +1047,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load) switch_console_set_complete("add pa devlist"); switch_console_set_complete("add pa indev"); switch_console_set_complete("add pa outdev"); + switch_console_set_complete("add pa preparestream"); + switch_console_set_complete("add pa switchstream"); + switch_console_set_complete("add pa closestreams"); switch_console_set_complete("add pa ringdev"); switch_console_set_complete("add pa ringfile"); switch_console_set_complete("add pa play"); + switch_console_set_complete("add pa playdev"); switch_console_set_complete("add pa looptest"); /* indicate that the module should continue to be loaded */ @@ -881,9 +1071,12 @@ static switch_status_t load_config(void) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); return SWITCH_STATUS_TERM; } - + destroy_audio_streams(); + destroy_codecs(); globals.dual_streams = 0; - + globals.live_stream_switch = 0; + globals.no_auto_resume_call = 0; + globals.no_ring_during_call = 0; globals.indev = globals.outdev = globals.ringdev = -1; globals.sample_rate = 8000; @@ -896,6 +1089,24 @@ static switch_status_t load_config(void) globals.debug = atoi(val); } else if (!strcmp(var, "ring-interval")) { globals.ring_interval = atoi(val); + } else if (!strcmp(var, "no-auto-resume-call")) { + if (switch_true(val)) { + globals.no_auto_resume_call = 1; + } else { + globals.no_auto_resume_call = 0; + } + } else if (!strcmp(var, "no-ring-during-call")) { + if (switch_true(val)) { + globals.no_ring_during_call = 1; + } else { + globals.no_ring_during_call = 0; + } + } else if (!strcmp(var, "live-stream-switch")) { + if (switch_true(val)) { + globals.live_stream_switch = 1; + } else { + globals.live_stream_switch = 0; + } } else if (!strcmp(var, "ring-file")) { set_global_ring_file(val); } else if (!strcmp(var, "hold-file")) { @@ -1007,8 +1218,7 @@ static switch_status_t load_config(void) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown) { - deactivate_audio_device(); - deactivate_ring_device(); + destroy_audio_streams(); destroy_codecs(); Pa_Terminate(); @@ -1017,6 +1227,9 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown) switch_event_free_subclass(MY_EVENT_RINGING); switch_event_free_subclass(MY_EVENT_MAKE_CALL); switch_event_free_subclass(MY_EVENT_ERROR_AUDIO_DEV); + switch_event_free_subclass(MY_EVENT_CALL_HELD); + switch_event_free_subclass(MY_EVENT_CALL_RESUMED); + switch_safe_free(globals.dialplan); switch_safe_free(globals.context); @@ -1118,7 +1331,99 @@ static void PrintSupportedStandardSampleRates(const PaStreamParameters * inputPa } /*******************************************************************/ +static switch_status_t play_dev(switch_stream_handle_t *stream, int outdev, char * file, const char * max_seconds, const char * no_close) +{ + switch_file_handle_t fh = { 0 }; + int samples = 0; + int seconds = 5; + audio_stream_t * audio_stream; + int created_stream = 0; + int wrote = 0; + switch_size_t olen; + int16_t abuf[2048]; + + if (!strcasecmp(file, "ringtest")) { + file = globals.ring_file; + } + if (outdev == -1) { + stream->write_function(stream, "Invalid output audio device\n"); + return SWITCH_STATUS_FALSE; + } + audio_stream = get_audio_stream(-1, outdev); + + fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN; + + if (switch_core_file_open(&fh, file, + globals.read_codec.implementation->number_of_channels, + globals.read_codec.implementation->actual_samples_per_second, + SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "Cannot play requested file %s\n", file); + return SWITCH_STATUS_FALSE; + } + + olen = globals.read_codec.implementation->samples_per_packet; + + if (max_seconds) { + int i = atoi(max_seconds); + if (i >= 0) { + seconds = i; + } + } + + if (globals.call_list) { + switch_mutex_lock(globals.pvt_lock); + if (!globals.main_stream) { + switch_mutex_unlock(globals.pvt_lock); + return SWITCH_STATUS_FALSE; + } + + if ( switch_test_flag(globals.call_list, TFLAG_MASTER) && globals.main_stream->outdev == outdev) { /*so we are the active stream so we need to dupe it basically */ + audio_stream = create_audio_stream(-1,outdev); + created_stream=1; + } + switch_mutex_unlock(globals.pvt_lock); + } + + if (! audio_stream) { + stream->write_function(stream, "Failed to engage audio device\n"); + return SWITCH_STATUS_FALSE; + } + + + + samples = globals.read_codec.implementation->actual_samples_per_second * seconds; + globals.stream_in_use=1; + while (switch_core_file_read(&fh, abuf, &olen) == SWITCH_STATUS_SUCCESS) { + if (globals.destroying_streams || ! audio_stream->stream) { + break; + } + + WriteAudioStream(audio_stream->stream, abuf, (long) olen, &(audio_stream->write_timer)); + wrote += (int) olen; + if (samples) { + samples -= (int) olen; + if (samples <= 0) { + break; + } + } + olen = globals.read_codec.implementation->samples_per_packet; + } + globals.stream_in_use = 0; + + switch_core_file_close(&fh); + if (! globals.call_list && ( ! no_close || strcasecmp(no_close, "no_close"))) { + destroy_audio_streams(); + } + + seconds = wrote / globals.read_codec.implementation->actual_samples_per_second; + stream->write_function(stream, "playback test [%s] %d second(s) %d samples @%dkhz", + file, seconds, wrote, globals.read_codec.implementation->actual_samples_per_second); + if (created_stream) { /*still need this as not added to the global pool */ + destroy_actual_stream(audio_stream); + } + return SWITCH_STATUS_SUCCESS; +} static switch_status_t devlist(char **argv, int argc, switch_stream_handle_t *stream) { int i, numDevices, prev; @@ -1200,8 +1505,7 @@ static int dump_info(int verbose) } if (verbose < 0) { - deactivate_audio_device(); - deactivate_ring_device(); + destroy_audio_streams(); destroy_codecs(); Pa_Terminate(); Pa_Initialize(); @@ -1309,36 +1613,15 @@ static int dump_info(int verbose) return err; } -static switch_status_t engage_device(int restart) +static switch_status_t create_codecs(int restart) { - PaStreamParameters inputParameters, outputParameters; - PaError err; int sample_rate = globals.sample_rate; int codec_ms = globals.codec_ms; - switch_event_t *event; - - switch_mutex_lock(globals.device_lock); - while (globals.deactivate_timer > switch_epoch_time_now(NULL)) { - switch_yield(1000000); - } - switch_mutex_unlock(globals.device_lock); - if (restart) { - deactivate_audio_device(); - deactivate_ring_device(); destroy_codecs(); } - - if (globals.read_timer.timer_interface) { - switch_core_timer_sync(&globals.read_timer); - } - - if (globals.write_timer.timer_interface) { - switch_core_timer_sync(&globals.write_timer); - } - - if (globals.audio_stream) { + if (globals.codecs_inited) { return SWITCH_STATUS_SUCCESS; } @@ -1375,20 +1658,18 @@ static switch_status_t engage_device(int restart) return SWITCH_STATUS_FALSE; } } - - - if (!globals.write_timer.timer_interface) { - if (switch_core_timer_init(&globals.write_timer, + if (!globals.readfile_timer.timer_interface) { + if (switch_core_timer_init(&globals.readfile_timer, globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet, module_pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n"); switch_core_codec_destroy(&globals.read_codec); switch_core_codec_destroy(&globals.write_codec); - switch_core_timer_destroy(&globals.read_timer); return SWITCH_STATUS_FALSE; } } + if (!globals.hold_timer.timer_interface) { if (switch_core_timer_init(&globals.hold_timer, globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet, @@ -1397,106 +1678,119 @@ static switch_status_t engage_device(int restart) switch_core_codec_destroy(&globals.read_codec); switch_core_codec_destroy(&globals.write_codec); switch_core_timer_destroy(&globals.read_timer); - switch_core_timer_destroy(&globals.write_timer); + switch_core_timer_destroy(&globals.readfile_timer); + return SWITCH_STATUS_FALSE; } } - globals.read_frame.rate = sample_rate; - globals.read_frame.codec = &globals.read_codec; + globals.cng_frame.rate = globals.read_frame.rate = sample_rate; + globals.cng_frame.codec = globals.read_frame.codec = &globals.read_codec; - switch_mutex_lock(globals.device_lock); - /* LOCKED ************************************************************************************************** */ - inputParameters.device = globals.indev; - inputParameters.channelCount = 1; - inputParameters.sampleFormat = SAMPLE_TYPE; - inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency; - inputParameters.hostApiSpecificStreamInfo = NULL; - outputParameters.device = globals.outdev; + globals.codecs_inited=1; + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_audio_stream() +{ + audio_stream_t *stream; + if (! globals.call_list) { /* If no active calls then it will automatically switch over on next call */ + return SWITCH_STATUS_SUCCESS; + } + stream = get_audio_stream(globals.indev, globals.outdev); + if (stream == NULL) { + return SWITCH_STATUS_FALSE; + } + + globals.main_stream = stream;//TODO: need locks around here?? + + return SWITCH_STATUS_SUCCESS; +} +PaError open_audio_stream(PABLIO_Stream **stream, const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters) +{ + if (inputParameters->device != -1) { + return OpenAudioStream(stream, inputParameters, outputParameters, globals.sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, globals.dual_streams); + } + return OpenAudioStream(stream, NULL, outputParameters, globals.sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, 0); +} + +static audio_stream_t *create_audio_stream(int indev, int outdev) +{ + PaStreamParameters inputParameters, outputParameters; + PaError err; + switch_event_t *event; + audio_stream_t *stream; + + stream = malloc(sizeof(audio_stream_t)); + if (stream == NULL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to alloc memory\n"); + return NULL; + } + memset(stream, 0, sizeof(audio_stream_t)); + stream->next = NULL; + stream->stream = NULL; + stream->indev = indev; + stream->outdev = outdev; + if (!stream->write_timer.timer_interface) { + if (switch_core_timer_init(&(stream->write_timer), + globals.timer_name, globals.codec_ms, globals.read_codec.implementation->samples_per_packet, + module_pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n"); + switch_safe_free(stream); + return NULL; + } + } + inputParameters.device = indev; + if (indev != -1) { + inputParameters.channelCount = 1; + inputParameters.sampleFormat = SAMPLE_TYPE; + inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency; + inputParameters.hostApiSpecificStreamInfo = NULL; + } + outputParameters.device = outdev; outputParameters.channelCount = 1; outputParameters.sampleFormat = SAMPLE_TYPE; outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; - //err = OpenAudioStream(&globals.audio_stream, NULL/*&inputParameters*/, &outputParameters, sample_rate, paClipOff, - //globals.read_codec.implementation->samples_per_packet); - err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff, - globals.read_codec.implementation->samples_per_packet, globals.dual_streams); - /* UNLOCKED ************************************************************************************************* */ + + err = open_audio_stream(&(stream->stream), &inputParameters, &outputParameters); if (err != paNoError) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening audio device retrying\n"); switch_yield(1000000); - err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff, - globals.read_codec.implementation->samples_per_packet, globals.dual_streams); + err = open_audio_stream(&(stream->stream), &inputParameters, &outputParameters); } - switch_mutex_unlock(globals.device_lock); - if (err != paNoError) { + switch_safe_free(stream); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device\n"); - switch_core_codec_destroy(&globals.read_codec); - switch_core_codec_destroy(&globals.write_codec); - switch_core_timer_destroy(&globals.read_timer); - switch_core_timer_destroy(&globals.write_timer); - switch_core_timer_destroy(&globals.hold_timer); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_ERROR_AUDIO_DEV) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Reason", Pa_GetErrorText(err)); switch_event_fire(&event); } - return SWITCH_STATUS_FALSE; + return NULL; } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engage audio device rate: %d channels %d\n", sample_rate, outputParameters.channelCount); - - engage_ring_device(); - - return SWITCH_STATUS_SUCCESS; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created audio stream: %d channels %d\n", globals.sample_rate, outputParameters.channelCount); + return stream; } -static switch_status_t engage_ring_device(void) +audio_stream_t *get_audio_stream(int indev, int outdev) { - PaStreamParameters outputParameters = { 0 }; - PaError err; - int sample_rate = globals.sample_rate; - int channels = 1; - - if (globals.ring_stream) { - return SWITCH_STATUS_SUCCESS; + audio_stream_t *stream; + if (outdev == -1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error invalid output audio device\n"); } - - if (globals.ringdev == globals.outdev) { - if (engage_device(0) == SWITCH_STATUS_SUCCESS) { - globals.ring_stream = globals.audio_stream; - } else { - goto error; - } - } else { - switch_mutex_lock(globals.device_lock); - /* LOCKED ************************************************************************************************** */ - outputParameters.device = globals.ringdev; - outputParameters.channelCount = channels; - outputParameters.sampleFormat = SAMPLE_TYPE; - outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; - outputParameters.hostApiSpecificStreamInfo = NULL; - err = OpenAudioStream(&globals.ring_stream, NULL, - &outputParameters, sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, globals.dual_streams); - /* UNLOCKED ************************************************************************************************* */ - switch_mutex_unlock(globals.device_lock); - - if (err != paNoError) { - goto error; - } + if (create_codecs(0) != SWITCH_STATUS_SUCCESS) { + return NULL; } - - switch_yield(10000); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engage ring device rate: %d channels %d\n", sample_rate, channels); - return SWITCH_STATUS_SUCCESS; - - - error: - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open ring device\n"); - return SWITCH_STATUS_FALSE; - + stream = find_audio_stream(indev, outdev, 0); + if (stream != NULL) { + return stream; + } + stream = create_audio_stream(indev, outdev); + if (stream) { + add_stream(stream, 0); + } + return stream; } static switch_status_t dtmf_call(char **argv, int argc, switch_stream_handle_t *stream) @@ -1523,6 +1817,211 @@ static switch_status_t dtmf_call(char **argv, int argc, switch_stream_handle_t * return SWITCH_STATUS_SUCCESS; } +static switch_status_t close_streams(char **argv, int argc, switch_stream_handle_t *stream) +{ + if (globals.call_list) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); + return SWITCH_STATUS_FALSE; + } + destroy_audio_streams(); + stream->write_function(stream, "closestreams all open streams closed\n"); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t set_indev(char **argv, int argc, switch_stream_handle_t *stream) +{ + int devval; + + if (globals.call_list && ! globals.live_stream_switch) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); + return SWITCH_STATUS_FALSE; + } + if (*argv[0] == '#') { + devval = get_dev_by_number(argv[0] + 1, 1); + } else { + devval = get_dev_by_name(argv[0], 1); + } + if (devval < 0) { + stream->write_function(stream, "indev not set (invalid value)\n"); + return SWITCH_STATUS_FALSE; + } + globals.indev = devval; + switch_audio_stream(); + stream->write_function(stream, "indev set to %d\n", devval); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t set_outdev(char **argv, int argc, switch_stream_handle_t *stream) +{ + int devval; + if (globals.call_list && ! globals.live_stream_switch) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); + return SWITCH_STATUS_FALSE; + } + if (*argv[0] == '#') { + devval = get_dev_by_number(argv[0] + 1, 0); + } else { + devval = get_dev_by_name(argv[0], 0); + } + if (devval < 0) { + stream->write_function(stream, "outdev not set (invalid value)\n"); + return SWITCH_STATUS_FALSE; + } + + globals.outdev = devval; + switch_audio_stream(); + stream->write_function(stream, "outdev set to %d\n", devval); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t prepare_stream(char **argv, int argc, switch_stream_handle_t *stream) +{ + int devval=-2,devval2=-1; + if (! strcmp(argv[0], "#-1")) { + devval = -1; + } else if (*argv[0] == '#') { + devval = get_dev_by_number(argv[0]+1, 1); + } + if (devval == -2) { + stream->write_function(stream, "preparestream not prepared as indev has (invalid value)\n"); + return SWITCH_STATUS_FALSE; + } + if (*argv[1] == '#') { + devval2 = get_dev_by_number(argv[1]+1, 0); + } + if (devval2 == -1) { + stream->write_function(stream, "preparestream not prepared as outdev has (invalid value)\n"); + return SWITCH_STATUS_FALSE; + } + + if (! get_audio_stream(devval,devval2)) { + stream->write_function(stream, "preparestream not prepared received an invalid stream back\n"); + return SWITCH_STATUS_FALSE; + } + stream->write_function(stream, "preparestream prepared indev: %d outdev: %d\n", devval, devval2); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_stream(char **argv, int argc, switch_stream_handle_t *stream) +{ + int devval =-1, devval2 = -1; + if (globals.call_list && ! globals.live_stream_switch) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); + return SWITCH_STATUS_FALSE; + } + if (*argv[0] == '#') { + devval = get_dev_by_number(argv[0]+1, 1); + } + if (devval == -1) { + stream->write_function(stream, "switchstream not prepared as indev has (invalid value)\n"); + return SWITCH_STATUS_FALSE; + } + if (*argv[1] == '#') { + devval2 = get_dev_by_number(argv[1]+1, 0); + } + if (devval2 == -1) { + stream->write_function(stream, "switchstream not prepared as outdev has (invalid value)\n"); + return SWITCH_STATUS_FALSE; + } + globals.indev = devval; + globals.outdev = devval2; + if (switch_audio_stream() != SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "switchstream was unable to switch\n"); + return SWITCH_STATUS_FALSE; + } + stream->write_function(stream, "switchstream switched to indev: %d outdev: %d\n", devval, devval2); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t set_ringdev(char **argv, int argc, switch_stream_handle_t *stream) +{ + int devval; + if (globals.call_list && ! globals.live_stream_switch) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); + return SWITCH_STATUS_FALSE; + } + if (! strcmp(argv[0], "#-1")) { + globals.ring_stream = NULL; + globals.ringdev = -1; + stream->write_function(stream, "ringdev set to %d\n", globals.ringdev); + return SWITCH_STATUS_SUCCESS; + } else if (*argv[0] == '#') { + devval = get_dev_by_number(argv[0] + 1, 0); + } else { + devval = get_dev_by_name(argv[0], 0); + } + if (devval == -1) { + stream->write_function(stream, "ringdev not set as dev has (invalid value)\n"); + return SWITCH_STATUS_FALSE; + } + globals.ringdev = devval; + stream->write_function(stream, "ringdev set to %d\n", globals.ringdev); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t looptest(char **argv, int argc, switch_stream_handle_t *stream) +{ + int samples = 0; + int success = 0; + int i; + + if (globals.call_list) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); + return SWITCH_STATUS_FALSE; + } + if (validate_main_audio_stream() != SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "looptest Failed to engage audio device\n"); + return SWITCH_STATUS_FALSE; + } + globals.stream_in_use = 1; + for (i = 0; i < 400; i++) { + if (globals.destroying_streams || ! globals.main_stream->stream) { + break; + } + if ((samples = ReadAudioStream(globals.main_stream->stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, &globals.read_timer))) { + WriteAudioStream(globals.main_stream->stream, globals.read_frame.data, (long) samples, &(globals.main_stream->write_timer)); + success = 1; + } + switch_yield(10000); + } + globals.stream_in_use = 0; + + if (!success) { + stream->write_function(stream, "Failed to read any bytes from indev\n"); + return SWITCH_STATUS_FALSE; + } + destroy_audio_streams(); + stream->write_function(stream, "looptest complete\n"); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t set_ringfile(char **argv, int argc, switch_stream_handle_t *stream) +{ + if (! argv[0]) { + stream->write_function(stream, "%s", globals.ring_file); + return SWITCH_STATUS_SUCCESS; + } + if (create_codecs(0) == SWITCH_STATUS_SUCCESS) { + switch_file_handle_t fh = { 0 }; + if (switch_core_file_open(&fh, + argv[0], + globals.read_codec.implementation->number_of_channels, + globals.read_codec.implementation->actual_samples_per_second, + SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) { + switch_core_file_close(&fh); + set_global_ring_file(argv[0]); + } else { + stream->write_function(stream, "ringfile Unable to open ring file %s\n", argv[0]); + return SWITCH_STATUS_FALSE; + } + } else { + stream->write_function(stream, "ringfile Failed to init codecs device\n"); + return SWITCH_STATUS_FALSE; + } + stream->write_function(stream, "ringfile set to %s", globals.ring_file); + return SWITCH_STATUS_SUCCESS; +} + static switch_status_t switch_call(char **argv, int argc, switch_stream_handle_t *stream) { private_t *tp, *tech_pvt = NULL; @@ -1542,7 +2041,10 @@ static switch_status_t switch_call(char **argv, int argc, switch_stream_handle_t } } else if (!strcasecmp(callid, "none")) { for (tp = globals.call_list; tp; tp = tp->next) { + if (switch_test_flag(tp, TFLAG_MASTER)) { switch_clear_flag_locked(tp, TFLAG_MASTER); + create_hold_event(tp,0); + } } stream->write_function(stream, "OK\n"); goto done; @@ -1559,6 +2061,7 @@ static switch_status_t switch_call(char **argv, int argc, switch_stream_handle_t remove_pvt(tech_pvt); } add_pvt(tech_pvt, PA_MASTER); + create_hold_event(tech_pvt, 1); stream->write_function(stream, "OK\n"); } else { stream->write_function(stream, "NO SUCH CALL\n"); @@ -1609,7 +2112,6 @@ static switch_status_t answer_call(char **argv, int argc, switch_stream_handle_t switch_channel_t *channel = switch_core_session_get_channel(tp->session); switch_set_flag_locked(tp, TFLAG_ANSWER); add_pvt(tp, PA_MASTER); - deactivate_ring_device(); switch_channel_mark_answered(channel); } } else { @@ -1624,7 +2126,6 @@ static switch_status_t answer_call(char **argv, int argc, switch_stream_handle_t switch_channel_t *channel = switch_core_session_get_channel(tp->session); switch_set_flag_locked(tp, TFLAG_ANSWER); add_pvt(tp, PA_MASTER); - deactivate_ring_device(); switch_channel_mark_answered(channel); x++; break; @@ -1766,7 +2267,6 @@ static switch_status_t place_call(char **argv, int argc, switch_stream_handle_t channel = switch_core_session_get_channel(session); switch_core_session_set_private(session, tech_pvt); tech_pvt->session = session; - globals.flags = GFLAG_EAR | GFLAG_MOUTH; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); switch_core_session_destroy(&session); @@ -1805,9 +2305,8 @@ static switch_status_t place_call(char **argv, int argc, switch_stream_handle_t switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); } tech_pvt->session = session; - if ((status = engage_device(0)) == SWITCH_STATUS_SUCCESS) { + if ((status = validate_main_audio_stream()) == SWITCH_STATUS_SUCCESS) { switch_set_flag_locked(tech_pvt, TFLAG_ANSWER); - deactivate_ring_device(); switch_channel_mark_answered(channel); switch_channel_set_state(channel, CS_INIT); if (switch_core_session_thread_launch(tech_pvt->session) != SWITCH_STATUS_SUCCESS) { @@ -1855,10 +2354,11 @@ SWITCH_STANDARD_API(pa_cmd) { char *argv[1024] = { 0 }; int argc = 0; - char *mycmd = NULL, *devname = NULL; + char *mycmd = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; pa_command_t func = NULL; - int lead = 1, devval = 0; + int devval; + int lead = 1; char *wcmd = NULL, *action = NULL; char cmd_buf[1024] = ""; char *http = NULL; @@ -1878,9 +2378,15 @@ SWITCH_STANDARD_API(pa_cmd) "pa devlist [xml]\n" "pa indev #|\n" "pa outdev #|\n" + "pa preparestream # #\n" + "pa switchstream # #\n" + "pa closestreams\n" "pa ringdev #|\n" - "pa play [ringtest|]\n" - "pa ringfile [filename]\n" "pa looptest\n" "--------------------------------------------------------------------------------\n"; + "pa play [ringtest|] [seconds] [no_close]\n" + "pa playdev # [ringtest|] [seconds] [no_close]\n" + "pa ringfile [filename]\n" + "pa looptest\n" + "--------------------------------------------------------------------------------\n"; if (stream->param_event) { @@ -1973,169 +2479,42 @@ SWITCH_STANDARD_API(pa_cmd) func = switch_call; } else if (!strcasecmp(argv[0], "dtmf")) { func = dtmf_call; + } else if (!strcasecmp(argv[0], "closestreams")) { + func = close_streams; } else if (argv[1] && !strcmp(argv[0], "indev")) { - - if (globals.call_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - goto done; - } - - if (*argv[1] == '#') { - devval = get_dev_by_number(argv[1] + 1, 1); - } else { - devval = get_dev_by_name(argv[1], 1); - } - devname = "indev"; - if (devval > -1) { - globals.indev = devval; - //engage_device(1); - } + func = set_indev; } else if (argv[1] && !strcmp(argv[0], "outdev")) { - - if (globals.call_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - goto done; - } - - if (*argv[1] == '#') { - devval = get_dev_by_number(argv[1] + 1, 0); - } else { - devval = get_dev_by_name(argv[1], 0); - } - devname = "outdev"; - if (devval > -1) { - globals.outdev = devval; - //engage_device(1); - } + func = set_outdev; + } else if (argv[1] && argv[2] && !strcmp(argv[0], "preparestream")) { + func = prepare_stream; + } else if (argv[1] && argv[2] && !strcmp(argv[0], "switchstream")) { + func = switch_stream; } else if (argv[1] && !strcmp(argv[0], "ringdev")) { - - if (globals.call_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - goto done; - } - - if (*argv[1] == '#') { - devval = get_dev_by_number(argv[1] + 1, 0); - } else { - devval = get_dev_by_name(argv[1], 0); - } - devname = "ringdev"; - if (devval > -1) { - globals.ringdev = devval; - //engage_device(1); - } - } else if ((argv[1] && !strcasecmp(argv[0], "play"))) { - switch_file_handle_t fh = { 0 }; - char *playfile = NULL; - int samples = 0; - int seconds = 5; - int wrote = 0; - - if (globals.call_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - goto done; - } - - if (!strcasecmp(argv[1], "ringtest")) { - playfile = globals.ring_file; - } else { - playfile = argv[1]; - } - - fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN; - if (engage_device(0) == SWITCH_STATUS_SUCCESS) { - if (switch_core_file_open(&fh, - playfile, - globals.read_codec.implementation->number_of_channels, - globals.read_codec.implementation->actual_samples_per_second, - SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) { - switch_size_t olen = globals.read_codec.implementation->samples_per_packet; - int16_t abuf[2048]; - - if (argv[2]) { - int i = atoi(argv[2]); - if (i >= 0) { - seconds = i; - } - } - - samples = globals.read_codec.implementation->actual_samples_per_second * seconds; - while (switch_core_file_read(&fh, abuf, &olen) == SWITCH_STATUS_SUCCESS) { - WriteAudioStream(globals.audio_stream, abuf, (long) olen, &globals.read_timer); - wrote += (int) olen; - if (samples) { - samples -= (int) olen; - if (samples <= 0) { - break; - } - } - olen = globals.read_codec.implementation->samples_per_packet; - } - - switch_core_file_close(&fh); - deactivate_audio_device(); - - seconds = wrote / globals.read_codec.implementation->actual_samples_per_second; - stream->write_function(stream, "playback test [%s] %d second(s) %d samples @%dkhz", - playfile, seconds, wrote, globals.read_codec.implementation->actual_samples_per_second); - - - } else { - stream->write_function(stream, "Cannot play requested file %s\n", argv[1]); - } - } else { + func = set_ringdev; + } else if ((argv[1] && !strcmp(argv[0], "play"))) { + if (validate_main_audio_stream() == SWITCH_STATUS_SUCCESS) { + play_dev(stream, globals.main_stream ? globals.main_stream->outdev : -1,argv[1],argv[2], argv[3]); + }else{ stream->write_function(stream, "Failed to engage audio device\n"); } goto done; + } else if ((argv[1] && argv[2] && !strcmp(argv[0], "playdev"))) { + if (*argv[1] == '#') { + devval = get_dev_by_number(argv[1] + 1, 0); + } else { + devval = -1; + } + play_dev(stream, devval,argv[2],argv[3],argv[4]); + goto done; } else if (!strcasecmp(argv[0], "looptest")) { - if (globals.call_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - goto done; - } - - if (engage_device(0) == SWITCH_STATUS_SUCCESS) { - int samples = 0; - int success = 0; - int i; - for (i = 0; i < 400; i++) { - if ((samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data, - globals.read_codec.implementation->samples_per_packet, &globals.read_timer))) { - WriteAudioStream(globals.audio_stream, globals.read_frame.data, (long) samples, &globals.write_timer); - success = 1; - } - switch_yield(10000); - } - if (!success) { - stream->write_function(stream, "Failed to read any bytes from indev\n"); - } - deactivate_audio_device(); - } else { - stream->write_function(stream, "Failed to engage audio device\n"); - } - goto done; + func = looptest; } else if (!strcasecmp(argv[0], "ringfile")) { - if (argv[1]) { - if (engage_device(0) == SWITCH_STATUS_SUCCESS) { - switch_file_handle_t fh = { 0 }; - if (switch_core_file_open(&fh, - argv[1], - globals.read_codec.implementation->number_of_channels, - globals.read_codec.implementation->actual_samples_per_second, - SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) { - switch_core_file_close(&fh); - set_global_ring_file(argv[1]); - } else { - stream->write_function(stream, "Unable to open ring file %s\n", argv[1]); - } - } else { - stream->write_function(stream, "Failed to engage audio device\n"); - } - } else { - stream->write_function(stream, "%s", globals.ring_file); - } - goto done; + func = set_ringfile; + } else { + stream->write_function(stream, "Unknown Command or not enough args [%s]\n", argv[0]); } + if (func) { if (http) { stream->write_function(stream, "
");
@@ -2143,21 +2522,12 @@ SWITCH_STANDARD_API(pa_cmd)
 
 		switch_mutex_lock(globals.pa_mutex);
 		status = func(&argv[lead], argc - lead, stream);
+		status = SWITCH_STATUS_SUCCESS; /*if func was defined we want to always return success as the command was found */
 		switch_mutex_unlock(globals.pa_mutex);
 
 		if (http) {
 			stream->write_function(stream, "\n\n
"); } - } else { - if (devname) { - if (devval > -1) { - stream->write_function(stream, "%s set to %d\n", devname, devval); - } else { - stream->write_function(stream, "%s not set (invalid value)\n", devname); - } - } else { - stream->write_function(stream, "Unknown Command [%s]\n", argv[0]); - } } done: @@ -2171,6 +2541,14 @@ SWITCH_STANDARD_API(pa_cmd) " " " " " " + " " + " " + " " + " " + " " + " " + " " + " " "

" "\n" "" From e79174cacf6abb943fe34840a5261b940b281c91 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 Feb 2011 19:32:14 -0600 Subject: [PATCH 54/86] fix regression from d72cde9b76a856cf002366300bea02c26db44ffb --- src/switch_core_session.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 4836aae73f..d2e28de523 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1865,6 +1865,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_app_flags(const char *ap SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_async(switch_core_session_t *session, const char *app, const char *arg) { switch_event_t *execute_event; + char *ap, *arp; + + if (!arg && strstr(app, "::")) { + ap = switch_core_session_strdup(session, app); + app = ap; + + if ((arp = strstr(ap, "::"))) { + *arp = '\0'; + arg = arp + 2; + } + } if (switch_event_create(&execute_event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute"); @@ -1894,6 +1905,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flag switch_application_interface_t *application_interface; switch_status_t status = SWITCH_STATUS_SUCCESS; + if (!arg && strstr(app, "::")) { + return switch_core_session_execute_application_async(session, app, arg); + } + if (switch_channel_down(session->channel)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Channel is hungup, aborting execution of application: %s\n", app); return SWITCH_STATUS_FALSE; From bdf678e401a8077aab06b9c04004c92ef6631e26 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 Feb 2011 20:12:36 -0600 Subject: [PATCH 55/86] dont run execute_on_fsk when there was no data collected --- src/mod/applications/mod_fsk/mod_fsk.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_fsk/mod_fsk.c b/src/mod/applications/mod_fsk/mod_fsk.c index 9802353075..0291707c62 100644 --- a/src/mod/applications/mod_fsk/mod_fsk.c +++ b/src/mod/applications/mod_fsk/mod_fsk.c @@ -220,6 +220,7 @@ static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_dat char *sp; switch_event_t *event; const char *app_var; + int total = 0; switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA); @@ -255,6 +256,7 @@ static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_dat } if (varname && val) { + total++; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s setting FSK var [%s][%s]\n", switch_channel_get_name(channel), varname, val); switch_channel_set_variable(channel, varname, val); @@ -270,7 +272,7 @@ static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_dat } } - if ((app_var = switch_channel_get_variable(channel, "execute_on_fsk"))) { + if (total && (app_var = switch_channel_get_variable(channel, "execute_on_fsk"))) { char *app_arg; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s processing execute_on_fsk [%s]\n", From dc436b82a52da05686ac178ad7854556e9688ed8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 Feb 2011 20:42:17 -0600 Subject: [PATCH 56/86] block control-z from fs cli and print a warning how to exit properly --- libs/esl/fs_cli.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index 1e3bf04ca1..19e8d7f82a 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -8,6 +8,7 @@ #include #define CMD_BUFLEN 1024 +static int WARN_STOP = 0; #ifdef WIN32 #define strdup(src) _strdup(src) @@ -535,6 +536,13 @@ static BOOL console_readConsole(HANDLE conIn, char* buf, int len, int* pRed, int static void handle_SIGINT(int sig) { if (sig); + + WARN_STOP = 1; + + signal(SIGINT, handle_SIGINT); +#ifdef SIGTSTP + signal(SIGTSTP, handle_SIGINT); +#endif return; } @@ -581,6 +589,12 @@ static void *msg_thread_run(esl_thread_t *me, void *obj) while(thread_running && handle->connected) { esl_status_t status = esl_recv_event_timed(handle, 10, 1, NULL); + + if (WARN_STOP) { + printf("Type control-D or /exit or /quit or /bye to exit.\n\n"); + WARN_STOP = 0; + } + if (status == ESL_FAIL) { esl_log(ESL_LOG_WARNING, "Disconnected.\n"); running = -1; thread_running = 0; @@ -1023,6 +1037,9 @@ int main(int argc, char *argv[]) } signal(SIGINT, handle_SIGINT); +#ifdef SIGTSTP + signal(SIGTSTP, handle_SIGINT); +#endif #ifdef SIGQUIT signal(SIGQUIT, handle_SIGQUIT); #endif From 2d190b37abe00999a2e76861b8c88f0053e0b78f Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 3 Feb 2011 23:46:19 -0600 Subject: [PATCH 57/86] fix iLBC under windows --- libs/ilbc/src/iLBC_decode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/ilbc/src/iLBC_decode.c b/libs/ilbc/src/iLBC_decode.c index fc46fe408c..9fc7a24bb4 100644 --- a/libs/ilbc/src/iLBC_decode.c +++ b/libs/ilbc/src/iLBC_decode.c @@ -47,7 +47,9 @@ { fld dbl frndint + fstp dbl } + return (long int) dbl; } #elif defined (_WIN64) #include From b6ac001276961761b14a89270da02498b4d3e740 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 08:44:11 -0600 Subject: [PATCH 58/86] fix regression from f60fdf653dd2d7f8d3eaa6a9086e1f68bd993c59 --- src/mod/applications/mod_dptools/mod_dptools.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 4be2a64f61..0b16492e14 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -2887,7 +2887,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, switch_call_cause_t *cancel_cause) { switch_xml_t x_domain = NULL, xml = NULL, x_user = NULL, x_group = NULL, x_param, x_params; - char *user = NULL, *domain = NULL; + char *user = NULL, *domain = NULL, *dup_domain = NULL; const char *dest = NULL; static switch_call_cause_t cause = SWITCH_CAUSE_NONE; unsigned int timelimit = 60; @@ -2908,7 +2908,8 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, if ((domain = strchr(user, '@'))) { *domain++ = '\0'; } else { - domain = switch_core_get_variable_pdup("domain", switch_core_session_get_pool(session)); + domain = switch_core_get_variable_dup("domain"); + dup_domain = domain; } if (!domain) { @@ -3115,6 +3116,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, } switch_safe_free(user); + switch_safe_free(dup_domain); return cause; } From 46f6c6e42d2775ccfecb8f445ebbaaf32ab34df7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 08:56:30 -0600 Subject: [PATCH 59/86] fix regression from f60fdf653dd2d7f8d3eaa6a9086e1f68bd993c59 --- src/mod/applications/mod_dptools/mod_dptools.c | 4 +++- .../dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 0b16492e14..f7bf86b4c7 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -2774,7 +2774,7 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session switch_originate_flag_t myflags = SOF_NONE; char *cid_name_override = NULL; char *cid_num_override = NULL; - char *domain = NULL; + char *domain = NULL, *dup_domain = NULL; switch_channel_t *new_channel = NULL; unsigned int timelimit = 60; const char *skip, *var; @@ -2788,6 +2788,7 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session *domain++ = '\0'; } else { domain = switch_core_get_variable_pdup("domain", switch_core_session_get_pool(session)); + dup_domain = domain; } if (!domain) { @@ -2859,6 +2860,7 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session switch_safe_free(template); switch_safe_free(group); + switch_safe_free(dup_domain); if (cause == SWITCH_CAUSE_NONE) { cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; diff --git a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c index 43534dadba..3bc5cb4a3d 100644 --- a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c +++ b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c @@ -309,11 +309,13 @@ static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, switch_call_cause_t *cancel_cause) { const char *profile; + char *dup_profile = NULL; if (session) { profile = switch_channel_get_variable(switch_core_session_get_channel(session), "sip_profile"); } else { - profile = switch_core_get_variable_pdup("sip_profile", switch_core_session_get_pool(session)); + dup_profile = switch_core_get_variable_dup("sip_profile"); + profile = dup_profile; } if (zstr(profile)) { profile = "default"; @@ -323,6 +325,8 @@ static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, UNPROTECT_INTERFACE(sip_endpoint_interface); + switch_safe_free(dup_profile); + return switch_core_session_outgoing_channel(session, var_event, "sofia", outbound_profile, new_session, pool, SOF_NONE, cancel_cause); } From 2ec2a9b0d335a8d6a30ab5a92448ac3ad63649ff Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 09:40:04 -0600 Subject: [PATCH 60/86] skip blocking writes on fs_cli to avoid backing up event socket --- libs/esl/fs_cli.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index 19e8d7f82a..a70d63fab5 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -589,22 +589,36 @@ static void *msg_thread_run(esl_thread_t *me, void *obj) while(thread_running && handle->connected) { esl_status_t status = esl_recv_event_timed(handle, 10, 1, NULL); - - if (WARN_STOP) { - printf("Type control-D or /exit or /quit or /bye to exit.\n\n"); - WARN_STOP = 0; - } + int aok = 1; if (status == ESL_FAIL) { - esl_log(ESL_LOG_WARNING, "Disconnected.\n"); + if (aok) esl_log(ESL_LOG_WARNING, "Disconnected.\n"); running = -1; thread_running = 0; } else if (status == ESL_SUCCESS) { +#ifndef WIN32 + fd_set can_write; + int fd; + struct timeval to; + + fd = fileno(stdout); + memset(&to, 0, sizeof(to)); + FD_ZERO(&can_write); + FD_SET(fd, &can_write); + to.tv_sec = 0; + to.tv_usec = 100000; + if (select(fd + 1, NULL, &can_write, NULL, &to) > 0) { + aok = FD_ISSET(fd, &can_write); + } else { + aok = 0; + } +#endif + if (handle->last_event) { const char *type = esl_event_get_header(handle->last_event, "content-type"); int known = 0; if (!esl_strlen_zero(type)) { - if (!strcasecmp(type, "log/data")) { + if (aok && !strcasecmp(type, "log/data")) { const char *userdata = esl_event_get_header(handle->last_event, "user-data"); if (esl_strlen_zero(userdata) || esl_strlen_zero(filter_uuid) || !strcasecmp(filter_uuid, userdata)) { @@ -631,7 +645,7 @@ static void *msg_thread_run(esl_thread_t *me, void *obj) } else if (!strcasecmp(type, "text/disconnect-notice")) { running = -1; thread_running = 0; known++; - } else if (!strcasecmp(type, "text/event-plain")) { + } else if (aok && !strcasecmp(type, "text/event-plain")) { char *foo; esl_event_serialize(handle->last_ievent, &foo, ESL_FALSE); printf("RECV EVENT\n%s\n", foo); @@ -641,7 +655,7 @@ static void *msg_thread_run(esl_thread_t *me, void *obj) } } - if (!known) { + if (aok && !known) { char *foo; printf("INCOMING DATA [%s]\n%s\n", type, handle->last_event->body ? handle->last_event->body : ""); esl_event_serialize(handle->last_event, &foo, ESL_FALSE); @@ -651,6 +665,11 @@ static void *msg_thread_run(esl_thread_t *me, void *obj) } } + if (WARN_STOP) { + if (aok) printf("Type control-D or /exit or /quit or /bye to exit.\n\n"); + WARN_STOP = 0; + } + usleep(1000); } From 36f6218b8bba3233cf3fb501b01a0288a08e9f00 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 10:58:26 -0600 Subject: [PATCH 61/86] add sanity check on jitterbuffer debug --- src/switch_rtp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index e8d7558bce..4df867aa64 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1875,6 +1875,10 @@ static void jb_logger(const char *file, const char *func, int line, int level, c SWITCH_DECLARE(switch_status_t) switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp_session, const char *name) { + if (!switch_rtp_ready(rtp_session)) { + return SWITCH_STATUS_FALSE; + } + stfu_n_debug(rtp_session->jb, name); stfu_global_set_logger(jb_logger); From e9e33f5160fb5272c4f912dac6a29415215bba1c Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Fri, 4 Feb 2011 12:48:07 -0600 Subject: [PATCH 62/86] FS-3033 VS2010 libportaudio project improvements for DirectX builds and switch to build DirectX by default --- Freeswitch.2010.sln | 24 ++-- .../build/msvc/portaudio.2010.vcxproj | 136 ++++-------------- 2 files changed, 43 insertions(+), 117 deletions(-) diff --git a/Freeswitch.2010.sln b/Freeswitch.2010.sln index edee701d51..464cb2e273 100644 --- a/Freeswitch.2010.sln +++ b/Freeswitch.2010.sln @@ -1569,18 +1569,18 @@ Global {0A18A071-125E-442F-AFF7-A3F68ABECF99}.All|x64 Setup.ActiveCfg = Release DirectSound|x64 {0A18A071-125E-442F-AFF7-A3F68ABECF99}.All|x64 Setup.Build.0 = Release DirectSound|x64 {0A18A071-125E-442F-AFF7-A3F68ABECF99}.All|x86 Setup.ActiveCfg = Release DirectSound|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.ActiveCfg = Debug|Win32 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.Build.0 = Debug|Win32 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.ActiveCfg = Debug|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.Build.0 = Debug|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64 Setup.ActiveCfg = Debug|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x86 Setup.ActiveCfg = Debug|Win32 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.ActiveCfg = Release|Win32 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.Build.0 = Release|Win32 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.ActiveCfg = Release|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.Build.0 = Release|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64 Setup.ActiveCfg = Release|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x86 Setup.ActiveCfg = Release|Win32 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.ActiveCfg = Debug DirectSound|Win32 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.Build.0 = Debug DirectSound|Win32 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.ActiveCfg = Debug DirectSound|x64 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.Build.0 = Debug DirectSound|x64 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64 Setup.ActiveCfg = Debug DirectSound|x64 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x86 Setup.ActiveCfg = Debug DirectSound|Win32 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.ActiveCfg = Release DirectSound|Win32 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.Build.0 = Release DirectSound|Win32 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.ActiveCfg = Release DirectSound|x64 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.Build.0 = Release DirectSound|x64 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64 Setup.ActiveCfg = Release DirectSound|x64 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x86 Setup.ActiveCfg = Release DirectSound|Win32 {08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.All|Win32.ActiveCfg = Release|x64 {08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.All|x64.ActiveCfg = Release|x64 {08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.All|x64.Build.0 = Release|x64 diff --git a/libs/portaudio/build/msvc/portaudio.2010.vcxproj b/libs/portaudio/build/msvc/portaudio.2010.vcxproj index b4eca56713..10b4c25fd9 100644 --- a/libs/portaudio/build/msvc/portaudio.2010.vcxproj +++ b/libs/portaudio/build/msvc/portaudio.2010.vcxproj @@ -41,11 +41,11 @@ - DynamicLibrary + StaticLibrary false - DynamicLibrary + StaticLibrary false @@ -57,11 +57,11 @@ false - DynamicLibrary + StaticLibrary false - DynamicLibrary + StaticLibrary false @@ -77,9 +77,11 @@ + + @@ -92,10 +94,12 @@ + + @@ -110,18 +114,6 @@ <_ProjectFileVersion>10.0.30319.1 - $(Configuration)\ - $(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Configuration)\ - $(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false @@ -231,45 +223,23 @@ true true Win32 - .\Debug_x86/portaudio.tlb - - Disabled ..\..\src\common;..\..\include;.\;..\..\src\os\win;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions) + WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_WMME;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL - $(Platform)\$(Configuration)/portaudio.pch - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ Level3 true - ProgramDatabase _DEBUG;%(PreprocessorDefinitions) 0x0409 - - ksuser.lib;%(AdditionalDependencies) - $(Platform)\$(Configuration)\portaudio_x86.dll - true - .\portaudio.def - true - $(Platform)\$(Configuration)\portaudio_x86.pdb - false - - - $(Platform)\$(Configuration)\portaudio_x86.lib - MachineX86 - true - $(Platform)\$(Configuration)\portaudio.bsc @@ -278,45 +248,23 @@ true true X64 - .\Debug_x86/portaudio.tlb - - Disabled ..\..\src\common;..\..\include;.\;..\..\src\os\win;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions) + WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_WMME;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL - $(Platform)\$(Configuration)\portaudio.pch - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ Level3 true - ProgramDatabase _DEBUG;%(PreprocessorDefinitions) 0x0409 - - ksuser.lib;%(AdditionalDependencies) - $(Platform)\$(Configuration)\portaudio_x64.dll - true - .\portaudio.def - true - $(Platform)\$(Configuration)/portaudio_x64.pdb - false - - - $(Platform)\$(Configuration)\portaudio_x64.lib - MachineX64 - true - $(Platform)\$(Configuration)/portaudio_x64.bsc @@ -325,22 +273,15 @@ true true Win32 - .\Release_x86/portaudio.tlb - - MaxSpeed - OnlyExplicitInline + Default ..\..\src\common;..\..\include;.\;..\..\src\os\win;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;%(PreprocessorDefinitions) + WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_WMME;%(PreprocessorDefinitions) true MultiThreadedDLL true - $(Platform)\$(Configuration)/portaudio.pch - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ Level3 true @@ -348,20 +289,8 @@ NDEBUG;%(PreprocessorDefinitions) 0x0409 - - $(Platform)\$(Configuration)\portaudio_x86.dll - true - .\portaudio.def - $(Platform)\$(Configuration)\portaudio_x86.pdb - false - - - $(Platform)\$(Configuration)\portaudio_x86.lib - MachineX86 - true - $(Platform)\$(Configuration)\portaudio.bsc @@ -370,22 +299,15 @@ true true X64 - .\Release_x86/portaudio.tlb - - MaxSpeed - OnlyExplicitInline - ..\..\src\common;..\..\include;.\;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + Default + ..\..\src\common;..\..\include;.\;..\..\src\os\win;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_WMME;%(PreprocessorDefinitions) true MultiThreadedDLL true - $(Platform)\$(Configuration)\portaudio.pch - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ Level3 true @@ -393,20 +315,8 @@ NDEBUG;%(PreprocessorDefinitions) 0x0409 - - $(Platform)\$(Configuration)\portaudio_x64.dll - true - .\portaudio.def - $(Platform)\$(Configuration)/portaudio_x64.pdb - false - - - $(Platform)\$(Configuration)/portaudio_x64.lib - MachineX64 - true - $(Platform)\$(Configuration)\portaudio_x64.bsc @@ -594,6 +504,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -605,6 +516,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -618,6 +530,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -629,6 +542,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -642,6 +556,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -653,6 +568,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -666,6 +582,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -677,6 +594,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -690,6 +608,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -701,6 +620,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -714,6 +634,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -725,6 +646,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -738,6 +660,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -749,6 +672,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -762,6 +686,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -773,6 +698,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true From f4481b05ab8ae1faf6eedb438085e688371e79c6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 13:05:48 -0600 Subject: [PATCH 63/86] fix sql err --- src/mod/endpoints/mod_sofia/sofia_presence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index a38a61eab8..2313cb7a1a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -2576,7 +2576,7 @@ uint32_t sofia_presence_contact_count(sofia_profile_t *profile, const char *cont char buf[32] = ""; char *sql; - sql = switch_mprintf("select count(*) from sip_subscriptions where profile_name='%q' and contact_str='%q'", profile->name, contact_str); + sql = switch_mprintf("select count(*) from sip_subscriptions where profile_name='%q' and contact='%q'", profile->name, contact_str); sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf)); switch_safe_free(sql); From b8b7266abb7a6c081ad1e1531aea69daf5d7509c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 13:11:31 -0600 Subject: [PATCH 64/86] add default to conf to demonstrate min-idle-cpu --- conf/autoload_configs/switch.conf.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/conf/autoload_configs/switch.conf.xml b/conf/autoload_configs/switch.conf.xml index 8342f120fc..32cb76f08a 100644 --- a/conf/autoload_configs/switch.conf.xml +++ b/conf/autoload_configs/switch.conf.xml @@ -23,6 +23,10 @@ + + + + + diff --git a/src/mod/codecs/mod_opus/Makefile b/src/mod/codecs/mod_opus/Makefile new file mode 100644 index 0000000000..a34695678b --- /dev/null +++ b/src/mod/codecs/mod_opus/Makefile @@ -0,0 +1,28 @@ +BASE=../../../.. + +OPUS=opus-0.9.0 + +OPUS_DIR=$(switch_srcdir)/libs/$(OPUS) +OPUS_BUILDDIR=$(switch_builddir)/libs/$(OPUS) +LOCAL_CFLAGS=-I$(OPUS_DIR)/src -g -O2 + +IETF_LA=$(OPUS_BUILDDIR)/src/.libs/libietfcodec.a +CELT_LA=$(OPUS_BUILDDIR)/celt/libcelt/.libs/libcelt0.a +SILK_LA=$(OPUS_BUILDDIR)/silk/.libs/libSKP_SILK_SDK.a + +LOCAL_LIBADD=$(IETF_LA) $(CELT_LA) $(SILK_LA) -lm -lz + +include $(BASE)/build/modmake.rules + +$(OPUS_DIR): + $(GETLIB) $(OPUS).tar.gz + +$(OPUS_BUILDDIR)/Makefile: $(OPUS_DIR) + mkdir -p $(OPUS_BUILDDIR) + cd $(OPUS_BUILDDIR) && $(DEFAULT_VARS) $(OPUS_DIR)/configure --disable-shared --with-pic --srcdir=$(OPUS_DIR) + $(TOUCH_TARGET) + +$(IETF_LA): $(OPUS_BUILDDIR)/Makefile + cd $(OPUS_BUILDDIR) && $(MAKE) + $(TOUCH_TARGET) + diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c new file mode 100644 index 0000000000..341254fe0c --- /dev/null +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -0,0 +1,209 @@ +/* + * 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): + * + * Brian K. West + * + * mod_opus.c -- The OPUS ultra-low delay audio codec (http://www.opus-codec.org/) + * + */ + +#include "switch.h" +#include "opus.h" + + +SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load); +SWITCH_MODULE_DEFINITION(mod_opus, mod_opus_load, NULL, NULL); + +struct opus_context { + OpusEncoder *encoder_object; + OpusDecoder *decoder_object; + int frame_size; +}; + +static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) +{ + struct opus_context *context = NULL; + int encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); + int decoding = (flags & SWITCH_CODEC_FLAG_DECODE); + + if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) { + return SWITCH_STATUS_FALSE; + } + + context->frame_size = codec->implementation->samples_per_packet; + + if (encoding) { + /* come up with a way to specify these */ + int bitrate_bps = codec->implementation->bits_per_second; + int mode = MODE_HYBRID; + int use_vbr = 1; + int complexity = 10; + int use_inbandfec = 1; + int use_dtx = 1; + int bandwidth = BANDWIDTH_FULLBAND; + + context->encoder_object = opus_encoder_create(codec->implementation->actual_samples_per_second, codec->implementation->number_of_channels); + + opus_encoder_ctl(context->encoder_object, OPUS_SET_MODE(mode)); + opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(bitrate_bps)); + opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(bandwidth)); + opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR_FLAG(use_vbr)); + opus_encoder_ctl(context->encoder_object, OPUS_SET_COMPLEXITY(complexity)); + opus_encoder_ctl(context->encoder_object, OPUS_SET_INBAND_FEC_FLAG(use_inbandfec)); + opus_encoder_ctl(context->encoder_object, OPUS_SET_DTX_FLAG(use_dtx)); + + } + + if (decoding) { + context->decoder_object = opus_decoder_create(codec->implementation->actual_samples_per_second, codec->implementation->number_of_channels); + } + + codec->private_info = context; + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_opus_destroy(switch_codec_t *codec) +{ + codec->private_info = NULL; + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_opus_encode(switch_codec_t *codec, + switch_codec_t *other_codec, + void *decoded_data, + uint32_t decoded_data_len, + uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, + unsigned int *flag) +{ + struct opus_context *context = codec->private_info; + int bytes = 0; + int len = (int) *encoded_data_len; + + if (!context) { + return SWITCH_STATUS_FALSE; + } + + if (len > 1275) len = 1275; + + bytes = opus_encode(context->encoder_object, (void *) decoded_data, decoded_data_len / 2, (unsigned char *) encoded_data, len); + + if (bytes > 0) { + *encoded_data_len = (uint32_t) bytes; + return SWITCH_STATUS_SUCCESS; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder Error!\n"); + return SWITCH_STATUS_GENERR; +} + +static switch_status_t switch_opus_decode(switch_codec_t *codec, + switch_codec_t *other_codec, + void *encoded_data, + uint32_t encoded_data_len, + uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, + unsigned int *flag) +{ + struct opus_context *context = codec->private_info; + int samples = 0; + + if (!context) { + return SWITCH_STATUS_FALSE; + } + + samples = opus_decode(context->decoder_object, encoded_data, encoded_data_len, decoded_data, *decoded_data_len); + + if (samples < 0) { + return SWITCH_STATUS_GENERR; + } + + *decoded_data_len = samples * 2; + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) +{ + switch_codec_interface_t *codec_interface; + + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA)"); + + switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 115, /* the IANA code number */ + "OPUS", /* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + 48000, /* samples transferred per second */ + 48000, /* actual samples transferred per second */ + 32000, /* bits transferred per second */ + 10000, /* number of microseconds per frame */ + 80, /* number of samples per frame */ + 960, /* number of bytes per frame decompressed */ + 0, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_opus_init, /* function to initialize a codec handle using this implementation */ + switch_opus_encode, /* function to encode raw data into encoded data */ + switch_opus_decode, /* function to decode encoded data into raw data */ + switch_opus_destroy); /* deinitalize a codec handle using this implementation */ + + + switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 115, /* the IANA code number */ + "OPUS", /* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + 48000, /* samples transferred per second */ + 48000, /* actual samples transferred per second */ + 32000, /* bits transferred per second */ + 20000, /* number of microseconds per frame */ + 160, /* number of samples per frame */ + 1920, /* number of bytes per frame decompressed */ + 0, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_opus_init, /* function to initialize a codec handle using this implementation */ + switch_opus_encode, /* function to encode raw data into encoded data */ + switch_opus_decode, /* function to decode encoded data into raw data */ + switch_opus_destroy); /* deinitalize a codec handle using this implementation */ + + + + + /* indicate that the module should continue to be loaded */ + 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: + */ From e7d68a79dc7838d74e7b8985494dcde532910d32 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 16:02:31 -0600 Subject: [PATCH 68/86] change signalling name to avoid polluting the namespace before its ready --- src/mod/codecs/mod_opus/mod_opus.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index 341254fe0c..ddb5a7ac83 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -151,11 +151,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); - SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA)"); + SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA 0.9.0)"); switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ 115, /* the IANA code number */ - "OPUS", /* the IANA code name */ + "Opus-0.9.0",/* the IANA code name */ NULL, /* default fmtp to send (can be overridden by the init function) */ 48000, /* samples transferred per second */ 48000, /* actual samples transferred per second */ @@ -174,7 +174,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ 115, /* the IANA code number */ - "OPUS", /* the IANA code name */ + "Opus-0.9.0", /* the IANA code name */ NULL, /* default fmtp to send (can be overridden by the init function) */ 48000, /* samples transferred per second */ 48000, /* actual samples transferred per second */ From 998a04d2cfa361a4d600175809d5fef02374c720 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 16:25:00 -0600 Subject: [PATCH 69/86] add 10 20 and 40ms --- src/mod/codecs/mod_opus/mod_opus.c | 69 +++++++++++++----------------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index ddb5a7ac83..0234ed8541 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -147,52 +147,43 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) { switch_codec_interface_t *codec_interface; + int samples = 80; + int bytes = 960; + int mss = 10000; + int x = 0; + int rate = 48000; + int bits = 32000; /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA 0.9.0)"); - switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - 115, /* the IANA code number */ - "Opus-0.9.0",/* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function) */ - 48000, /* samples transferred per second */ - 48000, /* actual samples transferred per second */ - 32000, /* bits transferred per second */ - 10000, /* number of microseconds per frame */ - 80, /* number of samples per frame */ - 960, /* number of bytes per frame decompressed */ - 0, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - 1, /* number of frames per network packet */ - switch_opus_init, /* function to initialize a codec handle using this implementation */ - switch_opus_encode, /* function to encode raw data into encoded data */ - switch_opus_decode, /* function to decode encoded data into raw data */ - switch_opus_destroy); /* deinitalize a codec handle using this implementation */ - - - switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - 115, /* the IANA code number */ - "Opus-0.9.0", /* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function) */ - 48000, /* samples transferred per second */ - 48000, /* actual samples transferred per second */ - 32000, /* bits transferred per second */ - 20000, /* number of microseconds per frame */ - 160, /* number of samples per frame */ - 1920, /* number of bytes per frame decompressed */ - 0, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - 1, /* number of frames per network packet */ - switch_opus_init, /* function to initialize a codec handle using this implementation */ - switch_opus_encode, /* function to encode raw data into encoded data */ - switch_opus_decode, /* function to decode encoded data into raw data */ - switch_opus_destroy); /* deinitalize a codec handle using this implementation */ - - - + for (x = 0; x < 3; x++) { + switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 115, /* the IANA code number */ + "Opus-0.9.0",/* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + rate, /* samples transferred per second */ + rate, /* actual samples transferred per second */ + bits, /* bits transferred per second */ + mss, /* number of microseconds per frame */ + samples, /* number of samples per frame */ + bytes, /* number of bytes per frame decompressed */ + 0, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_opus_init, /* function to initialize a codec handle using this implementation */ + switch_opus_encode, /* function to encode raw data into encoded data */ + switch_opus_decode, /* function to decode encoded data into raw data */ + switch_opus_destroy); /* deinitalize a codec handle using this implementation */ + + bytes *= 2; + samples *= 2; + mss *= 2; + } + /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; } From 294436486302d0547b34ba26e5fa402c4ebaa58f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 16:53:38 -0600 Subject: [PATCH 70/86] nm 40 doesn't work yet --- src/mod/codecs/mod_opus/mod_opus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index 0234ed8541..b9a31208a4 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -159,7 +159,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA 0.9.0)"); - for (x = 0; x < 3; x++) { + for (x = 0; x < 2; x++) { switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ 115, /* the IANA code number */ "Opus-0.9.0",/* the IANA code name */ From beb829053945926447ba0f970faf1a3326d83981 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Fri, 4 Feb 2011 18:22:53 -0500 Subject: [PATCH 71/86] chlog: freetdm: isdn: fix for 4ESS call clearing procedures --- .../ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index 97984fbfab..5702b72fa2 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -801,12 +801,14 @@ static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdm sngisdn_snd_release(ftdmchan, 0); break; case FTDM_CHANNEL_STATE_PROCEED: - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) && - ((sngisdn_span_data_t*)(ftdmchan->span->signal_data))->switchtype == SNGISDN_SWITCH_5ESS) { + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { + if (((sngisdn_span_data_t*)(ftdmchan->span->signal_data))->switchtype == SNGISDN_SWITCH_4ESS || + ((sngisdn_span_data_t*)(ftdmchan->span->signal_data))->switchtype == SNGISDN_SWITCH_5ESS) { - /* When using 5ESS, if the user wants to clear an inbound call, the correct procedure is to send a PROGRESS with in-band info available, and play tones. Then send a DISCONNECT. If we reached this point, it means user did not try to play-tones, so send a RELEASE because remote side does not expect DISCONNECT in state 3 */ - sngisdn_snd_release(ftdmchan, 0); - break; + /* When using 5ESS, if the user wants to clear an inbound call, the correct procedure is to send a PROGRESS with in-band info available, and play tones. Then send a DISCONNECT. If we reached this point, it means user did not try to play-tones, so send a RELEASE because remote side does not expect DISCONNECT in state 3 */ + sngisdn_snd_release(ftdmchan, 0); + break; + } } /* fall-through */ default: From 0d5fcf65a0fef932f32874da6f4bdddb69279c53 Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Sun, 6 Feb 2011 01:28:09 -0500 Subject: [PATCH 72/86] xml_config: change min/max enforcements to >= instead of > --- src/switch_xml_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_xml_config.c b/src/switch_xml_config.c index b6b37bd7db..5ade057b37 100644 --- a/src/switch_xml_config.c +++ b/src/switch_xml_config.c @@ -177,7 +177,7 @@ SWITCH_DECLARE(switch_status_t) switch_xml_config_parse_event(switch_event_t *ev if (int_options) { /* Enforce validation options */ - if ((int_options->enforce_min && !(intval > int_options->min)) || (int_options->enforce_max && !(intval < int_options->max))) { + if ((int_options->enforce_min && !(intval >= int_options->min)) || (int_options->enforce_max && !(intval <= int_options->max))) { /* Validation failed, set default */ intval = (int) (intptr_t) item->defaultvalue; /* Then complain */ From 7386b9f8f55e6b2648bcfb3f9dafaf62dccd772e Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Sun, 6 Feb 2011 01:26:55 -0500 Subject: [PATCH 73/86] Add session.ringReady() to check for CF_RING_READY --- src/mod/languages/mod_spidermonkey/mod_spidermonkey.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c index 1d6ee8d679..a818c1dcd1 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c @@ -2126,6 +2126,15 @@ static JSBool session_media_ready(JSContext * cx, JSObject * obj, uintN argc, js } +static JSBool session_ring_ready(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval) +{ + struct js_session *jss = JS_GetPrivate(cx, obj); + + *rval = BOOLEAN_TO_JSVAL((jss && jss->session && switch_channel_test_flag(switch_core_session_get_channel(jss->session), CF_RING_READY)) ? JS_TRUE : JS_FALSE); + + return JS_TRUE; +} + static JSBool session_answered(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval) { struct js_session *jss = JS_GetPrivate(cx, obj); @@ -2673,6 +2682,7 @@ static JSFunctionSpec session_methods[] = { {"ready", session_ready, 0}, {"answered", session_answered, 0}, {"mediaReady", session_media_ready, 0}, + {"ringReady", session_ring_ready, 0}, {"waitForAnswer", session_wait_for_answer, 0}, {"waitForMedia", session_wait_for_media, 0}, {"getEvent", session_get_event, 0}, From 2b4f163826132cf55698008a22c065374320796a Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Sun, 6 Feb 2011 01:40:13 -0500 Subject: [PATCH 74/86] Add libjpeg-dev to apt prereqs --- support-d/prereq.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-d/prereq.sh b/support-d/prereq.sh index 4e214cff89..8bc454ded4 100755 --- a/support-d/prereq.sh +++ b/support-d/prereq.sh @@ -2,7 +2,7 @@ UNAME=`uname` NEEDED_PACKAGES_YUM='automake autoconf libtool screen gdb gcc-c++ compat-gcc-32 compat-gcc-32-c++ subversion ncurses-devel unixODBC-devel make wget' -NEEDED_PACAKGES_APT='automake autoconf libtool screen gdb libncurses5-dev unixodbc-dev subversion emacs22-nox gcc g++ make' +NEEDED_PACAKGES_APT='automake autoconf libtool screen gdb libncurses5-dev unixodbc-dev subversion emacs22-nox gcc g++ make libjpeg-dev' NEEDED_PACKAGES_PKG_ADD='' From d4b5b07b2a76404ed8bf5adf8bc2bc9c0cbd9f04 Mon Sep 17 00:00:00 2001 From: Leon de Rooij Date: Mon, 7 Feb 2011 10:36:04 +0100 Subject: [PATCH 75/86] reswig mod_lua for freeswitch.email --- src/mod/languages/mod_lua/mod_lua_wrap.cpp | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/mod/languages/mod_lua/mod_lua_wrap.cpp b/src/mod/languages/mod_lua/mod_lua_wrap.cpp index 1d84a39fd5..559d4032c0 100644 --- a/src/mod/languages/mod_lua/mod_lua_wrap.cpp +++ b/src/mod/languages/mod_lua/mod_lua_wrap.cpp @@ -1582,6 +1582,55 @@ fail: } +static int _wrap_email(lua_State* L) { + int SWIG_arg = -1; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) NULL ; + char *arg4 = (char *) NULL ; + char *arg5 = (char *) NULL ; + char *arg6 = (char *) NULL ; + char *arg7 = (char *) NULL ; + bool result; + + SWIG_check_num_args("email",2,7) + if(!lua_isstring(L,1)) SWIG_fail_arg("email",1,"char *"); + if(!lua_isstring(L,2)) SWIG_fail_arg("email",2,"char *"); + if(lua_gettop(L)>=3 && !lua_isstring(L,3)) SWIG_fail_arg("email",3,"char *"); + if(lua_gettop(L)>=4 && !lua_isstring(L,4)) SWIG_fail_arg("email",4,"char *"); + if(lua_gettop(L)>=5 && !lua_isstring(L,5)) SWIG_fail_arg("email",5,"char *"); + if(lua_gettop(L)>=6 && !lua_isstring(L,6)) SWIG_fail_arg("email",6,"char *"); + if(lua_gettop(L)>=7 && !lua_isstring(L,7)) SWIG_fail_arg("email",7,"char *"); + arg1 = (char *)lua_tostring(L, 1); + arg2 = (char *)lua_tostring(L, 2); + if(lua_gettop(L)>=3){ + arg3 = (char *)lua_tostring(L, 3); + } + if(lua_gettop(L)>=4){ + arg4 = (char *)lua_tostring(L, 4); + } + if(lua_gettop(L)>=5){ + arg5 = (char *)lua_tostring(L, 5); + } + if(lua_gettop(L)>=6){ + arg6 = (char *)lua_tostring(L, 6); + } + if(lua_gettop(L)>=7){ + arg7 = (char *)lua_tostring(L, 7); + } + result = (bool)email(arg1,arg2,arg3,arg4,arg5,arg6,arg7); + SWIG_arg=0; + lua_pushboolean(L,(int)(result==true)); SWIG_arg++; + return SWIG_arg; + + if(0) SWIG_fail; + +fail: + lua_error(L); + return SWIG_arg; +} + + static int _wrap_new_IVRMenu(lua_State* L) { int SWIG_arg = -1; IVRMenu *arg1 = (IVRMenu *) 0 ; @@ -7525,6 +7574,7 @@ static swig_lua_class _wrap_class_LUA_Dbh = { "Dbh", &SWIGTYPE_p_LUA__Dbh,_wrap_ static const struct luaL_reg swig_commands[] = { { "consoleLog", _wrap_consoleLog}, { "consoleCleanLog", _wrap_consoleCleanLog}, + { "email", _wrap_email}, { "console_log", _wrap_console_log}, { "console_clean_log", _wrap_console_clean_log}, { "msleep", _wrap_msleep}, From 080c5ae98167e590bebf698439c550bdb656925e Mon Sep 17 00:00:00 2001 From: cypromis Date: Mon, 7 Feb 2011 14:04:44 +0100 Subject: [PATCH 76/86] FS-1742 - Make Voicemail use 1 SQL query instead of 4 to get the message count use in MWI - Now also working on your more favourite and less favourite databases --- src/mod/applications/mod_voicemail/mod_voicemail.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 80b011e189..f868c3a284 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1278,7 +1278,9 @@ static void message_count(vm_profile_t *profile, const char *id_in, const char * myid = resolve_id(id_in, domain_name, "message-count"); switch_snprintf(sql, sizeof(sql), - "select read_epoch=0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' group by read_epoch=0,read_flags;", + "select 1, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch=0 group by read_flags + union + select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;", myid, domain_name, myfolder); vm_execute_sql_callback(profile, profile->mutex, sql, message_count_callback, &cbt); From cf83f9c381a6abb988efc41b8711271b4665b79e Mon Sep 17 00:00:00 2001 From: cypromis Date: Mon, 7 Feb 2011 15:32:26 +0100 Subject: [PATCH 77/86] seems whitespaces are unpopular on some linux/gcc combinations --- src/mod/applications/mod_voicemail/mod_voicemail.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index f868c3a284..16841277d6 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1277,11 +1277,8 @@ static void message_count(vm_profile_t *profile, const char *id_in, const char * myid = resolve_id(id_in, domain_name, "message-count"); - switch_snprintf(sql, sizeof(sql), - "select 1, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch=0 group by read_flags - union - select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;", - myid, domain_name, myfolder); + switch_snprintf(sql, sizeof(sql), "select 1, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch=0 group by read_flags union + select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;", myid, domain_name, myfolder); vm_execute_sql_callback(profile, profile->mutex, sql, message_count_callback, &cbt); From 12c13e115b96e9e036bd65655c1f12a72a83510e Mon Sep 17 00:00:00 2001 From: cypromis Date: Mon, 7 Feb 2011 16:01:20 +0100 Subject: [PATCH 78/86] more formatting mistakes *sigh* --- src/mod/applications/mod_voicemail/mod_voicemail.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 16841277d6..f829e574d2 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1277,9 +1277,9 @@ static void message_count(vm_profile_t *profile, const char *id_in, const char * myid = resolve_id(id_in, domain_name, "message-count"); - switch_snprintf(sql, sizeof(sql), "select 1, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch=0 group by read_flags union - select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;", myid, domain_name, myfolder); - + switch_snprintf(sql, sizeof(sql), "select 1, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' " + "and read_epoch=0 group by read_flags union select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' " + "and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;", myid, domain_name, myfolder); vm_execute_sql_callback(profile, profile->mutex, sql, message_count_callback, &cbt); *total_new_messages = cbt.total_new_messages + cbt.total_new_urgent_messages; From 1cc51046c5b5b61e86394b97996a2d7833244f90 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Thu, 3 Feb 2011 14:12:32 -0500 Subject: [PATCH 79/86] freetdm: ss7 - only unload layers when they are loaded freetdm: ss7 - configuration updated to allow a route to use multiple linksets...new configuration file --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c | 13 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 85 ++++++------ .../ftmod_sangoma_ss7_main.c | 11 +- .../ftmod_sangoma_ss7_main.h | 7 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 122 ++++++++++++------ 5 files changed, 157 insertions(+), 81 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c index 15fc1ef5db..01d101300e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c @@ -74,6 +74,7 @@ int ftmod_ss7_relay_chan_config(int id); int ft_to_sngss7_cfg_all(void) { int x = 0; + int ret = 0; /* check if we have done gen_config already */ if (!(g_ftdm_sngss7_data.gen_config)) { @@ -289,15 +290,17 @@ int ft_to_sngss7_cfg_all(void) /* check if this link has been configured already */ if (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_CONFIGURED)) { - if (ftmod_ss7_mtp3_nsap_config(x)) { - SS7_CRITICAL("MTP3 NSAP %d configuration FAILED!\n", x); + ret = ftmod_ss7_mtp3_nsap_config(x); + if (ret) { + SS7_CRITICAL("MTP3 NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret)); return 1; } else { SS7_INFO("MTP3 NSAP %d configuration DONE!\n", x); } - if (ftmod_ss7_isup_nsap_config(x)) { - SS7_CRITICAL("ISUP NSAP %d configuration FAILED!\n", x); + ret = ftmod_ss7_isup_nsap_config(x); + if (ret) { + SS7_CRITICAL("ISUP NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret)); return 1; } else { SS7_INFO("ISUP NSAP %d configuration DONE!\n", x); @@ -580,7 +583,7 @@ int ftmod_ss7_mtp3_gen_config(void) cfg.t.cfg.s.snGen.ssfValid = TRUE; /* ssf validation required */ cfg.t.cfg.s.snGen.nmbDLSap = MAX_SN_LINKS; /* number of MTP Data Link SAPs */ - cfg.t.cfg.s.snGen.nmbNSap = MAX_SN_VARIANTS; /* number of Upper Layer Saps */ + cfg.t.cfg.s.snGen.nmbNSap = MAX_SN_ROUTES; /* number of Upper Layer Saps */ cfg.t.cfg.s.snGen.nmbRouts = MAX_SN_ROUTES; /* maximum number of routing entries */ cfg.t.cfg.s.snGen.nmbLnkSets = MAX_SN_LINKSETS; /* number of link sets */ cfg.t.cfg.s.snGen.nmbRteInst = MAX_SN_ROUTES*16; /* number of simultaneous Rte instances */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c index 4ab4359c93..0298429109 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c @@ -1131,46 +1131,57 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; ftdmchan = ss7_info->ftdmchan; - /* grab the signaling_status */ - ftdm_channel_get_sig_status(ftdmchan, &sigstatus); + if (ftdmchan == NULL) { + /* this should never happen!!! */ + stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|FTDMCHAN DOES NOT EXISTS", + ckt->span, + ckt->chan, + ckt->cic); + + } else { + /* grab the signaling_status */ + ftdm_channel_get_sig_status(ftdmchan, &sigstatus); + + stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|sig_status=%4s|state=%s|", + ckt->span, + ckt->chan, + ckt->cic, + ftdm_signaling_status2str(sigstatus), + ftdm_channel_state2str(ftdmchan->state)); + + if ((sngss7_test_ckt_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || + (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) { + stream->write_function(stream, "l_mn=Y|"); + }else { + stream->write_function(stream, "l_mn=N|"); + } + + if ((sngss7_test_ckt_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || + (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) { + stream->write_function(stream, "r_mn=Y|"); + }else { + stream->write_function(stream, "r_mn=N|"); + } + + if (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) { + stream->write_function(stream, "l_hw=Y|"); + }else { + stream->write_function(stream, "l_hw=N|"); + } + + if (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) { + stream->write_function(stream, "r_hw=Y|"); + }else { + stream->write_function(stream, "r_hw=N|"); + } - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|sig_status=%4s|state=%s|", - ckt->span, - ckt->chan, - ckt->cic, - ftdm_signaling_status2str(sigstatus), - ftdm_channel_state2str(ftdmchan->state)); - - if((sngss7_test_ckt_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) { - stream->write_function(stream, "l_mn=Y|"); - }else { - stream->write_function(stream, "l_mn=N|"); + if (sngss7_test_ckt_flag(ss7_info, FLAG_RELAY_DOWN)) { + stream->write_function(stream, "relay=Y|"); + }else { + stream->write_function(stream, "relay=N|"); + } } - if((sngss7_test_ckt_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) { - stream->write_function(stream, "r_mn=Y|"); - }else { - stream->write_function(stream, "r_mn=N|"); - } - - if(sngss7_test_ckt_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) { - stream->write_function(stream, "l_hw=Y|"); - }else { - stream->write_function(stream, "l_hw=N|"); - } - - if(sngss7_test_ckt_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) { - stream->write_function(stream, "r_hw=Y|"); - }else { - stream->write_function(stream, "r_hw=N|"); - } - - if(sngss7_test_ckt_flag(ss7_info, FLAG_RELAY_DOWN)) { - stream->write_function(stream, "relay=Y|"); - }else { - stream->write_function(stream, "relay=N|"); - } - stream->write_function(stream, "flags=0x%X",ss7_info->ckt_flags); stream->write_function(stream, "\n"); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index adee000abb..ad528272c4 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -1570,26 +1570,33 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_ss7_unload) if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC)) { sng_isup_free_cc(); + sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC); } if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) { ftmod_ss7_shutdown_isup(); sng_isup_free_isup(); + sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP); } if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3)) { ftmod_ss7_shutdown_mtp3(); sng_isup_free_mtp3(); + sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3); } if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) { ftmod_ss7_shutdown_mtp2(); sng_isup_free_mtp2(); sng_isup_free_mtp1(); + sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2); } - ftmod_ss7_shutdown_relay(); - sng_isup_free_relay(); + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY)) { + ftmod_ss7_shutdown_relay(); + sng_isup_free_relay(); + sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY); + } sng_isup_free_sm(); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index 5272aa8bac..fe291fb305 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -219,13 +219,18 @@ typedef struct sng_link_set { uint32_t links[16]; } sng_link_set_t; +typedef struct sng_link_set_list { + uint32_t lsId; + struct sng_link_set_list *next; +} sng_link_set_list_t; + typedef struct sng_route { char name[MAX_NAME_LEN]; uint32_t flags; uint32_t id; uint32_t dpc; uint32_t cmbLinkSetId; - uint32_t linkSetId; + struct sng_link_set_list lnkSets; uint32_t linkType; uint32_t switchType; uint32_t ssf; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c index d2fa973393..dc6428d0bb 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c @@ -1268,9 +1268,9 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) ftdm_conf_parameter_t *parm = mtp_route->parameters; int num_parms = mtp_route->n_parameters; int i; + sng_link_set_list_t *lnkSet; ftdm_conf_node_t *linkset; - int ls_id; int numLinks; /* initalize the mtpRoute structure */ @@ -1383,42 +1383,50 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) } /* fill in the rest of the values in the mtpRoute struct */ - mtpRoute.nwId = mtpRoute.id; + mtpRoute.nwId = 0; mtpRoute.cmbLinkSetId = mtpRoute.id; /* parse in the list of linksets this route is reachable by */ linkset = mtp_route->child->child; + /* initalize the link-list of linkSet Ids */ + lnkSet = &mtpRoute.lnkSets; + while (linkset != NULL) { /**************************************************************************/ /* extract the linkset Id */ - ls_id = atoi(linkset->parameters->val); + lnkSet->lsId = atoi(linkset->parameters->val); - if (g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].id != 0) { - SS7_DEBUG("Found mtpRoute linkset id = %d that is valid\n",ls_id); + if (g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].id != 0) { + SS7_DEBUG("Found mtpRoute linkset id = %d that is valid\n",lnkSet->lsId); } else { - SS7_ERROR("Found mtpRoute linkset id = %d that is invalid\n",ls_id); + SS7_ERROR("Found mtpRoute linkset id = %d that is invalid\n",lnkSet->lsId); goto move_along; } /* pull up the linktype, switchtype, and SSF from the linkset */ - mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].linkType; - mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].switchType; - mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].ssf; + mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].linkType; + mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].switchType; + mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].ssf; /* extract the number of cmbLinkSetId aleady on this linkset */ - numLinks = g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].numLinks; + numLinks = g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].numLinks; /* add this routes cmbLinkSetId to the list */ - g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].links[numLinks] = mtpRoute.cmbLinkSetId; + g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].links[numLinks] = mtpRoute.cmbLinkSetId; /* increment the number of cmbLinkSets on this linkset */ - g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].numLinks++; + g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].numLinks++; + + /* update the linked list */ + lnkSet->next = ftdm_malloc(sizeof(sng_link_set_list_t)); + lnkSet = lnkSet->next; + lnkSet->lsId = 0; + lnkSet->next = NULL; move_along: /* move to the next linkset element */ linkset = linkset->next; - /**************************************************************************/ } /* while (linkset != null) */ @@ -1465,6 +1473,7 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) { sng_isup_inf_t sng_isup; sng_isap_t sng_isap; + sng_link_set_list_t *lnkSet; ftdm_conf_parameter_t *parm = isup_interface->parameters; int num_parms = isup_interface->n_parameters; int i; @@ -1500,7 +1509,6 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) } else if (!strcasecmp(parm->var, "spc")) { /**********************************************************************/ sng_isup.spc = atoi(parm->val); - g_ftdm_sngss7_data.cfg.spc = sng_isup.spc; SS7_DEBUG("Found an isup SPC = %d\n", sng_isup.spc); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtprouteId")) { @@ -1747,17 +1755,14 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) sngss7_set_flag(&sng_isup, SNGSS7_PAUSED); /* trickle down the SPC to all sub entities */ - int linkSetId; + lnkSet = &g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].lnkSets; - linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].linkSetId; + g_ftdm_sngss7_data.cfg.mtp3Link[lnkSet->lsId].spc = sng_isup.spc; + lnkSet = lnkSet->next; - i = 1; - while (g_ftdm_sngss7_data.cfg.mtp3Link[i].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtp3Link[i].linkSetId == linkSetId) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].spc = g_ftdm_sngss7_data.cfg.spc; - } - - i++; + while (lnkSet->next != NULL) { + g_ftdm_sngss7_data.cfg.mtp3Link[lnkSet->lsId].spc = sng_isup.spc; + lnkSet = lnkSet->next; } /* pull values from the lower levels */ @@ -2342,7 +2347,10 @@ static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet) /******************************************************************************/ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route) { - int i = mtp3_route->id; + sng_link_set_list_t *lnkSet = NULL; + int i = mtp3_route->id; + int tmp = 0; + /* check if this id value has been used already */ if (g_ftdm_sngss7_data.cfg.mtpRoute[i].id == 0) { @@ -2355,10 +2363,19 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route) } /* fill in the cmbLinkSet in the linkset structure */ - int tmp = g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3_route->linkSetId].numLinks; + lnkSet = &mtp3_route->lnkSets; - g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3_route->linkSetId].links[tmp] = mtp3_route->cmbLinkSetId; - g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3_route->linkSetId].numLinks++; + tmp = g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].numLinks; + g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].links[tmp] = mtp3_route->cmbLinkSetId; + g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].numLinks++; + + while (lnkSet->next != NULL) { + tmp = g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].numLinks; + g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].links[tmp] = mtp3_route->cmbLinkSetId; + g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].numLinks++; + + lnkSet = lnkSet->next; + } strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, (char *)mtp3_route->name); @@ -2369,7 +2386,7 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route) g_ftdm_sngss7_data.cfg.mtpRoute[i].cmbLinkSetId = mtp3_route->cmbLinkSetId; g_ftdm_sngss7_data.cfg.mtpRoute[i].isSTP = mtp3_route->isSTP; g_ftdm_sngss7_data.cfg.mtpRoute[i].nwId = mtp3_route->nwId; - g_ftdm_sngss7_data.cfg.mtpRoute[i].linkSetId = mtp3_route->linkSetId; + g_ftdm_sngss7_data.cfg.mtpRoute[i].lnkSets = mtp3_route->lnkSets; g_ftdm_sngss7_data.cfg.mtpRoute[i].ssf = mtp3_route->ssf; if (mtp3_route->t6 != 0) { g_ftdm_sngss7_data.cfg.mtpRoute[i].t6 = mtp3_route->t6; @@ -2439,8 +2456,7 @@ static int ftmod_ss7_fill_in_nsap(sng_route_t *mtp3_route) i = 1; while (g_ftdm_sngss7_data.cfg.nsap[i].id != 0) { if ((g_ftdm_sngss7_data.cfg.nsap[i].linkType == mtp3_route->linkType) && - (g_ftdm_sngss7_data.cfg.nsap[i].switchType == mtp3_route->switchType) && - (g_ftdm_sngss7_data.cfg.nsap[i].ssf == mtp3_route->ssf)) { + (g_ftdm_sngss7_data.cfg.nsap[i].switchType == mtp3_route->switchType)) { /* we have a match so break out of this loop */ break; @@ -2789,6 +2805,7 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan) sngss7_chan_data_t *ss7_info = NULL; int x; int count = 1; + int flag; while (ccSpan->ch_map[0] != '\0') { /**************************************************************************/ @@ -2799,13 +2816,45 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan) return FTDM_FAIL; } - /* find the spot in master array for this circuit */ - x = (ccSpan->procId * 1000) + count; + /* find a spot for this circuit in the global structure */ + x = (ccSpan->procId * 1000); + flag = 0; + while (flag == 0) { + /**********************************************************************/ + /* check the id value ( 0 = new, 0 > circuit can be existing) */ + if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) { + /* we're at the end of the list of circuitsl aka this is new */ + SS7_DEBUG("Found a new circuit %d, ccSpanId=%d, chan=%d\n", + x, + ccSpan->id, + count); - /* check if this circuit has already been filled in */ - if (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - SS7_DEVEL_DEBUG("Filling in circuit that already exists...%d\n", x); - } + /* throw the flag to end the loop */ + flag = 1; + } else { + /* check the ccspan.id and chan to see if the circuit already exists */ + if ((g_ftdm_sngss7_data.cfg.isupCkt[x].ccSpanId == ccSpan->id) && + (g_ftdm_sngss7_data.cfg.isupCkt[x].chan == count)) { + + /* we are processing a circuit that already exists */ + SS7_DEBUG("Found an existing circuit %d, ccSpanId=%d, chan%d\n", + x, + ccSpan->id, + count); + + /* throw the flag to end the loop */ + flag = 1; + + /* not supporting reconfig at this time */ + SS7_DEBUG("Not supporting ckt reconfig at this time!\n"); + goto move_along; + } else { + /* this is not the droid you are looking for */ + x++; + } + } + /**********************************************************************/ + } /* while (flag == 0) */ /* prepare the global info sturcture */ ss7_info = ftdm_calloc(1, sizeof(sngss7_chan_data_t)); @@ -2901,6 +2950,7 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan) g_ftdm_sngss7_data.cfg.isupCkt[x].cic, g_ftdm_sngss7_data.cfg.isupCkt[x].id); +move_along: /* increment the span channel count */ count++; From 946ec62893014a5796d0d90b1fc62797d4102164 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Mon, 7 Feb 2011 10:49:26 -0500 Subject: [PATCH 80/86] freemtdm: ss7 - SPC no long in sng_gen...new configuration file --- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c | 7 +++---- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c | 4 +++- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 5 ----- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c index 01d101300e..20bcc3a043 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c @@ -99,6 +99,7 @@ int ft_to_sngss7_cfg_all(void) return 1; } else { SS7_INFO("Started Stack Manager!\n"); + sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_SM); } /* check if the configuration had a Relay Channel */ @@ -575,12 +576,10 @@ int ftmod_ss7_mtp3_gen_config(void) cfg.t.cfg.s.snGen.typeSP = LSN_TYPE_SP; /* type of signalling postatic int */ - cfg.t.cfg.s.snGen.spCode1 = g_ftdm_sngss7_data.cfg.spc; /* our DPC for CCITT version */ - + cfg.t.cfg.s.snGen.spCode1 = 0; /* our DPC for CCITT version */ #if (SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || SS7_CHINA || defined(TDS_ROLL_UPGRADE_SUPPORT)) - cfg.t.cfg.s.snGen.spCode2 = g_ftdm_sngss7_data.cfg.spc; /* our DPC for ANSI or CHINA version */ + cfg.t.cfg.s.snGen.spCode2 = 0; /* our DPC for ANSI or CHINA version */ #endif - cfg.t.cfg.s.snGen.ssfValid = TRUE; /* ssf validation required */ cfg.t.cfg.s.snGen.nmbDLSap = MAX_SN_LINKS; /* number of MTP Data Link SAPs */ cfg.t.cfg.s.snGen.nmbNSap = MAX_SN_ROUTES; /* number of Upper Layer Saps */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index ad528272c4..2f2e502314 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -1598,7 +1598,9 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_ss7_unload) sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY); } - sng_isup_free_sm(); + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_SM)) { + sng_isup_free_sm(); + } sng_isup_free_gen(); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c index dc6428d0bb..46df9908e9 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c @@ -464,11 +464,6 @@ static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen) SS7_DEBUG("Found license file = %s\n", g_ftdm_sngss7_data.cfg.license); SS7_DEBUG("Found signature file = %s\n", g_ftdm_sngss7_data.cfg.signature); /**********************************************************************/ - } else if (!strcasecmp(parm->var, "spc")) { - /**********************************************************************/ - g_ftdm_sngss7_data.cfg.spc = atoi(parm->val); - SS7_DEBUG("Found SPC = %d\n", g_ftdm_sngss7_data.cfg.spc); - /**********************************************************************/ } else { /**********************************************************************/ SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); From bab7a2392f955facbb91d0f30512682e2b38773e Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Mon, 7 Feb 2011 17:09:14 +0100 Subject: [PATCH 81/86] refactor config parsing --- conf/autoload_configs/cdr_pg_csv.conf.xml | 14 +- .../mod_cdr_pg_csv/mod_cdr_pg_csv.c | 141 +++++++++--------- 2 files changed, 77 insertions(+), 78 deletions(-) diff --git a/conf/autoload_configs/cdr_pg_csv.conf.xml b/conf/autoload_configs/cdr_pg_csv.conf.xml index 2f2efa9b26..427bf2d058 100644 --- a/conf/autoload_configs/cdr_pg_csv.conf.xml +++ b/conf/autoload_configs/cdr_pg_csv.conf.xml @@ -1,19 +1,23 @@ - - - - - + + + + + + + + + diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c index 5227161f23..1ec56bdd64 100644 --- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c +++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c @@ -37,18 +37,27 @@ #include #include +SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_pg_csv_load); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_cdr_pg_csv_shutdown); +SWITCH_MODULE_DEFINITION(mod_cdr_pg_csv, mod_cdr_pg_csv_load, mod_cdr_pg_csv_shutdown, NULL); + + typedef enum { CDR_LEG_A = (1 << 0), CDR_LEG_B = (1 << 1) } cdr_leg_t; -struct cdr_fd { +typedef enum { + SPOOL_FORMAT_CSV, + SPOOL_FORMAT_SQL +} spool_format_t; + +typedef struct { int fd; char *path; int64_t bytes; switch_mutex_t *mutex; -}; -typedef struct cdr_fd cdr_fd_t; +} cdr_fd_t; const char *default_template = "\"${local_ip_v4}\",\"${caller_id_name}\",\"${caller_id_number}\",\"${destination_number}\",\"${context}\",\"${start_stamp}\"," @@ -59,23 +68,59 @@ static struct { switch_memory_pool_t *pool; switch_hash_t *fd_hash; switch_hash_t *template_hash; - char *log_dir; - char *default_template; int shutdown; - int rotate; - int debug; - cdr_leg_t legs; char *db_info; char *db_table; - char *spool_format; PGconn *db_connection; int db_online; + cdr_leg_t legs; + char *spool_dir; + spool_format_t spool_format; + int rotate; + int debug; + char *default_template; switch_mutex_t *db_mutex; } globals = { 0 }; -SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_pg_csv_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_cdr_pg_csv_shutdown); -SWITCH_MODULE_DEFINITION(mod_cdr_pg_csv, mod_cdr_pg_csv_load, mod_cdr_pg_csv_shutdown, NULL); +static switch_xml_config_enum_item_t config_opt_cdr_leg_enum[] = { + {"a", CDR_LEG_A}, + {"b", CDR_LEG_B}, + {"ab", CDR_LEG_A | CDR_LEG_B}, + {NULL, 0} +}; + +static switch_xml_config_enum_item_t config_opt_spool_format_enum[] = { + {"csv", SPOOL_FORMAT_CSV}, + {"sql", SPOOL_FORMAT_SQL}, + {NULL, 0} +}; + +static switch_status_t config_validate_spool_dir(switch_xml_config_item_t *item, const char *newvalue, switch_config_callback_type_t callback_type, switch_bool_t changed) +{ + if ((callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD)) { + if (zstr(newvalue)) { + globals.spool_dir = switch_core_sprintf(globals.pool, "%s%scdr-pg-csv", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR); + } + } + + return SWITCH_STATUS_SUCCESS; +} + +static switch_xml_config_item_t config_settings[] = { + /* key, type, flags, ptr, default_value, data, syntax, helptext */ + SWITCH_CONFIG_ITEM_STRING_STRDUP("db-info", CONFIG_RELOADABLE, &globals.db_info, "dbname=cdr", NULL, NULL), + SWITCH_CONFIG_ITEM_STRING_STRDUP("db-table", CONFIG_RELOADABLE, &globals.db_table, "cdr", NULL, NULL), + SWITCH_CONFIG_ITEM_STRING_STRDUP("default-template", CONFIG_RELOADABLE, &globals.default_template, "default", NULL, NULL), + SWITCH_CONFIG_ITEM("legs", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.legs, (void *) CDR_LEG_A, &config_opt_cdr_leg_enum, "a|b|ab", NULL), + SWITCH_CONFIG_ITEM("spool-format", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.spool_format, (void *) SPOOL_FORMAT_CSV, &config_opt_spool_format_enum, "csv|sql", "Disk spool format to use if SQL insert fails."), + SWITCH_CONFIG_ITEM("rotate-on-hup", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.rotate, SWITCH_FALSE, NULL, NULL, NULL), + SWITCH_CONFIG_ITEM("debug", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.debug, SWITCH_FALSE, NULL, NULL, NULL), + + /* key, type, flags, ptr, defaultvalue, function, functiondata, syntax, helptext */ + SWITCH_CONFIG_ITEM_CALLBACK("spool-dir", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &globals.spool_dir, NULL, config_validate_spool_dir, NULL, NULL, NULL), + SWITCH_CONFIG_ITEM_END() +}; + static off_t fd_size(int fd) { @@ -363,12 +408,12 @@ static switch_status_t insert_cdr(const char * const template, const char * cons switch_mutex_unlock(globals.db_mutex); /* SQL INSERT failed for whatever reason. Spool the attempted query to disk */ - if (!strcasecmp(globals.spool_format, "sql")) { - path = switch_mprintf("%s%scdr-spool.sql", globals.log_dir, SWITCH_PATH_SEPARATOR); + if (globals.spool_format == SPOOL_FORMAT_SQL) { + path = switch_mprintf("%s%scdr-spool.sql", globals.spool_dir, SWITCH_PATH_SEPARATOR); assert(path); spool_cdr(path, sql); } else { - path = switch_mprintf("%s%scdr-spool.csv", globals.log_dir, SWITCH_PATH_SEPARATOR); + path = switch_mprintf("%s%scdr-spool.csv", globals.spool_dir, SWITCH_PATH_SEPARATOR); assert(path); spool_cdr(path, cdr); } @@ -402,8 +447,8 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) } } - if (switch_dir_make_recursive(globals.log_dir, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", globals.log_dir); + if (switch_dir_make_recursive(globals.spool_dir, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", globals.spool_dir); return SWITCH_STATUS_FALSE; } @@ -485,7 +530,6 @@ static switch_state_handler_table_t state_handlers = { }; - static switch_status_t load_config(switch_memory_pool_t *pool) { char *cf = "cdr_pg_csv.conf"; @@ -509,40 +553,11 @@ static switch_status_t load_config(switch_memory_pool_t *pool) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding default template.\n"); globals.legs = CDR_LEG_A; + if (switch_xml_config_parse_module_settings("cdr_pg_csv.conf", SWITCH_FALSE, config_settings) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_FALSE; + } + if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) { - - if ((settings = switch_xml_child(cfg, "settings"))) { - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - if (!strcasecmp(var, "debug")) { - globals.debug = switch_true(val); - } else if (!strcasecmp(var, "legs")) { - globals.legs = 0; - - if (strchr(val, 'a')) { - globals.legs |= CDR_LEG_A; - } - - if (strchr(val, 'b')) { - globals.legs |= CDR_LEG_B; - } - } else if (!strcasecmp(var, "log-base")) { - globals.log_dir = switch_core_sprintf(pool, "%s%scdr-pg-csv", val, SWITCH_PATH_SEPARATOR); - } else if (!strcasecmp(var, "rotate-on-hup")) { - globals.rotate = switch_true(val); - } else if (!strcasecmp(var, "db-info")) { - globals.db_info = switch_core_strdup(pool, val); - } else if (!strcasecmp(var, "db-table") || !strcasecmp(var, "g-table")) { - globals.db_table = switch_core_strdup(pool, val); - } else if (!strcasecmp(var, "default-template")) { - globals.default_template = switch_core_strdup(pool, val); - } else if (!strcasecmp(var, "spool-format")) { - globals.spool_format = switch_core_strdup(pool, val); - } - } - } - if ((settings = switch_xml_child(cfg, "templates"))) { for (param = switch_xml_child(settings, "template"); param; param = param->next) { char *var = (char *) switch_xml_attr(param, "name"); @@ -558,26 +573,6 @@ static switch_status_t load_config(switch_memory_pool_t *pool) switch_xml_free(xml); } - if (!globals.log_dir) { - globals.log_dir = switch_core_sprintf(pool, "%s%scdr-pg-csv", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR); - } - - if (zstr(globals.db_info)) { - globals.db_info = switch_core_strdup(pool, "dbname=cdr"); - } - - if (zstr(globals.db_table)) { - globals.db_table = switch_core_strdup(pool, "cdr"); - } - - if (zstr(globals.default_template)) { - globals.default_template = switch_core_strdup(pool, "default"); - } - - if (zstr(globals.spool_format)) { - globals.spool_format = switch_core_strdup(pool, "csv"); - } - return status; } @@ -588,8 +583,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_pg_csv_load) load_config(pool); - if ((status = switch_dir_make_recursive(globals.log_dir, SWITCH_DEFAULT_DIR_PERMS, pool)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", globals.log_dir); + if ((status = switch_dir_make_recursive(globals.spool_dir, SWITCH_DEFAULT_DIR_PERMS, pool)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", globals.spool_dir); return status; } From 8c12162a9d92ceac55c6305f2336efcf7157b923 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 7 Feb 2011 12:53:31 -0600 Subject: [PATCH 82/86] FS-3040 --- src/mod/applications/mod_voicemail/mod_voicemail.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index f829e574d2..bea82142b6 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1277,9 +1277,14 @@ static void message_count(vm_profile_t *profile, const char *id_in, const char * myid = resolve_id(id_in, domain_name, "message-count"); - switch_snprintf(sql, sizeof(sql), "select 1, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' " - "and read_epoch=0 group by read_flags union select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' " - "and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;", myid, domain_name, myfolder); + switch_snprintf(sql, sizeof(sql), "select 1, read_flags, count(read_epoch) from voicemail_msgs where " + "username='%s' and domain='%s' and in_folder='%s' " + "and read_epoch=0 group by read_flags union select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' " + "and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;", + myid, domain_name, myfolder, myid, domain_name, myfolder); + + + vm_execute_sql_callback(profile, profile->mutex, sql, message_count_callback, &cbt); *total_new_messages = cbt.total_new_messages + cbt.total_new_urgent_messages; From 526e6fe48cadc9418d64f2b639bad68d8883dcdd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 7 Feb 2011 13:14:20 -0600 Subject: [PATCH 83/86] FS-3038 --- .../applications/mod_commands/mod_commands.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 807770ac15..f34042a54f 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -4439,19 +4439,23 @@ SWITCH_STANDARD_API(strftime_tz_api_function) if ((format = strchr(mycmd, ' '))) { *format++ = '\0'; - } - if ((p = strchr(format, '|'))) { - *p++ = '\0'; - when = atol(format); - format = p; + if (format && (p = strchr(format, '|'))) { + *p++ = '\0'; + when = atol(format); + format = p; + } } } - if (switch_strftime_tz(tz_name, format, date, sizeof(date), when * 1000000) == SWITCH_STATUS_SUCCESS) { /* The lookup of the zone may fail. */ + if (zstr(format)) { + format = "%Y-%m-%d"; + } + + if (format && switch_strftime_tz(tz_name, format, date, sizeof(date), when * 1000000) == SWITCH_STATUS_SUCCESS) { /* The lookup of the zone may fail. */ stream->write_function(stream, "%s", date); } else { - stream->write_function(stream, "-ERR Invalid Timezone\n"); + stream->write_function(stream, "-ERR Invalid Timezone/Format\n"); } switch_safe_free(mycmd); From f0a31e1bfff2d49d97bc0ee83627c426fa311bfc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 7 Feb 2011 14:35:56 -0600 Subject: [PATCH 84/86] default to 10 --- src/mod/endpoints/mod_sofia/mod_sofia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index c78aac7933..c6832030b4 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -3708,7 +3708,7 @@ SWITCH_STANDARD_API(sofia_function) if (argc > 2) { if (strstr(argv[2], "presence")) { - mod_sofia_globals.debug_presence = 1; + mod_sofia_globals.debug_presence = 10; stream->write_function(stream, "+OK Debugging presence\n"); } From bcb2262fdc48b36bd2e6bfe45adcbaecd1d091ee Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Mon, 7 Feb 2011 22:22:37 +0100 Subject: [PATCH 85/86] major factor of pgsql field handling --- conf/autoload_configs/cdr_pg_csv.conf.xml | 25 +- .../mod_cdr_pg_csv/mod_cdr_pg_csv.c | 279 +++++++----------- 2 files changed, 130 insertions(+), 174 deletions(-) diff --git a/conf/autoload_configs/cdr_pg_csv.conf.xml b/conf/autoload_configs/cdr_pg_csv.conf.xml index 427bf2d058..4fec817b45 100644 --- a/conf/autoload_configs/cdr_pg_csv.conf.xml +++ b/conf/autoload_configs/cdr_pg_csv.conf.xml @@ -16,10 +16,25 @@ - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c index 1ec56bdd64..51194f4b14 100644 --- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c +++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c @@ -59,28 +59,34 @@ typedef struct { switch_mutex_t *mutex; } cdr_fd_t; -const char *default_template = - "\"${local_ip_v4}\",\"${caller_id_name}\",\"${caller_id_number}\",\"${destination_number}\",\"${context}\",\"${start_stamp}\"," - "\"${answer_stamp}\",\"${end_stamp}\",\"${duration}\",\"${billsec}\",\"${hangup_cause}\",\"${uuid}\",\"${bleg_uuid}\",\"${accountcode}\"," - "\"${read_codec}\",\"${write_codec}\""; +typedef struct { + char *col_name; + char *var_name; + switch_bool_t quote; + switch_bool_t not_null; +} cdr_field_t; + +typedef struct { + char *columns; + cdr_field_t fields[1]; +} db_schema_t; static struct { switch_memory_pool_t *pool; switch_hash_t *fd_hash; - switch_hash_t *template_hash; int shutdown; char *db_info; char *db_table; + db_schema_t *db_schema; PGconn *db_connection; + switch_mutex_t *db_mutex; int db_online; cdr_leg_t legs; char *spool_dir; spool_format_t spool_format; int rotate; int debug; - char *default_template; - switch_mutex_t *db_mutex; -} globals = { 0 }; +} globals; static switch_xml_config_enum_item_t config_opt_cdr_leg_enum[] = { {"a", CDR_LEG_A}, @@ -110,7 +116,6 @@ static switch_xml_config_item_t config_settings[] = { /* key, type, flags, ptr, default_value, data, syntax, helptext */ SWITCH_CONFIG_ITEM_STRING_STRDUP("db-info", CONFIG_RELOADABLE, &globals.db_info, "dbname=cdr", NULL, NULL), SWITCH_CONFIG_ITEM_STRING_STRDUP("db-table", CONFIG_RELOADABLE, &globals.db_table, "cdr", NULL, NULL), - SWITCH_CONFIG_ITEM_STRING_STRDUP("default-template", CONFIG_RELOADABLE, &globals.default_template, "default", NULL, NULL), SWITCH_CONFIG_ITEM("legs", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.legs, (void *) CDR_LEG_A, &config_opt_cdr_leg_enum, "a|b|ab", NULL), SWITCH_CONFIG_ITEM("spool-format", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.spool_format, (void *) SPOOL_FORMAT_CSV, &config_opt_spool_format_enum, "csv|sql", "Disk spool format to use if SQL insert fails."), SWITCH_CONFIG_ITEM("rotate-on-hup", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.rotate, SWITCH_FALSE, NULL, NULL, NULL), @@ -239,135 +244,13 @@ static void spool_cdr(const char *path, const char *log_line) switch_safe_free(log_line_lf); } -static switch_status_t insert_cdr(const char * const template, const char * const cdr) +static switch_status_t insert_cdr(const char *values) { - char *columns, *values; - char *p, *q; - unsigned vlen; - char *nullValues, *temp, *tp; - int nullCounter = 0, charCounter = 0; char *sql = NULL, *path = NULL; PGresult *res; - if (!template || !*template || !cdr || !*cdr) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Bad parameter\n"); - return SWITCH_STATUS_FALSE; - } - - /* Build comma-separated list of field names by dropping $ { } ; chars */ - switch_strdup(columns, template); - for (p = columns, q = columns; *p; ++p) { - switch (*p) { - case '$': case '"': case '{': case '}': case ';': - break; - default: - *q++ = *p; - } - } - *q = '\0'; - - /* - * In the expanded vars, replace double quotes (") with single quotes (') - * for correct PostgreSQL syntax, and replace semi-colon with space to - * prevent SQL injection attacks - */ - switch_strdup(values, cdr); - for (p = values; *p; ++p) { - switch(*p) { - case '"': - *p = '\''; - break; - case ';': - *p = ' '; - break; - } - } - vlen = p - values; - - /* - * Patch for changing empty strings ('') in the expanded variables to - * PostgreSQL null - */ - for (p = values; *p; ++p) { - if (*p == ',') { - if (charCounter == 0) { - nullCounter++; - } - charCounter = 0; - } else if (*p != ' ' && *p != '\'') { - charCounter++; - } - } - - if (charCounter == 0) { - nullCounter++; - } - - nullCounter *= 4; - vlen += nullCounter; - switch_zmalloc(nullValues, strlen(values) + nullCounter + 1); - charCounter = 0; - temp = nullValues; - tp = nullValues; - - for (p = values; *p; ++tp, ++p) { - if (*p == ',') { - if (charCounter == 0) { - temp++; - *temp = 'n'; - temp++; - if (temp == tp) tp++; - *temp = 'u'; - temp++; - if (temp == tp) tp++; - *temp = 'l'; - temp++; - if (temp == tp) tp++; - *temp = 'l'; - temp++; - while (temp != tp) { - *temp = ' '; - temp++; - } - } - charCounter = 0; - temp = tp; - } else if (*p != ' ' && *p != '\'') { - charCounter++; - } - *tp = *p; - } - - if (charCounter == 0) { - temp++; - *temp = 'n'; - temp++; - if (temp == tp) tp++; - *temp = 'u'; - temp++; - if (temp == tp) tp++; - *temp = 'l'; - temp++; - if (temp == tp) tp++; - *temp = 'l'; - temp++; - while (temp != tp) { - *temp = ' '; - temp++; - } - } - - charCounter = 0; - temp = tp; - *tp = 0; - tp = values; - values = nullValues; - switch_safe_free(tp); - - sql = switch_mprintf("INSERT INTO %s (%s) VALUES (%s);", globals.db_table, columns, values); + sql = switch_mprintf("INSERT INTO %s (%s) VALUES (%s);", globals.db_table, globals.db_schema->columns, values); assert(sql); - switch_safe_free(columns); - switch_safe_free(values); if (globals.debug) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Query: \"%s\"\n", sql); @@ -415,7 +298,7 @@ static switch_status_t insert_cdr(const char * const template, const char * cons } else { path = switch_mprintf("%s%scdr-spool.csv", globals.spool_dir, SWITCH_PATH_SEPARATOR); assert(path); - spool_cdr(path, cdr); + spool_cdr(path, values); } switch_safe_free(path); @@ -428,8 +311,10 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_status_t status = SWITCH_STATUS_SUCCESS; - const char *template_str = NULL; - char *expanded_vars = NULL; + char *values = NULL, *tmp = NULL, *pq_var = NULL; + const char *var = NULL; + cdr_field_t *cdr_field = NULL; + switch_size_t len, offset; if (globals.shutdown) { return SWITCH_STATUS_SUCCESS; @@ -465,24 +350,40 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) } } - template_str = (const char *) switch_core_hash_find(globals.template_hash, globals.default_template); + switch_zmalloc(values, 1); + offset = 0; - if (!template_str) { - template_str = default_template; + for (cdr_field = globals.db_schema->fields; cdr_field->var_name; cdr_field++) { + if ((var = switch_channel_get_variable(channel, cdr_field->var_name))) { + /* Allocate sufficient buffer for PQescapeString */ + len = strlen(var); + tmp = switch_core_session_alloc(session, len * 2 + 1); + PQescapeString(tmp, var, len); + var = tmp; + } + + if (cdr_field->quote) { + if ((cdr_field->not_null == SWITCH_FALSE) && zstr(var)) { + pq_var = switch_mprintf("null,", var); + } else { + pq_var = switch_mprintf("'%s',", var); + } + } else { + pq_var = switch_mprintf("%s,", var); + } + + /* Resize values buffer to accomodate next var */ + len = strlen(pq_var); + tmp = realloc(values, offset + len); + values = tmp; + memcpy(values + offset, pq_var, len); + switch_safe_free(pq_var); + offset += len; } + *(values + --offset) = '\0'; - expanded_vars = switch_channel_expand_variables(channel, template_str); - - if (!expanded_vars) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error expanding CDR variables.\n"); - return SWITCH_STATUS_FALSE; - } - - insert_cdr(template_str, expanded_vars); - - if (expanded_vars != template_str) { - switch_safe_free(expanded_vars); - } + insert_cdr(values); + switch_safe_free(values); return status; } @@ -532,9 +433,13 @@ static switch_state_handler_table_t state_handlers = { static switch_status_t load_config(switch_memory_pool_t *pool) { - char *cf = "cdr_pg_csv.conf"; - switch_xml_t cfg, xml, settings, param; switch_status_t status = SWITCH_STATUS_SUCCESS; + char *cf = "cdr_pg_csv.conf", *ptr; + switch_xml_t cfg, xml, schema, field; + const char *attr; + int num_fields = 0; + switch_size_t len = 0; + cdr_field_t *cdr_field; if (globals.db_online) { PQfinish(globals.db_connection); @@ -544,32 +449,69 @@ static switch_status_t load_config(switch_memory_pool_t *pool) memset(&globals, 0, sizeof(globals)); switch_core_hash_init(&globals.fd_hash, pool); - switch_core_hash_init(&globals.template_hash, pool); switch_mutex_init(&globals.db_mutex, SWITCH_MUTEX_NESTED, pool); globals.pool = pool; - switch_core_hash_insert(globals.template_hash, "default", default_template); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding default template.\n"); - globals.legs = CDR_LEG_A; - - if (switch_xml_config_parse_module_settings("cdr_pg_csv.conf", SWITCH_FALSE, config_settings) != SWITCH_STATUS_SUCCESS) { + if (switch_xml_config_parse_module_settings(cf, SWITCH_FALSE, config_settings) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_FALSE; } if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) { - if ((settings = switch_xml_child(cfg, "templates"))) { - for (param = switch_xml_child(settings, "template"); param; param = param->next) { - char *var = (char *) switch_xml_attr(param, "name"); - if (var) { - char *tpl; - tpl = switch_core_strdup(pool, param->txt); - - switch_core_hash_insert(globals.template_hash, var, tpl); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding template %s.\n", var); + if ((schema = switch_xml_child(cfg, "schema"))) { + /* Count fields in schema so we can calculate required buffer size */ + for (field = switch_xml_child(schema, "field"); field; field = field->next) { + if (switch_xml_attr(field, "var")) { + num_fields++; } } + + globals.db_schema = switch_core_alloc(pool, (num_fields + 1) * sizeof(cdr_field_t)); + cdr_field = globals.db_schema->fields; + + for (field = switch_xml_child(schema, "field"); field; field = field->next) { + if ((attr = switch_xml_attr(field, "var"))) { + cdr_field->var_name = switch_core_strdup(pool, attr); + + /* Assume SQL column name is the same as FreeSWITCH channel var name, unless specified otherwise */ + if ((attr = switch_xml_attr(field, "column"))) { + cdr_field->col_name = switch_core_strdup(pool, attr); + } else { + cdr_field->col_name = switch_core_strdup(pool, cdr_field->var_name); + } + + /* Assume all fields should be quoted (treated as strings), unless specified otherwise */ + if ((attr = switch_xml_attr(field, "quote")) && !strncmp(attr, "false", 5)) { + cdr_field->quote = SWITCH_FALSE; + } else { + cdr_field->quote = SWITCH_TRUE; + } + + /* Assume all fields allow SQL nulls, unless specified otherwise */ + if ((attr = switch_xml_attr(field, "not-null")) && !strncmp(attr, "true", 4)) { + cdr_field->not_null = SWITCH_TRUE; + } else { + cdr_field->not_null = SWITCH_FALSE; + } + + len += strlen(cdr_field->col_name) + 1; + cdr_field++; + } + } + cdr_field->var_name = 0; + + globals.db_schema->columns = switch_core_alloc(pool, len); + ptr = globals.db_schema->columns; + for (cdr_field = globals.db_schema->fields; cdr_field->col_name; cdr_field++) { + len = strlen(cdr_field->col_name); + memcpy(ptr, cdr_field->col_name, len); + ptr += len; + *ptr = ','; + ptr++; + } + *--ptr = '\0'; } + switch_xml_free(xml); } @@ -596,7 +538,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_pg_csv_load) switch_core_add_state_handler(&state_handlers); *module_interface = switch_loadable_module_create_module_interface(pool, modname); - return status; } From 3830484155cfa3bd8ef09b88515e8afa6c251121 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 7 Feb 2011 16:06:45 -0600 Subject: [PATCH 86/86] freetdm: do not expect result_cb to be set to make the interface cleaner --- libs/freetdm/src/ftdm_io.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 0f92f59053..c9000de1f2 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -37,9 +37,6 @@ * */ -#ifdef MOYTEST -crap -#endif #define _GNU_SOURCE #include "private/ftdm_core.h" #include @@ -2509,10 +2506,12 @@ FT_DECLARE(ftdm_status_t) _ftdm_call_place(const char *file, const char *func, i } /* we have a locked channel and are not afraid of using it! */ - status = hunting->result_cb(fchan, caller_data); - if (status != FTDM_SUCCESS) { - status = FTDM_ECANCELED; - goto done; + if (hunting->result_cb) { + status = hunting->result_cb(fchan, caller_data); + if (status != FTDM_SUCCESS) { + status = FTDM_ECANCELED; + goto done; + } } ftdm_channel_set_caller_data(fchan, caller_data);