From acd56d2fe2a0458801010cc6b03c524023cbc597 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 22 Aug 2010 18:00:40 -0500 Subject: [PATCH 001/245] 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 002/245] 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 003/245] 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 004/245] 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 005/245] 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 006/245] 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 007/245] 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 008/245] 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 57613192ccbf2a735d4afacfd63956aba5735457 Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Mon, 17 Jan 2011 15:24:55 -0800 Subject: [PATCH 009/245] Bump sounds file version to 1.0.14 --- build/sounds_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/sounds_version.txt b/build/sounds_version.txt index cb0c481b13..20cb29cbd7 100644 --- a/build/sounds_version.txt +++ b/build/sounds_version.txt @@ -1,3 +1,3 @@ -en-us-callie 1.0.13 +en-us-callie 1.0.14 ru-RU-elena 1.0.12 From 978cb111e7971eceb238d396124e10424b148a6c Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 19 Jan 2011 16:35:55 -0500 Subject: [PATCH 010/245] freetdm - improved default bearer-cap code --- .../ftmod_sangoma_isdn_support.c | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index 9c1b7baf79..64147b7d75 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -881,18 +881,27 @@ ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap) bearCap->usrInfoLyr1Prot.pres = PRSNT_NODEF; bearCap->usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1); - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN && - bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) { - - /* We are bridging a call from T1 */ - bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW; - - } else if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) { - - /* We are bridging a call from E1 */ - bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW; + switch (signal_data->switchtype) { + case SNGISDN_SWITCH_NI2: + case SNGISDN_SWITCH_4ESS: + case SNGISDN_SWITCH_5ESS: + case SNGISDN_SWITCH_DMS100: + case SNGISDN_SWITCH_INSNET: + if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Overriding bearer cap to u-law\n"); + bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW; + } + break; + case SNGISDN_SWITCH_EUROISDN: + case SNGISDN_SWITCH_QSIG: + if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Overriding bearer cap to a-law\n"); + bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW; + } + break; } + bearCap->lyr1Ident.pres = PRSNT_NODEF; bearCap->lyr1Ident.val = IN_L1_IDENT; } From 1da8339ffb5719ba92ececeb27b6c335f3e6b4aa Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 20 Jan 2011 10:42:28 -0500 Subject: [PATCH 011/245] freetdm: added support for early-media-override --- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 3 ++ .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 14 +++++--- .../ftmod_sangoma_isdn_cfg.c | 25 +++++++++++++- .../ftmod_sangoma_isdn_stack_hndl.c | 33 +++++++++++++++---- 4 files changed, 63 insertions(+), 12 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 e7053c1d43..df528ae9c1 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 @@ -676,6 +676,9 @@ static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdm /*OUTBOUND...so we were told by the line of this so noifiy the user*/ sigev.event_id = FTDM_SIGEVENT_PROCEED; ftdm_span_send_signal(ftdmchan->span, &sigev); + if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) { + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); + } } else { if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) { /* By default, we do not send a progress indicator in the proceed */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index 58fcc07040..80dc73f0fa 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -112,6 +112,11 @@ typedef enum { SNGISDN_OPT_FALSE = 2, } sngisdn_opt_t; +typedef enum { + SNGISDN_EARLY_MEDIA_ON_PROCEED = (1 << 0), + SNGISDN_EARLY_MEDIA_ON_PROGRESS = (1 << 1), + SNGISDN_EARLY_MEDIA_ON_ALERT= (1 << 2), +} sngisdn_early_media_opt_t; typedef enum { SNGISDN_AVAIL_DOWN = 1, @@ -188,7 +193,8 @@ typedef struct sngisdn_span_data { uint8_t span_id; uint8_t tei; uint8_t min_digits; - uint8_t trace_flags; /* TODO: change to flags, so we can use ftdm_test_flag etc.. */ + uint8_t trace_flags; /* TODO change to bit map of sngisdn_tracetype_t */ + uint8_t early_media_flags; /* bit map of ftdm_sngisdn_early_media_opt_t */ uint8_t overlap_dial; uint8_t setup_arb; uint8_t facility_ie_decode; @@ -196,10 +202,10 @@ typedef struct sngisdn_span_data { int8_t facility_timeout; uint8_t num_local_numbers; uint8_t ignore_cause_value; - uint8_t raw_trace_q931; - uint8_t raw_trace_q921; + uint8_t raw_trace_q931; /* TODO: combine with trace_flags */ + uint8_t raw_trace_q921; /* TODO: combine with trace_flags */ uint8_t timer_t3; - uint8_t restart_opt; + uint8_t restart_opt; char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS]; ftdm_sched_t *sched; ftdm_queue_t *event_queue; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index aad68e15d1..afba96accc 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -192,6 +192,24 @@ static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span) return FTDM_SUCCESS; } +static ftdm_status_t parse_early_media(const char* opt, ftdm_span_t *span) +{ + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; + if (!strcasecmp(opt, "on-proceed")) { + signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_PROCEED; + } else if (!strcasecmp(opt, "on-progress")) { + signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_PROGRESS; + } else if (!strcasecmp(opt, "on-alert")) { + signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_ALERT; + } else { + ftdm_log(FTDM_LOG_ERROR, "Unsupported early-media option %s\n", opt); + return FTDM_FAIL; + } + ftdm_log(FTDM_LOG_DEBUG, "Early media opt:0x%x\n", signal_data->early_media_flags); + return FTDM_SUCCESS; +} + + static ftdm_status_t set_switchtype_defaults(ftdm_span_t *span) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; @@ -249,6 +267,7 @@ static ftdm_status_t set_switchtype_defaults(ftdm_span_t *span) return FTDM_SUCCESS; } + ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span) { unsigned paramindex; @@ -351,10 +370,14 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ parse_yesno(var, val, &signal_data->raw_trace_q931); } else if (!strcasecmp(var, "q921-raw-trace")) { parse_yesno(var, val, &signal_data->raw_trace_q921); + } else if (!strcasecmp(var, "early-media-override")) { + if (parse_early_media(val, span) != FTDM_SUCCESS) { + return FTDM_FAIL; + } } else { ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var); } - } + } /* for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) */ if (signal_data->switchtype == SNGISDN_SWITCH_INVALID) { ftdm_log(FTDM_LOG_ERROR, "%s: switchtype not specified", span->name); 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 7b7c748c7a..0b52011d42 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 @@ -167,12 +167,12 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) char retrieved_str[255]; ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str); - /* - return values for "sng_isdn_retrieve_facility_information_following": - If there will be no information following, or fails to decode IE, returns -1 - If there will be no information following, but current FACILITY IE contains a caller name, returns 0 - If there will be information following, returns 1 - */ + /* + return values for "sng_isdn_retrieve_facility_information_following": + If there will be no information following, or fails to decode IE, returns -1 + If there will be no information following, but current FACILITY IE contains a caller name, returns 0 + If there will be information following, returns 1 + */ if (ret_val == 1) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n"); @@ -346,6 +346,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; @@ -384,7 +385,7 @@ 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: + case FTDM_CHANNEL_STATE_RINGING: if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.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); @@ -393,16 +394,34 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) } switch (evntType) { case MI_CALLPROC: + if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) && + (signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_PROCEED)) { + + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on proceed\n"); + sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); + } if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED); } break; case MI_ALERTING: + if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) && + (signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_ALERT)) { + + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on alert\n"); + sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); + } if (ftdmchan->state == FTDM_CHANNEL_STATE_PROCEED) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RINGING); } break; case MI_PROGRESS: + if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) && + (signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_PROGRESS)) { + + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on progress\n"); + sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); + } if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } else if (ftdmchan->state != FTDM_CHANNEL_STATE_PROGRESS) { From d743baefedfbe679a647013adc2718defef90718 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 20 Jan 2011 11:03:13 -0500 Subject: [PATCH 012/245] freetdm: Fix for defaulting to wrong codec --- .../src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index afba96accc..bd5b13bfec 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -389,10 +389,11 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ } if (span->default_caller_data.bearer_layer1 == FTDM_INVALID_INT_PARM) { - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) { - span->default_caller_data.bearer_layer1 = IN_UIL1_G711ULAW; - } else { + if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN || + signal_data->switchtype == SNGISDN_SWITCH_QSIG) { span->default_caller_data.bearer_layer1 = IN_UIL1_G711ALAW; + } else { + span->default_caller_data.bearer_layer1 = IN_UIL1_G711ULAW; } } return FTDM_SUCCESS; From 70700617d3d6bd45904a81be443fe28aa7fd0387 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 20 Jan 2011 13:52:00 -0600 Subject: [PATCH 013/245] add execute_on_originate var ' ' to run in origination thread or '::' to run async. also originating_leg_uuid variable to show the uuid of the originating leg on an outbound channel --- src/switch_ivr_originate.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index d156c700fd..78743e6420 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -2755,6 +2755,26 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } } + + if (session) { + switch_channel_set_variable(originate_status[i].peer_channel, "originating_leg_uuid", switch_core_session_get_uuid(session)); + } + + if ((vvar = switch_channel_get_variable_dup(originate_status[i].peer_channel, "execute_on_originate", SWITCH_FALSE))) { + char *app = switch_core_session_strdup(originate_status[i].peer_session, vvar); + char *arg = NULL; + + if (strstr(app, "::")) { + switch_core_session_execute_application_async(originate_status[i].peer_session, app, arg); + } else { + if ((arg = strchr(app, ' '))) { + *arg++ = '\0'; + } + + switch_core_session_execute_application(originate_status[i].peer_session, app, arg); + } + + } } if (table) { @@ -2773,7 +2793,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess *cause = SWITCH_CAUSE_SUCCESS; goto outer_for; } - + if (!switch_core_session_running(originate_status[i].peer_session)) { if (originate_status[i].per_channel_delay_start) { switch_channel_set_flag(originate_status[i].peer_channel, CF_BLOCK_STATE); From fd984d03bb629d08ac4192c5a1d3432e94ceb3d5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 20 Jan 2011 17:52:54 -0600 Subject: [PATCH 014/245] D'oh Over zealous packet eating --- src/switch_rtp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 4e5450d7e8..3ce7a07e60 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2494,7 +2494,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } } - if (rtp_session->recv_msg.header.pt != 13 && + if (bytes && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) && + rtp_session->recv_msg.header.pt != 13 && rtp_session->recv_msg.header.pt != rtp_session->recv_te && (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) && rtp_session->recv_msg.header.pt != rtp_session->payload) { From 1c95ad98cd1c0e966b738796e74923db8919b754 Mon Sep 17 00:00:00 2001 From: Joao Mesquita Date: Thu, 20 Jan 2011 22:43:50 -0300 Subject: [PATCH 015/245] Export the variables to the b leg as well --- src/mod/applications/mod_dptools/mod_dptools.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 41417255bb..5a3be0328d 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -2982,6 +2982,8 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, } } } + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_user", user); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_domain", domain); if (!dest) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No dial-string available, please check your user directory.\n"); From 7fbc47f83a5bf455b6ece49deb7771d144bbce4c Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Fri, 21 Jan 2011 09:09:53 -0600 Subject: [PATCH 016/245] FS-2973 Fix possible segfaults and memory leak during unload, and add new setting odbc-retries --- conf/autoload_configs/easyroute.conf.xml | 3 +++ src/mod/applications/mod_easyroute/mod_easyroute.c | 13 +++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/conf/autoload_configs/easyroute.conf.xml b/conf/autoload_configs/easyroute.conf.xml index 7cd490942f..350a50989b 100644 --- a/conf/autoload_configs/easyroute.conf.xml +++ b/conf/autoload_configs/easyroute.conf.xml @@ -11,6 +11,9 @@ + + + + From 4eccdfef58a64652ae2a1f0a7a1f11ae55346420 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Fri, 21 Jan 2011 21:47:46 -0500 Subject: [PATCH 028/245] mod_erlang_event: Don't urlencode events (and destroy an event after use) --- src/mod/event_handlers/mod_erlang_event/ei_helpers.c | 1 + src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/mod/event_handlers/mod_erlang_event/ei_helpers.c b/src/mod/event_handlers/mod_erlang_event/ei_helpers.c index a99b52074c..db4f7780e0 100644 --- a/src/mod/event_handlers/mod_erlang_event/ei_helpers.c +++ b/src/mod/event_handlers/mod_erlang_event/ei_helpers.c @@ -111,6 +111,7 @@ void ei_encode_switch_event_headers(ei_x_buff * ebuf, switch_event_t *event) for (hp = event->headers; hp; hp = hp->next) { ei_x_encode_tuple_header(ebuf, 2); _ei_x_encode_string(ebuf, hp->name); + switch_url_decode(hp->value); _ei_x_encode_string(ebuf, hp->value); } diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c index 8d3c594b75..1a8bd00790 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c @@ -532,6 +532,7 @@ static switch_status_t notify_new_session(listener_t *listener, session_elem_t * session_element->uuid_str); } + switch_event_destroy(&call_event); ei_x_free(&lbuf); return SWITCH_STATUS_SUCCESS; } From 8d6d52e015411649e0591eb7ad667885523b99c3 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Fri, 21 Jan 2011 21:50:02 -0500 Subject: [PATCH 029/245] mod_conference Add energy level to conference_add_event_member_data This is useful when you want to find the energy a member joined with without having to pull the 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 2d9341a598..7f7ee83795 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -477,6 +477,7 @@ static switch_status_t conference_add_event_member_data(conference_member_t *mem switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Mute-Detect", "%s", switch_test_flag(member, MFLAG_MUTE_DETECT) ? "true" : "false" ); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-Type", "%s", switch_test_flag(member, MFLAG_MOD) ? "moderator" : "member"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Energy-Level", "%d", member->energy_level); return status; } From 9fe440b2fe63935331b148ffc1d3c7a5ddffa20b Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Fri, 21 Jan 2011 21:53:03 -0500 Subject: [PATCH 030/245] mod_erlang_event Add proper locking for the list of XML bindings --- .../event_handlers/mod_erlang_event/handle_msg.c | 4 ++-- .../mod_erlang_event/mod_erlang_event.c | 13 +++++++++---- .../mod_erlang_event/mod_erlang_event.h | 1 + 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/mod/event_handlers/mod_erlang_event/handle_msg.c b/src/mod/event_handlers/mod_erlang_event/handle_msg.c index 9ae15277fd..87f91fc51b 100644 --- a/src/mod/event_handlers/mod_erlang_event/handle_msg.c +++ b/src/mod/event_handlers/mod_erlang_event/handle_msg.c @@ -778,7 +778,7 @@ static switch_status_t handle_msg_bind(listener_t *listener, erlang_msg * msg, e binding->process.pid = msg->from; binding->listener = listener; - switch_thread_rwlock_wrlock(globals.listener_rwlock); + switch_thread_rwlock_wrlock(globals.bindings_rwlock); for (ptr = bindings.head; ptr && ptr->next; ptr = ptr->next); @@ -789,7 +789,7 @@ static switch_status_t handle_msg_bind(listener_t *listener, erlang_msg * msg, e } switch_xml_set_binding_sections(bindings.search_binding, switch_xml_get_binding_sections(bindings.search_binding) | section); - switch_thread_rwlock_unlock(globals.listener_rwlock); + switch_thread_rwlock_unlock(globals.bindings_rwlock); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sections %d\n", switch_xml_get_binding_sections(bindings.search_binding)); diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c index 1a8bd00790..900b9655ff 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c @@ -90,7 +90,7 @@ static void remove_binding(listener_t *listener, erlang_pid * pid) { struct erlang_binding *ptr, *lst = NULL; - switch_thread_rwlock_wrlock(globals.listener_rwlock); + switch_thread_rwlock_wrlock(globals.bindings_rwlock); switch_xml_set_binding_sections(bindings.search_binding, SWITCH_XML_SECTION_MAX); @@ -100,7 +100,7 @@ static void remove_binding(listener_t *listener, erlang_pid * pid) if (ptr->next) { bindings.head = ptr->next; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed all (only?) listeners\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed all (only?) binding\n"); bindings.head = NULL; break; } @@ -111,13 +111,13 @@ static void remove_binding(listener_t *listener, erlang_pid * pid) lst->next = NULL; } } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed listener\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed binding\n"); } else { switch_xml_set_binding_sections(bindings.search_binding, switch_xml_get_binding_sections(bindings.search_binding) | ptr->section); } } - switch_thread_rwlock_unlock(globals.listener_rwlock); + switch_thread_rwlock_unlock(globals.bindings_rwlock); } @@ -381,6 +381,8 @@ static switch_xml_t erlang_fetch(const char *sectionstr, const char *tag_name, c section = switch_xml_parse_section_string((char *) sectionstr); + switch_thread_rwlock_rdlock(globals.bindings_rwlock); + for (ptr = bindings.head; ptr; ptr = ptr->next) { if (ptr->section != section) continue; @@ -417,6 +419,8 @@ static switch_xml_t erlang_fetch(const char *sectionstr, const char *tag_name, c switch_mutex_unlock(ptr->listener->sock_mutex); } + switch_thread_rwlock_unlock(globals.bindings_rwlock); + ei_x_free(&buf); if (!p) { @@ -1638,6 +1642,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_erlang_event_load) memset(&prefs, 0, sizeof(prefs)); switch_thread_rwlock_create(&globals.listener_rwlock, pool); + switch_thread_rwlock_create(&globals.bindings_rwlock, pool); switch_mutex_init(&globals.fetch_reply_mutex, SWITCH_MUTEX_DEFAULT, pool); switch_mutex_init(&globals.listener_count_mutex, SWITCH_MUTEX_UNNESTED, pool); switch_core_hash_init(&globals.fetch_reply_hash, pool); diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h index dacfbd661b..121e7b4f95 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h @@ -161,6 +161,7 @@ struct api_command_struct { struct globals_struct { switch_thread_rwlock_t *listener_rwlock; + switch_thread_rwlock_t *bindings_rwlock; switch_event_node_t *node; switch_mutex_t *ref_mutex; switch_mutex_t *fetch_reply_mutex; From 5316bcd9dc648b3874ebddea75ed6f34431c7f35 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Sat, 22 Jan 2011 13:36:16 +0800 Subject: [PATCH 031/245] Typo in the spandsp .pc.in file fixed --- libs/spandsp/spandsp.pc.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/spandsp/spandsp.pc.in b/libs/spandsp/spandsp.pc.in index 86a50ff62a..1a91ba04e1 100644 --- a/libs/spandsp/spandsp.pc.in +++ b/libs/spandsp/spandsp.pc.in @@ -1,5 +1,5 @@ prefix=@prefix@ -exec_prefix=@exec_prefix@ +exec_prefix=@prefix@ libdir=@libdir@ includedir=@includedir@ From 9adac7c6988df8436c634edaaa13ae39067f8df7 Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Sun, 23 Jan 2011 01:42:39 +0100 Subject: [PATCH 032/245] [fsxs] Remove APR and APR-UTIL libraries from fsxs LIBS variable. "LIBS" in the final fsxs script will be empty now. We still link against libfreeswitch when building a module, but we don't explicitly list (some of) its dependency libs anymore (this list was not complete anyway). This fixes a bogus /path_to_source/expat.la entry in LIBS that came from "apu-config --libs". Tested on Gentoo x86_64 (binutils 2.20.1) and Centos 5.5 (binutils 2.17.50). Tested-by: Stefan Knoblich Signed-off-by: Stefan Knoblich --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 8d35068c35..37a01d27fb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -349,7 +349,7 @@ scripts/fsxs: scripts/fsxs.in -e "s|@INCLUDES\@|-I$(prefix)/include|" \ -e "s|@SOLINK\@|$(SOLINK)|" \ -e "s|@LDFLAGS\@|-L$(prefix)/lib|" \ - -e "s|@LIBS\@|`./libs/apr/apr-1-config --libs` `./libs/apr-util/apu-1-config --libs`|" \ + -e "s|@LIBS\@||" \ $(top_srcdir)/scripts/fsxs.in > scripts/fsxs ## From b88cd3457a847cf05564df51bd8a60036b15bfd8 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Sat, 22 Jan 2011 22:51:48 -0600 Subject: [PATCH 033/245] FS-3000 mod_conference: if more digits than the length of the correct pin the remaining digits are accounted for next retry --- .../mod_conference/mod_conference.c | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 7f7ee83795..e6a47bf1ec 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -5597,6 +5597,7 @@ SWITCH_STANDARD_APP(conference_function) char pin_buf[80] = ""; int pin_retries = 3; /* XXX - this should be configurable - i'm too lazy to do it right now... */ int pin_valid = 0; + int be_friendly = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; char *supplied_pin_value; @@ -5631,19 +5632,23 @@ SWITCH_STANDARD_APP(conference_function) switch_status_t pstatus = SWITCH_STATUS_FALSE; /* be friendly */ - if (conference->pin_sound) { - pstatus = conference_local_play_file(conference, session, conference->pin_sound, 20, pin_buf, sizeof(pin_buf)); - } else if (conference->tts_engine && conference->tts_voice) { - pstatus = - switch_ivr_speak_text(session, conference->tts_engine, conference->tts_voice, "please enter the conference pin number", NULL); - } else { - pstatus = switch_ivr_speak_text(session, "flite", "slt", "please enter the conference pin number", NULL); + if (!be_friendly) { + if (conference->pin_sound) { + pstatus = conference_local_play_file(conference, session, conference->pin_sound, 20, pin_buf, sizeof(pin_buf)); + } else if (conference->tts_engine && conference->tts_voice) { + pstatus = + switch_ivr_speak_text(session, conference->tts_engine, conference->tts_voice, "please enter the conference pin number", NULL); + } else { + pstatus = switch_ivr_speak_text(session, "flite", "slt", "please enter the conference pin number", NULL); + } + + if (pstatus != SWITCH_STATUS_SUCCESS && pstatus != SWITCH_STATUS_BREAK) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot ask the user for a pin, ending call"); + switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + } } - if (pstatus != SWITCH_STATUS_SUCCESS && pstatus != SWITCH_STATUS_BREAK) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot ask the user for a pin, ending call"); - switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - } + be_friendly = 1; /* wait for them if neccessary */ if (strlen(pin_buf) < strlen(dpin)) { @@ -5660,13 +5665,12 @@ SWITCH_STANDARD_APP(conference_function) pin_valid = (status == SWITCH_STATUS_SUCCESS && strcmp(pin_buf, dpin) == 0); if (!pin_valid) { - /* zero the collected pin */ - memset(pin_buf, 0, sizeof(pin_buf)); - /* more friendliness */ if (conference->bad_pin_sound) { conference_local_play_file(conference, session, conference->bad_pin_sound, 20, pin_buf, sizeof(pin_buf)); } + /* zero the collected pin */ + memset(pin_buf, 0, sizeof(pin_buf)); } pin_retries--; } From 0e37dcb5db19592d28eb771edb4a0d394f5275ac Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Sun, 23 Jan 2011 17:43:38 -0600 Subject: [PATCH 034/245] windows - tweak installer permissions --- w32/Setup/Product.wxs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/w32/Setup/Product.wxs b/w32/Setup/Product.wxs index 2f072aa8ca..1de2ec204d 100644 --- a/w32/Setup/Product.wxs +++ b/w32/Setup/Product.wxs @@ -57,6 +57,9 @@ WorkingDirectory="INSTALLLOCATION"/> + + + + + + From 6294bc1620c94785f23bf6ae6966aaa67cf34c7f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 24 Jan 2011 09:41:53 -0600 Subject: [PATCH 035/245] have samples_out reflect what was written to the FH not the file even with buffering --- src/switch_core_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_file.c b/src/switch_core_file.c index c00756ffc6..19f23546f0 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -391,10 +391,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_write(switch_file_handle_t *fh, if ((status = fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen)) != SWITCH_STATUS_SUCCESS) { *len = 0; } - fh->samples_out += blen; } } + fh->samples_out += orig_len; return status; } else { switch_status_t status; From 7a1dcb69581ba593f3dc3868c94c1124c41e64f3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 24 Jan 2011 09:43:16 -0600 Subject: [PATCH 036/245] add record_restart_time_limit_on_dtmf var --- src/switch_ivr_play_say.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 523dfdeb02..4e9e7b95ca 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -372,6 +372,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se switch_event_t *event; int divisor = 0; int file_flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT; + int restart_limit_on_dtmf = 0; const char *prefix; prefix = switch_channel_get_variable(channel, "sound_prefix"); @@ -528,6 +529,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se if (switch_test_flag(fh, SWITCH_FILE_NATIVE)) { asis = 1; } + + restart_limit_on_dtmf = switch_true(switch_channel_get_variable(channel, "record_restart_limit_on_dtmf")); if ((p = switch_channel_get_variable(channel, "RECORD_TITLE"))) { vval = switch_core_session_strdup(session, p); @@ -637,6 +640,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ if (switch_channel_has_dtmf(channel)) { + + if (limit && restart_limit_on_dtmf) { + start = switch_epoch_time_now(NULL); + } + if (!args->input_callback && !args->buf && !args->dmachine) { status = SWITCH_STATUS_BREAK; break; From 6e4c30ea377728107e0747d614565eca964fa1d3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 24 Jan 2011 09:49:27 -0600 Subject: [PATCH 037/245] update code in mod_celt to match API of 0.10.0 --- src/mod/codecs/mod_celt/mod_celt.c | 34 +++++++++++------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/mod/codecs/mod_celt/mod_celt.c b/src/mod/codecs/mod_celt/mod_celt.c index 37983f3683..8d36b6af12 100644 --- a/src/mod/codecs/mod_celt/mod_celt.c +++ b/src/mod/codecs/mod_celt/mod_celt.c @@ -53,8 +53,8 @@ static switch_status_t switch_celt_init(switch_codec_t *codec, switch_codec_flag return SWITCH_STATUS_FALSE; } - context->mode_object = celt_mode_create(codec->implementation->actual_samples_per_second, codec->implementation->samples_per_packet, NULL); - + context->frame_size = codec->implementation->samples_per_packet; + context->mode_object = celt_mode_create(codec->implementation->actual_samples_per_second, context->frame_size, NULL); context->bytes_per_packet = (codec->implementation->bits_per_second * context->frame_size / codec->implementation->actual_samples_per_second + 4) / 8; /* @@ -106,15 +106,22 @@ static switch_status_t switch_celt_encode(switch_codec_t *codec, unsigned int *flag) { struct celt_context *context = codec->private_info; + int bytes = 0; if (!context) { return SWITCH_STATUS_FALSE; } - *encoded_data_len = (uint32_t) celt_encode(context->encoder_object, (void *) decoded_data, codec->implementation->samples_per_packet, - (unsigned char *) encoded_data, context->bytes_per_packet); + bytes = (uint32_t) celt_encode(context->encoder_object, (void *) decoded_data, codec->implementation->samples_per_packet, + (unsigned char *) encoded_data, context->bytes_per_packet); - return SWITCH_STATUS_SUCCESS; + 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_celt_decode(switch_codec_t *codec, @@ -152,23 +159,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_celt_load) SWITCH_ADD_CODEC(codec_interface, "CELT ultra-low delay"); - switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - 114, /* the IANA code number */ - "CELT", /* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function) */ - 32000, /* samples transferred per second */ - 32000, /* actual samples transferred per second */ - 32000, /* bits transferred per second */ - 10000, /* number of microseconds per frame */ - 320, /* number of samples per frame */ - 640, /* 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_celt_init, /* function to initialize a codec handle using this implementation */ - switch_celt_encode, /* function to encode raw data into encoded data */ - switch_celt_decode, /* function to decode encoded data into raw data */ - switch_celt_destroy); /* deinitalize a codec handle using this implementation */ ms_per_frame = 2000; samples_per_frame = 96; bytes_per_frame = 192; From a8f5bf60a87fb27420846bd9d9af5e61f1f947d6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 24 Jan 2011 12:18:02 -0600 Subject: [PATCH 038/245] fix proper display of meta digit in log lines --- src/include/switch_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 2c4de14334..a1a93c6ac8 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -192,7 +192,7 @@ static inline char switch_itodtmf(char i) r = i + 55; } - return r; + return r + 48; } static inline int switch_dtmftoi(char *s) From 976859bb45f08382424c9c4b0dbf6acb3fba64fb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 24 Jan 2011 14:04:26 -0600 Subject: [PATCH 039/245] fix unreachable condition with a null args to make any key stop playback/record etc without dequing and remove hard-coded flush digits in play_and_get_digits be sure to flush it yourself before using --- src/switch_ivr.c | 2 +- src/switch_ivr_play_say.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 496c29b524..a40da1b077 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -224,7 +224,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session, switch_ivr_parse_all_events(session); - if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { + if (args) { switch_dtmf_t dtmf; /* diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 4e9e7b95ca..dc263e9be5 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -634,7 +634,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se break; } - if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { + if (args) { /* dtmf handler function you can hook up to be executed when a digit is dialed during playback if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. @@ -862,7 +862,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi switch_ivr_parse_all_events(session); - if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { + if (args) { /* dtmf handler function you can hook up to be executed when a digit is dialed during gentones if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. @@ -1314,7 +1314,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_ivr_parse_all_events(session); - if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { + if (args) { /* dtmf handler function you can hook up to be executed when a digit is dialed during playback if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. @@ -1875,7 +1875,7 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t switch_status_t status; memset(digit_buffer, 0, digit_buffer_length); - switch_channel_flush_dtmf(channel); + status = switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, digit_buffer_length, timeout, valid_terminators, digit_timeout); if (status == SWITCH_STATUS_TIMEOUT && strlen(digit_buffer) >= min_digits) { @@ -2037,7 +2037,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session switch_event_destroy(&event); } - if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { + if (args) { /* dtmf handler function you can hook up to be executed when a digit is dialed during playback * if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ From 4eb5bbf41c3fcb6bfd33704a18bd2e7e52acd437 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 24 Jan 2011 14:48:44 -0600 Subject: [PATCH 040/245] FS-3000 revert previous - flush digits after pin error --- .../mod_conference/mod_conference.c | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index e6a47bf1ec..472f2d986c 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -5597,7 +5597,6 @@ SWITCH_STANDARD_APP(conference_function) char pin_buf[80] = ""; int pin_retries = 3; /* XXX - this should be configurable - i'm too lazy to do it right now... */ int pin_valid = 0; - int be_friendly = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; char *supplied_pin_value; @@ -5632,23 +5631,19 @@ SWITCH_STANDARD_APP(conference_function) switch_status_t pstatus = SWITCH_STATUS_FALSE; /* be friendly */ - if (!be_friendly) { - if (conference->pin_sound) { - pstatus = conference_local_play_file(conference, session, conference->pin_sound, 20, pin_buf, sizeof(pin_buf)); - } else if (conference->tts_engine && conference->tts_voice) { - pstatus = - switch_ivr_speak_text(session, conference->tts_engine, conference->tts_voice, "please enter the conference pin number", NULL); - } else { - pstatus = switch_ivr_speak_text(session, "flite", "slt", "please enter the conference pin number", NULL); - } - - if (pstatus != SWITCH_STATUS_SUCCESS && pstatus != SWITCH_STATUS_BREAK) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot ask the user for a pin, ending call"); - switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - } + if (conference->pin_sound) { + pstatus = conference_local_play_file(conference, session, conference->pin_sound, 20, pin_buf, sizeof(pin_buf)); + } else if (conference->tts_engine && conference->tts_voice) { + pstatus = + switch_ivr_speak_text(session, conference->tts_engine, conference->tts_voice, "please enter the conference pin number", NULL); + } else { + pstatus = switch_ivr_speak_text(session, "flite", "slt", "please enter the conference pin number", NULL); } - be_friendly = 1; + if (pstatus != SWITCH_STATUS_SUCCESS && pstatus != SWITCH_STATUS_BREAK) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot ask the user for a pin, ending call"); + switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + } /* wait for them if neccessary */ if (strlen(pin_buf) < strlen(dpin)) { @@ -5665,12 +5660,14 @@ SWITCH_STANDARD_APP(conference_function) pin_valid = (status == SWITCH_STATUS_SUCCESS && strcmp(pin_buf, dpin) == 0); if (!pin_valid) { - /* more friendliness */ - if (conference->bad_pin_sound) { - conference_local_play_file(conference, session, conference->bad_pin_sound, 20, pin_buf, sizeof(pin_buf)); - } /* zero the collected pin */ memset(pin_buf, 0, sizeof(pin_buf)); + + /* more friendliness */ + if (conference->bad_pin_sound) { + conference_local_play_file(conference, session, conference->bad_pin_sound, 20, NULL, 0); + } + switch_channel_flush_dtmf(channel); } pin_retries--; } From 24bcd10582193ef6dac5a124ad03323066e355f8 Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Mon, 24 Jan 2011 17:54:43 -0500 Subject: [PATCH 041/245] don't hold loadable_modules.mutex while a module shutdown function is run, so that we do not prevent new channels from being created. --- src/switch_loadable_module.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 03858aca29..d6796c8119 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -1047,20 +1047,24 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_unload_module(char *dir, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Module is not unloadable.\n"); *err = "Module is not unloadable"; status = SWITCH_STATUS_NOUNLOAD; - goto end; + goto unlock; } else { - if ((status = do_shutdown(module, SWITCH_TRUE, SWITCH_TRUE, !force, err) != SWITCH_STATUS_SUCCESS)) { - goto end; + /* Prevent anything from using the module while it's shutting down */ + switch_core_hash_delete(loadable_modules.module_hash, fname); + switch_mutex_unlock(loadable_modules.mutex); + if ((status = do_shutdown(module, SWITCH_TRUE, SWITCH_TRUE, !force, err)) != SWITCH_STATUS_SUCCESS) { + /* Something went wrong in the module's shutdown function, add it again */ + switch_core_hash_insert_locked(loadable_modules.module_hash, fname, module, loadable_modules.mutex); } + goto end; } - switch_core_hash_delete(loadable_modules.module_hash, fname); } else { *err = "No such module!"; status = SWITCH_STATUS_FALSE; } - end: +unlock: switch_mutex_unlock(loadable_modules.mutex); - + end: if (force) { switch_yield(1000000); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "PHEW!\n"); From 6477d3f87e32cc623638073fc1983ebfc4fa54cd Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Tue, 25 Jan 2011 00:26:58 +0100 Subject: [PATCH 042/245] make mod_snmp module unload more failsafe --- src/mod/event_handlers/mod_snmp/mod_snmp.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_snmp/mod_snmp.c b/src/mod/event_handlers/mod_snmp/mod_snmp.c index 040e82b602..36a133c805 100644 --- a/src/mod/event_handlers/mod_snmp/mod_snmp.c +++ b/src/mod/event_handlers/mod_snmp/mod_snmp.c @@ -98,6 +98,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load) netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1); init_agent("mod_snmp"); + + /* + * Override master/subagent ping interval to 5s, to ensure that + * agent_check_and_process() never blocks for longer than that. + */ + netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL, 5); + init_subagent(); init_snmp("mod_snmp"); @@ -107,8 +114,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load) SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime) { - /* block on select() */ - agent_check_and_process(1); + while (!globals.shutdown) { + /* Block on select() */ + agent_check_and_process(1); + } return SWITCH_STATUS_SUCCESS; } From 7ce63feadf86bf4321aa184311996d010aab59f8 Mon Sep 17 00:00:00 2001 From: cypromis Date: Tue, 25 Jan 2011 03:24:35 +0100 Subject: [PATCH 043/245] gpg-error is needed on c flags as well on solaris --- libs/iksemel/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/iksemel/configure.ac b/libs/iksemel/configure.ac index 1b8af13683..7761eb0295 100644 --- a/libs/iksemel/configure.ac +++ b/libs/iksemel/configure.ac @@ -83,7 +83,7 @@ AC_ARG_ENABLE(64, if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then if test "${enable_64}" = "yes"; then - CFLAGS="$CFLAGS -m64" + CFLAGS="$CFLAGS -m64 -lgpg-error" CXXFLAGS="$CXXFLAGS -m64 -lgpg-error" fi fi From 80a6279993f2369e79e70bc9b61bfcaf2f3e5f4c Mon Sep 17 00:00:00 2001 From: cypromis Date: Tue, 25 Jan 2011 04:14:31 +0100 Subject: [PATCH 044/245] explicitly add gpg-error if sun comiler, maybe that solves it finaly --- libs/iksemel/configure.ac | 3 +++ libs/iksemel/tools/Makefile.am | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libs/iksemel/configure.ac b/libs/iksemel/configure.ac index 7761eb0295..e00af1fb99 100644 --- a/libs/iksemel/configure.ac +++ b/libs/iksemel/configure.ac @@ -85,9 +85,12 @@ if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then if test "${enable_64}" = "yes"; then CFLAGS="$CFLAGS -m64 -lgpg-error" CXXFLAGS="$CXXFLAGS -m64 -lgpg-error" + SUNFLAGS="-lgpg.error" fi fi +AC_SUBST(SUNCFLAGS) + dnl Generating makefiles AC_CONFIG_FILES([ Makefile diff --git a/libs/iksemel/tools/Makefile.am b/libs/iksemel/tools/Makefile.am index ab81e66888..b7d80e9b05 100644 --- a/libs/iksemel/tools/Makefile.am +++ b/libs/iksemel/tools/Makefile.am @@ -8,11 +8,11 @@ bin_PROGRAMS = ikslint iksroster iksperf noinst_HEADERS = perf.h -ikslint_LDADD = $(top_builddir)/src/libiksemel.la +ikslint_LDADD = $(top_builddir)/src/libiksemel.la @SUNCFLAGS@ ikslint_SOURCES = ikslint.c hash.c -iksroster_LDADD = $(top_builddir)/src/libiksemel.la +iksroster_LDADD = $(top_builddir)/src/libiksemel.la @SUNCFLAGS@ iksroster_SOURCES = iksroster.c -iksperf_LDADD = $(top_builddir)/src/libiksemel.la +iksperf_LDADD = $(top_builddir)/src/libiksemel.la @SUNCFLAGS@ iksperf_SOURCES = iksperf.c perf.c From 0d098a5110e095bb9334196978289e081d5a022b Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 24 Jan 2011 21:42:54 -0600 Subject: [PATCH 045/245] revert till right solution found --- w32/Setup/Product.wxs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/w32/Setup/Product.wxs b/w32/Setup/Product.wxs index 1de2ec204d..2f072aa8ca 100644 --- a/w32/Setup/Product.wxs +++ b/w32/Setup/Product.wxs @@ -57,9 +57,6 @@ WorkingDirectory="INSTALLLOCATION"/> - - - - - - From 9509befbfa43810dcde11532663561838d267f2c Mon Sep 17 00:00:00 2001 From: cypromis Date: Tue, 25 Jan 2011 04:54:33 +0100 Subject: [PATCH 046/245] more sun fixes to libiksemel. --- libs/iksemel/configure.ac | 10 +++++++--- libs/iksemel/src/Makefile.am | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/libs/iksemel/configure.ac b/libs/iksemel/configure.ac index e00af1fb99..49d8621777 100644 --- a/libs/iksemel/configure.ac +++ b/libs/iksemel/configure.ac @@ -83,9 +83,13 @@ AC_ARG_ENABLE(64, if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then if test "${enable_64}" = "yes"; then - CFLAGS="$CFLAGS -m64 -lgpg-error" - CXXFLAGS="$CXXFLAGS -m64 -lgpg-error" - SUNFLAGS="-lgpg.error" + CFLAGS="$CFLAGS -xc99=all -mt -m64 -lgpg-error" + CXXFLAGS="$CXXFLAGS -xc99=all -mt -m64 -lgpg-error" + SUNFLAGS="-xc99=all -mt -m64 -lgpg-error" + else + CFLAGS="$CFLAGS -xc99=all -mt -lgpg-error" + CXXFLAGS="$CXXFLAGS -xc99=all -mt -lgpg-error" + SUNFLAGS="-xc99=all -mt -lgpg-error" fi fi diff --git a/libs/iksemel/src/Makefile.am b/libs/iksemel/src/Makefile.am index 20ca2630aa..10236f6deb 100644 --- a/libs/iksemel/src/Makefile.am +++ b/libs/iksemel/src/Makefile.am @@ -25,5 +25,5 @@ libiksemel_la_SOURCES = \ base64.c libiksemel_la_LDFLAGS = -version-info 4:0:1 -no-undefined -libiksemel_la_CFLAGS = $(CFLAGS) $(LIBGNUTLS_CFLAGS) -libiksemel_la_LIBADD = $(LIBGNUTLS_LIBS) +libiksemel_la_CFLAGS = $(CFLAGS) $(LIBGNUTLS_CFLAGS) @SUNCFLAGS@ +libiksemel_la_LIBADD = $(LIBGNUTLS_LIBS) @SUNCFLAGS@ From e78f2bfb5d5f17d0646f0bc2a9fad03546eac646 Mon Sep 17 00:00:00 2001 From: cypromis Date: Tue, 25 Jan 2011 05:24:46 +0100 Subject: [PATCH 047/245] not sure the stuff is needed in the core iksemel. this will take some more teting via hudson and some more comits, but hey, it does not have an impact on anythingbut solaris and derivates --- libs/iksemel/src/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/iksemel/src/Makefile.am b/libs/iksemel/src/Makefile.am index 10236f6deb..9d3da69df2 100644 --- a/libs/iksemel/src/Makefile.am +++ b/libs/iksemel/src/Makefile.am @@ -25,5 +25,5 @@ libiksemel_la_SOURCES = \ base64.c libiksemel_la_LDFLAGS = -version-info 4:0:1 -no-undefined -libiksemel_la_CFLAGS = $(CFLAGS) $(LIBGNUTLS_CFLAGS) @SUNCFLAGS@ -libiksemel_la_LIBADD = $(LIBGNUTLS_LIBS) @SUNCFLAGS@ +libiksemel_la_CFLAGS = $(CFLAGS) $(LIBGNUTLS_CFLAGS) +libiksemel_la_LIBADD = $(LIBGNUTLS_LIBS) From 23b387b7f5f4b13ca40c9d62ab06a04c66810e63 Mon Sep 17 00:00:00 2001 From: cypromis Date: Tue, 25 Jan 2011 05:53:26 +0100 Subject: [PATCH 048/245] antoher try at c options to make iksemel right on solaris --- libs/iksemel/configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/iksemel/configure.ac b/libs/iksemel/configure.ac index 49d8621777..403725a80d 100644 --- a/libs/iksemel/configure.ac +++ b/libs/iksemel/configure.ac @@ -83,12 +83,12 @@ AC_ARG_ENABLE(64, if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then if test "${enable_64}" = "yes"; then - CFLAGS="$CFLAGS -xc99=all -mt -m64 -lgpg-error" - CXXFLAGS="$CXXFLAGS -xc99=all -mt -m64 -lgpg-error" + CFLAGS="$CFLAGS -mt -m64 -lgpg-error" + CXXFLAGS="$CXXFLAGS -mt -m64 -lgpg-error" SUNFLAGS="-xc99=all -mt -m64 -lgpg-error" else - CFLAGS="$CFLAGS -xc99=all -mt -lgpg-error" - CXXFLAGS="$CXXFLAGS -xc99=all -mt -lgpg-error" + CFLAGS="$CFLAGS -mt -lgpg-error" + CXXFLAGS="$CXXFLAGS -mt -lgpg-error" SUNFLAGS="-xc99=all -mt -lgpg-error" fi fi From d164a79764c49dd11bbffcd26d6ca98770181c67 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 25 Jan 2011 11:10:59 -0600 Subject: [PATCH 049/245] add moh by default to uuid_broadcast when only broadcasting to A leg use aleg arg to disable this --- .../applications/mod_commands/mod_commands.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 15ac8ecd2a..1c12e1c0fa 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2389,15 +2389,26 @@ SWITCH_STANDARD_API(uuid_broadcast_function) switch_media_flag_t flags = SMF_NONE; if (argv[2]) { - if (!strcasecmp(argv[2], "both")) { + if (switch_stristr("both", (argv[2]))) { flags |= (SMF_ECHO_ALEG | SMF_ECHO_BLEG); - } else if (!strcasecmp(argv[2], "aleg")) { + } + + if (switch_stristr("aleg", argv[2])) { flags |= SMF_ECHO_ALEG; - } else if (!strcasecmp(argv[2], "bleg")) { + } + + if (switch_stristr("bleg", argv[2])) { + flags &= ~SMF_HOLD_BLEG; flags |= SMF_ECHO_BLEG; } + + if (switch_stristr("holdb", argv[2])) { + flags &= ~SMF_ECHO_BLEG; + flags |= SMF_HOLD_BLEG; + } + } else { - flags |= SMF_ECHO_ALEG; + flags = SMF_ECHO_ALEG | SMF_HOLD_BLEG; } status = switch_ivr_broadcast(argv[0], argv[1], flags); From 28465f38a08df99a76864bbf6a9ae5e4e7bcd720 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 25 Jan 2011 11:12:16 -0600 Subject: [PATCH 050/245] update syntax --- src/mod/applications/mod_commands/mod_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 1c12e1c0fa..7771b0996c 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2372,7 +2372,7 @@ SWITCH_STANDARD_API(uuid_media_function) return SWITCH_STATUS_SUCCESS; } -#define BROADCAST_SYNTAX " [aleg|bleg|both]" +#define BROADCAST_SYNTAX " [aleg|bleg|holdb|both]" SWITCH_STANDARD_API(uuid_broadcast_function) { char *mycmd = NULL, *argv[4] = { 0 }; From 02d1af647bac6b937de02608d53ea1831f51b968 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 25 Jan 2011 11:26:32 -0600 Subject: [PATCH 051/245] use switch_queue_trypop_timeout instead of a timer in mod_loopback to improve audio quality when not using bowout features --- src/mod/endpoints/mod_loopback/mod_loopback.c | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index f875f6b804..aa57668718 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,7 +111,6 @@ 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; @@ -166,15 +165,7 @@ 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); - 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)); - + tech_pvt->read_impl = *tech_pvt->read_codec.implementation; if (!tech_pvt->flag_mutex) { switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); @@ -376,7 +367,6 @@ 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); @@ -568,12 +558,10 @@ 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_trypop(tech_pvt->frame_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { + + if (switch_queue_pop_timeout(tech_pvt->frame_queue, &pop, tech_pvt->read_impl.microseconds_per_packet) == SWITCH_STATUS_SUCCESS && pop) { if (tech_pvt->write_frame) { switch_frame_free(&tech_pvt->write_frame); } @@ -585,6 +573,8 @@ 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; @@ -775,8 +765,6 @@ 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 636c1ecb4e9cace5967390a8a8125fa783f6d0b9 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Tue, 25 Jan 2011 19:19:17 +0100 Subject: [PATCH 052/245] wrap potentially non-threadsafe snmp operations in mutex; support snmpwalk in subagent --- src/mod/event_handlers/mod_snmp/mod_snmp.c | 27 ++-- src/mod/event_handlers/mod_snmp/subagent.c | 144 ++++++++++----------- 2 files changed, 77 insertions(+), 94 deletions(-) diff --git a/src/mod/event_handlers/mod_snmp/mod_snmp.c b/src/mod/event_handlers/mod_snmp/mod_snmp.c index 36a133c805..79ccd165c1 100644 --- a/src/mod/event_handlers/mod_snmp/mod_snmp.c +++ b/src/mod/event_handlers/mod_snmp/mod_snmp.c @@ -38,6 +38,7 @@ static struct { switch_memory_pool_t *pool; + switch_mutex_t *mutex; int shutdown; } globals; @@ -55,27 +56,13 @@ static int snmp_callback_log(int major, int minor, void *serverarg, void *client } -static switch_state_handler_table_t state_handlers = { - /*.on_init */ NULL, - /*.on_routing */ NULL, - /*.on_execute */ NULL, - /*.on_hangup */ NULL, - /*.on_exchange_media */ NULL, - /*.on_soft_execute */ NULL, - /*.on_consume_media */ NULL, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park */ NULL, - /*.on_reporting */ NULL -}; - - static switch_status_t load_config(switch_memory_pool_t *pool) { switch_status_t status = SWITCH_STATUS_SUCCESS; memset(&globals, 0, sizeof(globals)); globals.pool = pool; + switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool); return status; } @@ -87,7 +74,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load) load_config(pool); - switch_core_add_state_handler(&state_handlers); *module_interface = switch_loadable_module_create_module_interface(pool, modname); /* Register callback function so we get Net-SNMP logging handled by FreeSWITCH */ @@ -114,9 +100,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load) SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime) { - while (!globals.shutdown) { + if (!globals.shutdown) { /* Block on select() */ + switch_mutex_lock(globals.mutex); agent_check_and_process(1); + switch_mutex_unlock(globals.mutex); } return SWITCH_STATUS_SUCCESS; @@ -126,9 +114,12 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_snmp_shutdown) { globals.shutdown = 1; - switch_core_remove_state_handler(&state_handlers); + switch_mutex_lock(globals.mutex); snmp_shutdown("mod_snmp"); + switch_mutex_unlock(globals.mutex); + + switch_mutex_destroy(globals.mutex); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c index 8a9f2dac21..ad36624772 100644 --- a/src/mod/event_handlers/mod_snmp/subagent.c +++ b/src/mod/event_handlers/mod_snmp/subagent.c @@ -63,8 +63,8 @@ void init_subagent(void) { DEBUGMSGTL(("init_nstAgentSubagentObject", "Initializing\n")); - netsnmp_register_handler(netsnmp_create_handler_registration("identity", handle_identity, identity_oid, OID_LENGTH(identity_oid), HANDLER_CAN_RONLY)); - netsnmp_register_handler(netsnmp_create_handler_registration("systemStats", handle_systemStats, systemStats_oid, OID_LENGTH(systemStats_oid), HANDLER_CAN_RONLY)); + 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); } @@ -76,33 +76,29 @@ int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration * oid subid; switch(reqinfo->mode) { - case MODE_GET: - for (request = requests; request; request = request->next) { - subid = request->requestvb->name[OID_LENGTH(systemStats_oid)]; + case MODE_GET: + for (request = requests; request; request = request->next) { + subid = request->requestvb->name[reginfo->rootoid_len - 2]; - switch (subid) { - case versionString_oid: - snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &version, strlen(version)); - break; - case uuid_oid: - strncpy(uuid, switch_core_get_uuid(), sizeof(uuid)); - snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &uuid, strlen(uuid)); - break; - default: - snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid); - netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); - } + switch (subid) { + case versionString_oid: + snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &version, strlen(version)); + break; + case uuid_oid: + strncpy(uuid, switch_core_get_uuid(), sizeof(uuid)); + snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &uuid, strlen(uuid)); + break; + default: + snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid); + netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); } - break; + } + break; - case MODE_GETNEXT: - snmp_log(LOG_ERR, "MODE_GETNEXT not supported (yet)\n"); - break; - - default: - /* we should never get here, so this is a really bad error */ - snmp_log(LOG_ERR, "Unknown mode (%d) in handle_versionString\n", reqinfo->mode ); - return SNMP_ERR_GENERR; + default: + /* we should never get here, so this is a really bad error */ + snmp_log(LOG_ERR, "Unknown mode (%d) in handle_identity\n", reqinfo->mode ); + return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; @@ -117,59 +113,55 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio uint32_t int_val; switch(reqinfo->mode) { - case MODE_GET: - for (request = requests; request; request = request->next) { - subid = request->requestvb->name[OID_LENGTH(systemStats_oid)]; + case MODE_GET: + for (request = requests; request; request = request->next) { + subid = request->requestvb->name[reginfo->rootoid_len - 2]; - switch (subid) { - case uptime_oid: - uptime = switch_core_uptime() / 10000; - snmp_set_var_typed_value(requests->requestvb, ASN_TIMETICKS, (u_char *) &uptime, sizeof(uptime)); - break; - case sessionsSinceStartup_oid: - int_val = switch_core_session_id() - 1; - snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, (u_char *) &int_val, sizeof(int_val)); - break; - case currentSessions_oid: - int_val = switch_core_session_count(); - snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); - break; - case maxSessions_oid: - 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 currentCalls_oid: - /* - * 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; - snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); - break; - case sessionsPerSecond_oid: - 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)); - break; - case maxSessionsPerSecond_oid: - switch_core_session_ctl(SCSC_SPS, &int_val); - snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); - break; - default: - snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid); - netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); - } + switch (subid) { + case uptime_oid: + uptime = switch_core_uptime() / 10000; + snmp_set_var_typed_value(requests->requestvb, ASN_TIMETICKS, (u_char *) &uptime, sizeof(uptime)); + break; + case sessionsSinceStartup_oid: + int_val = switch_core_session_id() - 1; + snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, (u_char *) &int_val, sizeof(int_val)); + break; + case currentSessions_oid: + int_val = switch_core_session_count(); + snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + break; + case maxSessions_oid: + 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 currentCalls_oid: + /* + * 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; + snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + break; + case sessionsPerSecond_oid: + 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)); + break; + case maxSessionsPerSecond_oid: + switch_core_session_ctl(SCSC_SPS, &int_val); + snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + break; + default: + snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid); + netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); } - break; + } + break; - case MODE_GETNEXT: - snmp_log(LOG_ERR, "MODE_GETNEXT not supported (yet)\n"); - break; - - default: - /* we should never get here, so this is a really bad error */ - snmp_log(LOG_ERR, "Unknown mode (%d) in handle_systemStats\n", reqinfo->mode); - return SNMP_ERR_GENERR; + default: + /* we should never get here, so this is a really bad error */ + snmp_log(LOG_ERR, "Unknown mode (%d) in handle_systemStats\n", reqinfo->mode); + return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; From 4b731fd64c1bf16a0da20f1c10de8d382faed3a4 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Tue, 25 Jan 2011 20:00:32 +0100 Subject: [PATCH 053/245] tidy up subagent and #defines --- src/mod/event_handlers/mod_snmp/mod_snmp.c | 2 +- src/mod/event_handlers/mod_snmp/subagent.c | 135 +++++++++------------ src/mod/event_handlers/mod_snmp/subagent.h | 14 +++ 3 files changed, 71 insertions(+), 80 deletions(-) diff --git a/src/mod/event_handlers/mod_snmp/mod_snmp.c b/src/mod/event_handlers/mod_snmp/mod_snmp.c index 79ccd165c1..0310637e52 100644 --- a/src/mod/event_handlers/mod_snmp/mod_snmp.c +++ b/src/mod/event_handlers/mod_snmp/mod_snmp.c @@ -101,8 +101,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load) SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime) { if (!globals.shutdown) { - /* Block on select() */ switch_mutex_lock(globals.mutex); + /* Block on select() */ agent_check_and_process(1); switch_mutex_unlock(globals.mutex); } diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c index ad36624772..2da9ebeda6 100644 --- a/src/mod/event_handlers/mod_snmp/subagent.c +++ b/src/mod/event_handlers/mod_snmp/subagent.c @@ -37,31 +37,12 @@ #include "subagent.h" -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 }; - -/* identity sub-IDs - these must match MIB */ -enum { - versionString_oid = 1, - uuid_oid -}; - - -/* systemStats sub-IDs - these must match MIB */ -enum { - uptime_oid = 1, - sessionsSinceStartup_oid, - currentSessions_oid, - maxSessions_oid, - currentCalls_oid, - sessionsPerSecond_oid, - maxSessionsPerSecond_oid -}; - - void init_subagent(void) { - DEBUGMSGTL(("init_nstAgentSubagentObject", "Initializing\n")); + 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); @@ -70,28 +51,26 @@ void init_subagent(void) int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { - static char const version[] = SWITCH_VERSION_FULL; - char uuid[40] = ""; netsnmp_request_info *request = NULL; oid subid; + static char const version[] = SWITCH_VERSION_FULL; + char uuid[40] = ""; switch(reqinfo->mode) { case MODE_GET: - for (request = requests; request; request = request->next) { - subid = request->requestvb->name[reginfo->rootoid_len - 2]; + subid = requests->requestvb->name[reginfo->rootoid_len - 2]; - switch (subid) { - case versionString_oid: - snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &version, strlen(version)); - break; - case uuid_oid: - strncpy(uuid, switch_core_get_uuid(), sizeof(uuid)); - snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &uuid, strlen(uuid)); - break; - default: - snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid); - netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); - } + switch (subid) { + case ID_VERSION_STR: + snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &version, strlen(version)); + break; + case ID_UUID: + strncpy(uuid, switch_core_get_uuid(), sizeof(uuid)); + snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &uuid, strlen(uuid)); + break; + default: + snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid); + netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); } break; @@ -114,47 +93,45 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio switch(reqinfo->mode) { case MODE_GET: - for (request = requests; request; request = request->next) { - subid = request->requestvb->name[reginfo->rootoid_len - 2]; + subid = requests->requestvb->name[reginfo->rootoid_len - 2]; - switch (subid) { - case uptime_oid: - uptime = switch_core_uptime() / 10000; - snmp_set_var_typed_value(requests->requestvb, ASN_TIMETICKS, (u_char *) &uptime, sizeof(uptime)); - break; - case sessionsSinceStartup_oid: - int_val = switch_core_session_id() - 1; - snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, (u_char *) &int_val, sizeof(int_val)); - break; - case currentSessions_oid: - int_val = switch_core_session_count(); - snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); - break; - case maxSessions_oid: - 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 currentCalls_oid: - /* - * 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; - snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); - break; - case sessionsPerSecond_oid: - 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)); - break; - case maxSessionsPerSecond_oid: - switch_core_session_ctl(SCSC_SPS, &int_val); - snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); - break; - default: - snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid); - netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); - } + switch (subid) { + case SS_UPTIME: + uptime = switch_core_uptime() / 10000; + snmp_set_var_typed_value(requests->requestvb, ASN_TIMETICKS, (u_char *) &uptime, sizeof(uptime)); + 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)); + 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)); + 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)); + 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; + snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + 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)); + 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)); + break; + default: + snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid); + netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); } break; diff --git a/src/mod/event_handlers/mod_snmp/subagent.h b/src/mod/event_handlers/mod_snmp/subagent.h index 8a57d8a9f7..72dbeeb426 100644 --- a/src/mod/event_handlers/mod_snmp/subagent.h +++ b/src/mod/event_handlers/mod_snmp/subagent.h @@ -1,6 +1,20 @@ #ifndef subagent_H #define subagent_H +/* .1.3.6.1.4.1.27880.1.1 */ +#define ID_VERSION_STR 1 +#define ID_UUID 2 + +/* .1.3.6.1.4.1.27880.1.2 */ +#define SS_UPTIME 1 +#define SS_SESSIONS_SINCE_STARTUP 2 +#define SS_CURRENT_SESSIONS 3 +#define SS_MAX_SESSIONS 4 +#define SS_CURRENT_CALLS 5 +#define SS_SESSIONS_PER_SECOND 6 +#define SS_MAX_SESSIONS_PER_SECOND 7 + + void init_subagent(void); Netsnmp_Node_Handler handle_identity; Netsnmp_Node_Handler handle_systemStats; From 83d5cd6ff6f2f6e23c09ee387098a59d7764a84f Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Tue, 25 Jan 2011 20:04:29 +0100 Subject: [PATCH 054/245] whoops, tab craziness --- src/mod/event_handlers/mod_snmp/subagent.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mod/event_handlers/mod_snmp/subagent.h b/src/mod/event_handlers/mod_snmp/subagent.h index 72dbeeb426..33153780b5 100644 --- a/src/mod/event_handlers/mod_snmp/subagent.h +++ b/src/mod/event_handlers/mod_snmp/subagent.h @@ -2,15 +2,15 @@ #define subagent_H /* .1.3.6.1.4.1.27880.1.1 */ -#define ID_VERSION_STR 1 -#define ID_UUID 2 +#define ID_VERSION_STR 1 +#define ID_UUID 2 /* .1.3.6.1.4.1.27880.1.2 */ -#define SS_UPTIME 1 +#define SS_UPTIME 1 #define SS_SESSIONS_SINCE_STARTUP 2 -#define SS_CURRENT_SESSIONS 3 -#define SS_MAX_SESSIONS 4 -#define SS_CURRENT_CALLS 5 +#define SS_CURRENT_SESSIONS 3 +#define SS_MAX_SESSIONS 4 +#define SS_CURRENT_CALLS 5 #define SS_SESSIONS_PER_SECOND 6 #define SS_MAX_SESSIONS_PER_SECOND 7 From 7c624767116b30dc9074c1cfbbe7c3a5771950f9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 25 Jan 2011 14:13:15 -0600 Subject: [PATCH 055/245] revert change from 2800ea199d6c233fe0aeee91de3be33dfee19607 and add disconnect packet on listener kill --- .../mod_event_socket/mod_event_socket.c | 68 ++++++++++++------- 1 file changed, 43 insertions(+), 25 deletions(-) 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 344b0ee117..f3a2c92eb3 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 @@ -32,7 +32,7 @@ #include #define CMD_BUFLEN 1024 * 1000 #define MAX_QUEUE_LEN 25000 -#define MAX_MISSED 2000 +#define MAX_MISSED 500 SWITCH_MODULE_LOAD_FUNCTION(mod_event_socket_load); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_event_socket_shutdown); SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime); @@ -143,7 +143,7 @@ static const char *format2str(event_format_t format) } static void remove_listener(listener_t *listener); -static void kill_listener(listener_t *l); +static void kill_listener(listener_t *l, const char *message); static void kill_all_listeners(void); static uint32_t next_id(void) @@ -170,7 +170,7 @@ static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_l if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level) { switch_log_node_t *dnode = switch_log_node_dup(node); - if (switch_queue_push(l->log_queue, dnode) == SWITCH_STATUS_SUCCESS) { + if (switch_queue_trypush(l->log_queue, dnode) == SWITCH_STATUS_SUCCESS) { if (l->lost_logs) { int ll = l->lost_logs; switch_event_t *event; @@ -184,7 +184,7 @@ static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_l } else { switch_log_node_free(&dnode); if (++l->lost_logs > MAX_MISSED) { - kill_listener(l); + kill_listener(l, "Disconnected due to log queue failure.\n"); } } } @@ -366,7 +366,7 @@ static void event_handler(switch_event_t *event) if (send) { if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) { - if (switch_queue_push(l->event_queue, clone) == SWITCH_STATUS_SUCCESS) { + if (switch_queue_trypush(l->event_queue, clone) == SWITCH_STATUS_SUCCESS) { if (l->lost_events) { int le = l->lost_events; l->lost_events = 0; @@ -379,7 +379,7 @@ static void event_handler(switch_event_t *event) } } else { if (++l->lost_events > MAX_MISSED) { - kill_listener(l); + kill_listener(l, "Disconnected due to event queue failure.\n"); } switch_event_destroy(&clone); } @@ -579,8 +579,41 @@ static void remove_listener(listener_t *listener) switch_mutex_unlock(globals.listener_mutex); } -static void kill_listener(listener_t *l) +static void send_disconnect(listener_t *listener, const char *message) { + + char disco_buf[512] = ""; + switch_size_t len, mlen; + + if (zstr(message)) { + message = "Disconnected.\n"; + } + + mlen = strlen(message); + + if (listener->session) { + switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\n" + "Controlled-Session-UUID: %s\n" + "Content-Disposition: disconnect\n" "Content-Length: %d\n\n", switch_core_session_get_uuid(listener->session), mlen); + } else { + switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\nContent-Length: %d\n\n", mlen); + } + + len = strlen(disco_buf); + switch_socket_send(listener->sock, disco_buf, &len); + if (len > 0) { + len = mlen; + switch_socket_send(listener->sock, message, &len); + } +} + +static void kill_listener(listener_t *l, const char *message) +{ + + if (message) { + send_disconnect(l, message); + } + switch_clear_flag(l, LFLAG_RUNNING); if (l->sock) { switch_socket_shutdown(l->sock, SWITCH_SHUTDOWN_READWRITE); @@ -595,7 +628,7 @@ static void kill_all_listeners(void) switch_mutex_lock(globals.listener_mutex); for (l = listen_list.listeners; l; l = l->next) { - kill_listener(l); + kill_listener(l, "The system is being shut down.\n"); } switch_mutex_unlock(globals.listener_mutex); } @@ -1233,7 +1266,7 @@ static switch_status_t read_packet(listener_t *listener, switch_event_t **event, if (switch_channel_get_state(chan) < CS_HANGUP && switch_channel_test_flag(chan, CF_DIVERT_EVENTS)) { switch_event_t *e = NULL; while (switch_core_session_dequeue_event(listener->session, &e, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { - if (switch_queue_push(listener->event_queue, e) != SWITCH_STATUS_SUCCESS) { + if (switch_queue_trypush(listener->event_queue, e) != SWITCH_STATUS_SUCCESS) { switch_core_session_queue_event(listener->session, &e); break; } @@ -2540,22 +2573,7 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj) } if (listener->sock) { - char disco_buf[512] = ""; - const char message[] = "Disconnected, goodbye.\nSee you at ClueCon! http://www.cluecon.com/\n"; - int mlen = strlen(message); - - if (listener->session) { - switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\n" - "Controlled-Session-UUID: %s\n" - "Content-Disposition: disconnect\n" "Content-Length: %d\n\n", switch_core_session_get_uuid(listener->session), mlen); - } else { - switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\nContent-Length: %d\n\n", mlen); - } - - len = strlen(disco_buf); - switch_socket_send(listener->sock, disco_buf, &len); - len = mlen; - switch_socket_send(listener->sock, message, &len); + send_disconnect(listener, "Disconnected, goodbye.\nSee you at ClueCon! http://www.cluecon.com/\n"); close_socket(&listener->sock); } From 0e0431ecc66d04236cf4940b65977bad424fdc86 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Wed, 26 Jan 2011 20:05:16 +0100 Subject: [PATCH 056/245] update mod_sofia management interface OID --- 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 eb5e2ad1ae..6c91ce1274 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -4850,7 +4850,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) sofia_endpoint_interface->state_handler = &sofia_event_handlers; management_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_MANAGEMENT_INTERFACE); - management_interface->relative_oid = "1"; + management_interface->relative_oid = "1001"; management_interface->management_function = sofia_manage; SWITCH_ADD_API(api_interface, "sofia", "Sofia Controls", sofia_function, " "); From 15e65cfafb8a46caca8bb8a63d55edf817f17f2d Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 26 Jan 2011 14:40:35 -0600 Subject: [PATCH 057/245] 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 6f58e6aa425283137effa286d7f8638aa035aff4 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 26 Jan 2011 15:19:28 -0600 Subject: [PATCH 058/245] FS-2771 --- .../mod_conference/mod_conference.c | 60 ++++++++++++++----- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 472f2d986c..12b3193363 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -152,7 +152,8 @@ typedef enum { CFLAG_BRIDGE_TO = (1 << 6), CFLAG_WAIT_MOD = (1 << 7), CFLAG_VID_FLOOR = (1 << 8), - CFLAG_WASTE_BANDWIDTH = (1 << 9) + CFLAG_WASTE_BANDWIDTH = (1 << 9), + CFLAG_OUTCALL = (1 << 10) } conf_flag_t; typedef enum { @@ -288,6 +289,8 @@ typedef struct conference_obj { uint32_t avg_tally; switch_time_t run_time; char *uuid_str; + uint32_t originating; + switch_call_cause_t cancel_cause; } conference_obj_t; /* Relationship with another member */ @@ -395,11 +398,16 @@ SWITCH_STANDARD_API(conf_api_main); static switch_status_t conference_outcall(conference_obj_t *conference, char *conference_name, switch_core_session_t *session, - char *bridgeto, uint32_t timeout, char *flags, char *cid_name, char *cid_num, switch_call_cause_t *cause); + char *bridgeto, uint32_t timeout, + char *flags, + char *cid_name, + char *cid_num, + switch_call_cause_t *cause, + switch_call_cause_t *cancel_cause); static switch_status_t conference_outcall_bg(conference_obj_t *conference, char *conference_name, switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name, - const char *cid_num, const char *call_uuid); + const char *cid_num, const char *call_uuid, switch_call_cause_t *cancel_cause); SWITCH_STANDARD_APP(conference_function); static void launch_conference_thread(conference_obj_t *conference); static void launch_conference_video_thread(conference_obj_t *conference); @@ -1381,6 +1389,14 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v /* Rinse ... Repeat */ end: + if (switch_test_flag(conference, CFLAG_OUTCALL)) { + conference->cancel_cause = SWITCH_CAUSE_ORIGINATOR_CANCEL; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Ending pending outcall channels for Conference: '%s'\n", conference->name); + while(conference->originating) { + switch_yield(200000); + } + } + if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", conference->name); @@ -2404,6 +2420,8 @@ static void conference_loop_output(conference_member_t *member) switch_channel_set_private(channel, "_conference_autocall_list_", NULL); + switch_set_flag(member->conference, CFLAG_OUTCALL); + if (toval) { to = atoi(toval); if (to < 10 || to > 500) { @@ -2422,7 +2440,8 @@ static void conference_loop_output(conference_member_t *member) for (x = 0; x < argc; x++) { char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]); switch_assert(dial_str); - conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num, NULL); + conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num, NULL, + &member->conference->cancel_cause); switch_safe_free(dial_str); } switch_safe_free(cpstr); @@ -4244,9 +4263,9 @@ static switch_status_t conf_api_sub_dial(conference_obj_t *conference, switch_st } if (conference) { - conference_outcall(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], &cause); + conference_outcall(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], &cause, NULL); } else { - conference_outcall(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], &cause); + conference_outcall(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], &cause, NULL); } stream->write_function(stream, "Call Requested: result: [%s]\n", switch_channel_cause2str(cause)); @@ -4269,9 +4288,9 @@ static switch_status_t conf_api_sub_bgdial(conference_obj_t *conference, switch_ switch_uuid_format(uuid_str, &uuid); if (conference) { - conference_outcall_bg(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str); + conference_outcall_bg(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str, NULL); } else { - conference_outcall_bg(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str); + conference_outcall_bg(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str, NULL); } stream->write_function(stream, "OK Job-UUID: %s\n", uuid_str); @@ -4785,7 +4804,11 @@ SWITCH_STANDARD_API(conf_api_main) static switch_status_t conference_outcall(conference_obj_t *conference, char *conference_name, switch_core_session_t *session, - char *bridgeto, uint32_t timeout, char *flags, char *cid_name, char *cid_num, switch_call_cause_t *cause) + char *bridgeto, uint32_t timeout, + char *flags, char *cid_name, + char *cid_num, + switch_call_cause_t *cause, + switch_call_cause_t *cancel_cause) { switch_core_session_t *peer_session = NULL; switch_channel_t *peer_channel; @@ -4831,8 +4854,15 @@ static switch_status_t conference_outcall(conference_obj_t *conference, /* establish an outbound call leg */ - if (switch_ivr_originate(session, &peer_session, cause, bridgeto, timeout, NULL, cid_name, cid_num, NULL, NULL, SOF_NO_LIMITS, NULL) != - SWITCH_STATUS_SUCCESS) { + switch_mutex_lock(conference->mutex); + conference->originating++; + switch_mutex_unlock(conference->mutex); + status = switch_ivr_originate(session, &peer_session, cause, bridgeto, timeout, NULL, cid_name, cid_num, NULL, NULL, SOF_NO_LIMITS, cancel_cause); + switch_mutex_lock(conference->mutex); + conference->originating--; + switch_mutex_unlock(conference->mutex); + + if (status != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot create outgoing channel, cause: %s\n", switch_channel_cause2str(*cause)); if (caller_channel) { @@ -4909,6 +4939,7 @@ struct bg_call { char *cid_num; char *conference_name; char *uuid; + switch_call_cause_t *cancel_cause; switch_memory_pool_t *pool; }; @@ -4921,7 +4952,7 @@ static void *SWITCH_THREAD_FUNC conference_outcall_run(switch_thread_t *thread, switch_event_t *event; conference_outcall(call->conference, call->conference_name, - call->session, call->bridgeto, call->timeout, call->flags, call->cid_name, call->cid_num, &cause); + call->session, call->bridgeto, call->timeout, call->flags, call->cid_name, call->cid_num, &cause, call->cancel_cause); if (call->conference && test_eflag(call->conference, EFLAG_BGDIAL_RESULT) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { @@ -4949,7 +4980,7 @@ static void *SWITCH_THREAD_FUNC conference_outcall_run(switch_thread_t *thread, static switch_status_t conference_outcall_bg(conference_obj_t *conference, char *conference_name, switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name, - const char *cid_num, const char *call_uuid) + const char *cid_num, const char *call_uuid, switch_call_cause_t *cancel_cause) { struct bg_call *call = NULL; switch_thread_t *thread; @@ -4963,6 +4994,7 @@ static switch_status_t conference_outcall_bg(conference_obj_t *conference, call->conference = conference; call->session = session; call->timeout = timeout; + call->cancel_cause = cancel_cause; if (conference) { pool = conference->pool; @@ -5717,7 +5749,7 @@ SWITCH_STANDARD_APP(conference_function) /* if we're using "bridge:" make an outbound call and bridge it in */ if (!zstr(bridgeto) && strcasecmp(bridgeto, "none")) { switch_call_cause_t cause; - if (conference_outcall(conference, NULL, session, bridgeto, 60, NULL, NULL, NULL, &cause) != SWITCH_STATUS_SUCCESS) { + if (conference_outcall(conference, NULL, session, bridgeto, 60, NULL, NULL, NULL, &cause, NULL) != SWITCH_STATUS_SUCCESS) { goto done; } } else { From 9ffca057f109725986b741cb6019dce620c056b7 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 26 Jan 2011 17:24:25 -0500 Subject: [PATCH 059/245] chlog: freetdm - isdn: fix for not including some bearer-cap contents on BRI --- .../ftmod_sangoma_isdn_support.c | 54 +++++++++---------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index 64147b7d75..23fe08b983 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -873,38 +873,32 @@ ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap) bearCap->tranMode.pres = PRSNT_NODEF; bearCap->tranMode.val = IN_TM_CIRCUIT; - if (!FTDM_SPAN_IS_BRI(ftdmchan->span)) { - /* Trillium stack rejests lyr1Ident on BRI, but Netbricks always sends it. - Check with Trillium if this ever causes calls to fail in the field */ + bearCap->usrInfoLyr1Prot.pres = PRSNT_NODEF; + bearCap->usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1); - /* PRI only params */ - bearCap->usrInfoLyr1Prot.pres = PRSNT_NODEF; - bearCap->usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1); - - switch (signal_data->switchtype) { - case SNGISDN_SWITCH_NI2: - case SNGISDN_SWITCH_4ESS: - case SNGISDN_SWITCH_5ESS: - case SNGISDN_SWITCH_DMS100: - case SNGISDN_SWITCH_INSNET: - if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Overriding bearer cap to u-law\n"); - bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW; - } - break; - case SNGISDN_SWITCH_EUROISDN: - case SNGISDN_SWITCH_QSIG: - if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Overriding bearer cap to a-law\n"); - bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW; - } - break; - } - - - bearCap->lyr1Ident.pres = PRSNT_NODEF; - bearCap->lyr1Ident.val = IN_L1_IDENT; + switch (signal_data->switchtype) { + case SNGISDN_SWITCH_NI2: + case SNGISDN_SWITCH_4ESS: + case SNGISDN_SWITCH_5ESS: + case SNGISDN_SWITCH_DMS100: + case SNGISDN_SWITCH_INSNET: + if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Overriding bearer cap to u-law\n"); + bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW; + } + break; + case SNGISDN_SWITCH_EUROISDN: + case SNGISDN_SWITCH_QSIG: + if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Overriding bearer cap to a-law\n"); + bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW; + } + break; } + + bearCap->lyr1Ident.pres = PRSNT_NODEF; + bearCap->lyr1Ident.val = IN_L1_IDENT; + return FTDM_SUCCESS; } From a01814794c1fb49b77a6015edc8e1ad6c925bae3 Mon Sep 17 00:00:00 2001 From: Leon de Rooij Date: Thu, 27 Jan 2011 13:10:26 +0100 Subject: [PATCH 060/245] Added optional core: prefix to first arg passed to freeswitch.Dbh for giving direct access to sqlite db --- src/mod/languages/mod_lua/freeswitch_lua.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp index 1a170dcc98..01f708d66a 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.cpp +++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp @@ -312,15 +312,21 @@ switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t ityp Dbh::Dbh(char *dsn, char *user, char *pass) { switch_cache_db_connection_options_t options = { {0} }; + const char *prefix = "core:"; + m_connected = false; - options.odbc_options.dsn = dsn; - options.odbc_options.user = user; - options.odbc_options.pass = pass; - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) == SWITCH_STATUS_SUCCESS) { - m_connected = true; + if (strstr(dsn, prefix) == dsn) { + options.core_db_options.db_path = &dsn[strlen(prefix)]; + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) == SWITCH_STATUS_SUCCESS) { + m_connected = true; + } } else { - m_connected = false; + options.odbc_options.dsn = dsn; + options.odbc_options.user = user; + options.odbc_options.pass = pass; + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) == SWITCH_STATUS_SUCCESS) { + m_connected = true; + } } } From 425df0c78389d30561a7f025a1a3e3b2fbc5e413 Mon Sep 17 00:00:00 2001 From: Leon de Rooij Date: Thu, 27 Jan 2011 14:17:49 +0100 Subject: [PATCH 061/245] Added test_reactive to mod_lua freeswitch.Dbh --- src/mod/languages/mod_lua/freeswitch.i | 1 + src/mod/languages/mod_lua/freeswitch_lua.cpp | 10 ++ src/mod/languages/mod_lua/freeswitch_lua.h | 1 + src/mod/languages/mod_lua/mod_lua_wrap.cpp | 179 +++++++++++++++++++ 4 files changed, 191 insertions(+) diff --git a/src/mod/languages/mod_lua/freeswitch.i b/src/mod/languages/mod_lua/freeswitch.i index 9ccaf8ea9f..25faa5a5df 100644 --- a/src/mod/languages/mod_lua/freeswitch.i +++ b/src/mod/languages/mod_lua/freeswitch.i @@ -89,6 +89,7 @@ class Dbh { ~Dbh(); bool release(); bool connected(); + bool test_reactive(char *test_sql, char *drop_sql = NULL, char *reactive_sql = NULL); bool query(char *sql, SWIGLUA_FN lua_fun); int affected_rows(); }; diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp index 01f708d66a..b388f2e491 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.cpp +++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp @@ -350,6 +350,16 @@ bool Dbh::connected() return m_connected; } +bool Dbh::test_reactive(char *test_sql, char *drop_sql, char *reactive_sql) +{ + if (m_connected) { + if (switch_cache_db_test_reactive(dbh, test_sql, drop_sql, reactive_sql) == SWITCH_TRUE) { + return true; + } + } + return false; +} + int Dbh::query_callback(void *pArg, int argc, char **argv, char **cargv) { SWIGLUA_FN *lua_fun = (SWIGLUA_FN *)pArg; diff --git a/src/mod/languages/mod_lua/freeswitch_lua.h b/src/mod/languages/mod_lua/freeswitch_lua.h index 5f7966266c..6411d69697 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.h +++ b/src/mod/languages/mod_lua/freeswitch_lua.h @@ -62,6 +62,7 @@ namespace LUA { ~Dbh(); bool release(); bool connected(); + bool test_reactive(char *test_sql, char *drop_sql = NULL, char *reactive_sql = NULL); bool query(char *sql, SWIGLUA_FN lua_fun); int affected_rows(); }; diff --git a/src/mod/languages/mod_lua/mod_lua_wrap.cpp b/src/mod/languages/mod_lua/mod_lua_wrap.cpp index f10ed63fca..1d84a39fd5 100644 --- a/src/mod/languages/mod_lua/mod_lua_wrap.cpp +++ b/src/mod/languages/mod_lua/mod_lua_wrap.cpp @@ -7254,6 +7254,184 @@ fail: } +static int _wrap_Dbh_test_reactive__SWIG_0(lua_State* L) { + int SWIG_arg = -1; + LUA::Dbh *arg1 = (LUA::Dbh *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + char *arg4 = (char *) 0 ; + bool result; + + SWIG_check_num_args("test_reactive",4,4) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("test_reactive",1,"LUA::Dbh *"); + if(!lua_isstring(L,2)) SWIG_fail_arg("test_reactive",2,"char *"); + if(!lua_isstring(L,3)) SWIG_fail_arg("test_reactive",3,"char *"); + if(!lua_isstring(L,4)) SWIG_fail_arg("test_reactive",4,"char *"); + + if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_LUA__Dbh,0))){ + SWIG_fail_ptr("Dbh_test_reactive",1,SWIGTYPE_p_LUA__Dbh); + } + + arg2 = (char *)lua_tostring(L, 2); + arg3 = (char *)lua_tostring(L, 3); + arg4 = (char *)lua_tostring(L, 4); + result = (bool)(arg1)->test_reactive(arg2,arg3,arg4); + 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_Dbh_test_reactive__SWIG_1(lua_State* L) { + int SWIG_arg = -1; + LUA::Dbh *arg1 = (LUA::Dbh *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + bool result; + + SWIG_check_num_args("test_reactive",3,3) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("test_reactive",1,"LUA::Dbh *"); + if(!lua_isstring(L,2)) SWIG_fail_arg("test_reactive",2,"char *"); + if(!lua_isstring(L,3)) SWIG_fail_arg("test_reactive",3,"char *"); + + if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_LUA__Dbh,0))){ + SWIG_fail_ptr("Dbh_test_reactive",1,SWIGTYPE_p_LUA__Dbh); + } + + arg2 = (char *)lua_tostring(L, 2); + arg3 = (char *)lua_tostring(L, 3); + result = (bool)(arg1)->test_reactive(arg2,arg3); + 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_Dbh_test_reactive__SWIG_2(lua_State* L) { + int SWIG_arg = -1; + LUA::Dbh *arg1 = (LUA::Dbh *) 0 ; + char *arg2 = (char *) 0 ; + bool result; + + SWIG_check_num_args("test_reactive",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("test_reactive",1,"LUA::Dbh *"); + if(!lua_isstring(L,2)) SWIG_fail_arg("test_reactive",2,"char *"); + + if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_LUA__Dbh,0))){ + SWIG_fail_ptr("Dbh_test_reactive",1,SWIGTYPE_p_LUA__Dbh); + } + + arg2 = (char *)lua_tostring(L, 2); + result = (bool)(arg1)->test_reactive(arg2); + 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_Dbh_test_reactive(lua_State* L) { + int argc; + int argv[5]={ + 1,2,3,4,5 + }; + + argc = lua_gettop(L); + if (argc == 2) { + int _v; + { + void *ptr; + if (SWIG_isptrtype(L,argv[0])==0 || SWIG_ConvertPtr(L,argv[0], (void **) &ptr, SWIGTYPE_p_LUA__Dbh, 0)) { + _v = 0; + } else { + _v = 1; + } + } + if (_v) { + { + _v = lua_isstring(L,argv[1]); + } + if (_v) { + return _wrap_Dbh_test_reactive__SWIG_2(L); + } + } + } + if (argc == 3) { + int _v; + { + void *ptr; + if (SWIG_isptrtype(L,argv[0])==0 || SWIG_ConvertPtr(L,argv[0], (void **) &ptr, SWIGTYPE_p_LUA__Dbh, 0)) { + _v = 0; + } else { + _v = 1; + } + } + if (_v) { + { + _v = lua_isstring(L,argv[1]); + } + if (_v) { + { + _v = lua_isstring(L,argv[2]); + } + if (_v) { + return _wrap_Dbh_test_reactive__SWIG_1(L); + } + } + } + } + if (argc == 4) { + int _v; + { + void *ptr; + if (SWIG_isptrtype(L,argv[0])==0 || SWIG_ConvertPtr(L,argv[0], (void **) &ptr, SWIGTYPE_p_LUA__Dbh, 0)) { + _v = 0; + } else { + _v = 1; + } + } + if (_v) { + { + _v = lua_isstring(L,argv[1]); + } + if (_v) { + { + _v = lua_isstring(L,argv[2]); + } + if (_v) { + { + _v = lua_isstring(L,argv[3]); + } + if (_v) { + return _wrap_Dbh_test_reactive__SWIG_0(L); + } + } + } + } + } + + lua_pushstring(L,"No matching function for overloaded 'Dbh_test_reactive'"); + lua_error(L);return 0; +} + + static int _wrap_Dbh_query(lua_State* L) { int SWIG_arg = -1; LUA::Dbh *arg1 = (LUA::Dbh *) 0 ; @@ -7328,6 +7506,7 @@ delete arg1; static swig_lua_method swig_LUA_Dbh_methods[] = { {"release", _wrap_Dbh_release}, {"connected", _wrap_Dbh_connected}, + {"test_reactive", _wrap_Dbh_test_reactive}, {"query", _wrap_Dbh_query}, {"affected_rows", _wrap_Dbh_affected_rows}, {0,0} From 008e527c0f5c86e20521c4ebacf69adcb269b08a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 27 Jan 2011 08:18:22 -0600 Subject: [PATCH 062/245] FS-3012 --- src/mod/endpoints/mod_sofia/sofia.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 643b3dd814..47f94b151a 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -808,6 +808,18 @@ void sofia_event_callback(nua_event_t event, } } + if ((event == nua_i_invite) && (!session)) { + uint32_t sess_count = switch_core_session_count(); + uint32_t sess_max = switch_core_session_limit(0); + + if (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING) || !switch_core_ready()) { + nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END()); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No more sessions allowed at this time.\n"); + + goto done; + } + } if (sofia_test_pflag(profile, PFLAG_AUTH_ALL) && tech_pvt && tech_pvt->key && sip) { sip_authorization_t const *authorization = NULL; From 22c05ad542e3a36dd7dbb71bef5aca5ff009b1b9 Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 27 Jan 2011 09:41:18 -0600 Subject: [PATCH 063/245] fixes from tony --- scripts/perl/dhcp-inform.pl | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/scripts/perl/dhcp-inform.pl b/scripts/perl/dhcp-inform.pl index 3f977ca58b..2ca4bb8732 100644 --- a/scripts/perl/dhcp-inform.pl +++ b/scripts/perl/dhcp-inform.pl @@ -61,12 +61,7 @@ while ($sock->recv($newmsg, 1024)) { } print "Sending option 66 as $opt_u\n"; - $handle = IO::Socket::INET->new(Proto => 'udp', - PeerPort => '68', - LocalPort => '67', - ReuseAddr => 1, - PeerAddr => $dhcpreq->ciaddr(), - ) or die "socket: $@"; - $handle->send($dhcpresp->serialize()) + + $sock->send($dhcpresp->serialize()) } } From b889b44f1d632810662359f6becce869056a076c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 27 Jan 2011 10:28:49 -0600 Subject: [PATCH 064/245] add channel data to speech events when chosen to fire --- src/switch_ivr_async.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 4354f0dc0d..0a646b6d6e 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -3129,6 +3129,7 @@ static void *SWITCH_THREAD_FUNC speech_thread(switch_thread_t *thread, void *obj switch_event_t *dup; if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(channel, dup); switch_event_fire(&dup); } From 4b941542a309a8c7f7ad5d01cfef9d1c487376a8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 27 Jan 2011 10:34:05 -0600 Subject: [PATCH 065/245] fix out of place parens in logic test --- src/switch_channel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_channel.c b/src/switch_channel.c index 918ad82a99..de472a91d5 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2564,8 +2564,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_ring_ready_value(swi char *app; switch_event_t *event; - if (!switch_channel_test_flag(channel, CF_RING_READY) && !switch_channel_test_flag(channel, CF_EARLY_MEDIA && - !switch_channel_test_flag(channel, CF_ANSWERED))) { + if (!switch_channel_test_flag(channel, CF_RING_READY) && + !switch_channel_test_flag(channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(channel, CF_ANSWERED)) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_NOTICE, "Ring-Ready %s!\n", channel->name); switch_channel_set_flag_value(channel, CF_RING_READY, rv); if (channel->caller_profile && channel->caller_profile->times) { From 1388ed811a2369b26778c4cce158691f285c45b4 Mon Sep 17 00:00:00 2001 From: Leon de Rooij Date: Thu, 27 Jan 2011 18:52:14 +0100 Subject: [PATCH 066/245] 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 067/245] 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 608be370bcca24023ee9d05ee4a99c133044f0d3 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Thu, 27 Jan 2011 21:33:17 +0100 Subject: [PATCH 068/245] reduce agentx heartbeat to 2s, add management hook for mutex lock/unlock --- src/mod/event_handlers/mod_snmp/mod_snmp.c | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_snmp/mod_snmp.c b/src/mod/event_handlers/mod_snmp/mod_snmp.c index 0310637e52..56c7be1ef6 100644 --- a/src/mod/event_handlers/mod_snmp/mod_snmp.c +++ b/src/mod/event_handlers/mod_snmp/mod_snmp.c @@ -48,6 +48,20 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime); SWITCH_MODULE_DEFINITION(mod_snmp, mod_snmp_load, mod_snmp_shutdown, mod_snmp_runtime); +static switch_status_t snmp_manage(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen) +{ + if (action == SMA_GET) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Mutex lock request from relative OID %s.\n", relative_oid); + switch_mutex_lock(globals.mutex); + } else if (action == SMA_SET) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Mutex unlock request from relative OID %s.\n", relative_oid); + switch_mutex_unlock(globals.mutex); + } + + return SWITCH_STATUS_SUCCESS; +} + + static int snmp_callback_log(int major, int minor, void *serverarg, void *clientarg) { struct snmp_log_message *slm = (struct snmp_log_message *) serverarg; @@ -71,10 +85,14 @@ static switch_status_t load_config(switch_memory_pool_t *pool) SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load) { switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_management_interface_t *management_interface; load_config(pool); *module_interface = switch_loadable_module_create_module_interface(pool, modname); + management_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_MANAGEMENT_INTERFACE); + management_interface->relative_oid = "1000"; + management_interface->management_function = snmp_manage; /* Register callback function so we get Net-SNMP logging handled by FreeSWITCH */ snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_LOGGING, snmp_callback_log, NULL); @@ -86,10 +104,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load) init_agent("mod_snmp"); /* - * Override master/subagent ping interval to 5s, to ensure that + * Override master/subagent ping interval to 2s, to ensure that * agent_check_and_process() never blocks for longer than that. */ - netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL, 5); + netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL, 2); init_subagent(); init_snmp("mod_snmp"); @@ -107,6 +125,8 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime) switch_mutex_unlock(globals.mutex); } + switch_yield(5000); + return SWITCH_STATUS_SUCCESS; } From f8254f81607c9b2fe8ece3c48cb6dff700bcbead Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Thu, 27 Jan 2011 16:24:11 -0500 Subject: [PATCH 069/245] test --- build/modules.conf.in | 1 + 1 file changed, 1 insertion(+) diff --git a/build/modules.conf.in b/build/modules.conf.in index 84a9e9a74d..b46c2ff398 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -112,3 +112,4 @@ say/mod_say_ru ## Experimental Modules (don't cry if they're broken) #../../contrib/mod/xml_int/mod_xml_odbc + From e1c17cffe0bfbf7c50a02acc9384679ef283a96b Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 27 Jan 2011 16:36:45 -0500 Subject: [PATCH 070/245] freetdm: use the problem freetdm define to set wp alarms --- libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 2 +- libs/freetdm/src/include/freetdm.h | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index 3b384cdf32..b3d1fe6355 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -1242,7 +1242,7 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms) /* there is a bug in wanpipe where alarms were not properly set when they should be * on at application startup, until that is fixed we check the link status here too */ ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_LINK_STATUS, &sangoma_status); - ftdmchan->alarm_flags = sangoma_status == FTDM_HW_LINK_DISCONNECTED ? 1 : 0; + ftdmchan->alarm_flags = sangoma_status == FTDM_HW_LINK_DISCONNECTED ? FTDM_ALARM_RED : FTDM_ALARM_NONE; ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Link status is %d\n", sangoma_status); } } diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index aed40541a3..588dc311b6 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -838,11 +838,11 @@ typedef enum { /*! \brief FreeTDM supported hardware alarms. */ typedef enum { FTDM_ALARM_NONE = 0, - FTDM_ALARM_RED = (1 << 1), - FTDM_ALARM_YELLOW = (1 << 2), - FTDM_ALARM_RAI = (1 << 3), - FTDM_ALARM_BLUE = (1 << 4), - FTDM_ALARM_AIS = (1 << 5), + FTDM_ALARM_RED = (1 << 0), + FTDM_ALARM_YELLOW = (1 << 1), + FTDM_ALARM_RAI = (1 << 2), + FTDM_ALARM_BLUE = (1 << 3), + FTDM_ALARM_AIS = (1 << 4), FTDM_ALARM_GENERAL = (1 << 30) } ftdm_alarm_flag_t; From 48c02b7cd2770f6aee1d6e89f5ecfe207231f398 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Thu, 27 Jan 2011 16:49:09 -0500 Subject: [PATCH 071/245] test --- build/modules.conf.in | 1 - 1 file changed, 1 deletion(-) diff --git a/build/modules.conf.in b/build/modules.conf.in index b46c2ff398..84a9e9a74d 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -112,4 +112,3 @@ say/mod_say_ru ## Experimental Modules (don't cry if they're broken) #../../contrib/mod/xml_int/mod_xml_odbc - From 314a2a1e2061ef321fa5f9b32a9c70ef0040cdb8 Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 27 Jan 2011 10:40:49 -0600 Subject: [PATCH 072/245] FS-3004 --- .../mod_spandsp/mod_spandsp_fax.c | 89 +++++++++++-------- 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index 21c6a68a0e..4dd936b8c6 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -40,6 +40,9 @@ #define MAX_FEC_ENTRIES 4 #define MAX_FEC_SPAN 4 +#define SPANDSP_EVENT_TXFAXRESULT "spandsp::txfaxresult" +#define SPANDSP_EVENT_RXFAXRESULT "spandsp::rxfaxresult" + /***************************************************************************** OUR DEFINES AND STRUCTS *****************************************************************************/ @@ -305,7 +308,14 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result) switch_core_session_t *session; switch_channel_t *channel; pvt_t *pvt; - char *tmp; + char *fax_document_transferred_pages = NULL; + char *fax_document_total_pages = NULL; + char *fax_image_resolution = NULL; + char *fax_image_size = NULL; + char *fax_bad_rows = NULL; + char *fax_transfer_rate = NULL; + char *fax_result_code = NULL; + switch_event_t *event; pvt = (pvt_t *) user_data; switch_assert(pvt); @@ -353,13 +363,12 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "==============================================================================\n"); /* - Set our channel variables + Set our channel variables, variables are also used in event */ - tmp = switch_mprintf("%i", result); - if (tmp) { - switch_channel_set_variable(channel, "fax_result_code", tmp); - switch_safe_free(tmp); + fax_result_code = switch_core_session_sprintf(session, "%i", result); + if (fax_result_code) { + switch_channel_set_variable(channel, "fax_result_code", fax_result_code); } switch_channel_set_variable(channel, "fax_result_text", t30_completion_code_to_str(result)); @@ -368,49 +377,56 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result) switch_channel_set_variable(channel, "fax_local_station_id", local_ident); switch_channel_set_variable(channel, "fax_remote_station_id", far_ident); - tmp = switch_mprintf("%i", pvt->app_mode == FUNCTION_TX ? t.pages_tx : t.pages_rx); - if (tmp) { - switch_channel_set_variable(channel, "fax_document_transferred_pages", tmp); - switch_safe_free(tmp); + fax_document_transferred_pages = switch_core_session_sprintf(session, "%i", pvt->app_mode == FUNCTION_TX ? t.pages_tx : t.pages_rx); + if (fax_document_transferred_pages) { + switch_channel_set_variable(channel, "fax_document_transferred_pages", fax_document_transferred_pages); } - tmp = switch_mprintf("%i", t.pages_in_file); - if (tmp) { - switch_channel_set_variable(channel, "fax_document_total_pages", tmp); - switch_safe_free(tmp); + fax_document_total_pages = switch_core_session_sprintf(session, "%i", t.pages_in_file); + if (fax_document_total_pages) { + switch_channel_set_variable(channel, "fax_document_total_pages", fax_document_total_pages); } - tmp = switch_mprintf("%ix%i", t.x_resolution, t.y_resolution); - if (tmp) { - switch_channel_set_variable(channel, "fax_image_resolution", tmp); - switch_safe_free(tmp); + fax_image_resolution = switch_core_session_sprintf(session, "%ix%i", t.x_resolution, t.y_resolution); + if (fax_image_resolution) { + switch_channel_set_variable(channel, "fax_image_resolution", fax_image_resolution); } - tmp = switch_mprintf("%d", t.image_size); - if (tmp) { - switch_channel_set_variable(channel, "fax_image_size", tmp); - switch_safe_free(tmp); + fax_image_size = switch_core_session_sprintf(session, "%d", t.image_size); + if (fax_image_size) { + switch_channel_set_variable(channel, "fax_image_size", fax_image_size); } - tmp = switch_mprintf("%d", t.bad_rows); - if (tmp) { - switch_channel_set_variable(channel, "fax_bad_rows", tmp); - switch_safe_free(tmp); + fax_bad_rows = switch_core_session_sprintf(session, "%d", t.bad_rows); + if (fax_bad_rows) { + switch_channel_set_variable(channel, "fax_bad_rows", fax_bad_rows); } - tmp = switch_mprintf("%i", t.bit_rate); - if (tmp) { - switch_channel_set_variable(channel, "fax_transfer_rate", tmp); - switch_safe_free(tmp); + fax_transfer_rate = switch_core_session_sprintf(session, "%i", t.bit_rate); + if (fax_transfer_rate) { + switch_channel_set_variable(channel, "fax_transfer_rate", fax_transfer_rate); } /* switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); */ pvt->done = 1; - /* - TODO Fire events - */ + /* Fire event */ + + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, pvt->app_mode == FUNCTION_TX ? SPANDSP_EVENT_TXFAXRESULT : SPANDSP_EVENT_RXFAXRESULT) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-document-transferred-pages", fax_document_transferred_pages); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-document-total-pages", fax_document_total_pages); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-resolution", fax_image_resolution); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-size", fax_image_size); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-bad-rows", fax_bad_rows); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-transfer-rate", fax_transfer_rate); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-result-code", fax_result_code); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-result-text", t30_completion_code_to_str(result)); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-ecm-used", (t.error_correcting_mode) ? "on" : "off"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-local-station-id", local_ident); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-remote-station-id", far_ident); + switch_core_session_queue_private_event(session, &event, SWITCH_FALSE); + } } static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) @@ -1026,7 +1042,6 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Fax TX filename not set.\n"); goto done; } else if (pvt->app_mode == FUNCTION_RX) { - char *fname; const char *prefix; switch_time_t time; @@ -1036,11 +1051,7 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat prefix = globals.prepend_string; } - fname = switch_mprintf("%s/%s-%ld-%ld.tif", globals.spool, prefix, globals.total_sessions, time); - if (fname) { - pvt->filename = switch_core_session_strdup(session, fname); - switch_safe_free(fname); - } else { + if (!(pvt->filename = switch_core_session_sprintf(session, "%s/%s-%ld-%ld.tif", globals.spool, prefix, globals.total_sessions, time))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot automatically set fax RX destination file\n"); goto done; } From 155571d841effd7411686952da0d679af34bc0ac Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 27 Jan 2011 16:55:21 -0500 Subject: [PATCH 073/245] freetdm: fix ftdm error mapping to unix-style errors --- libs/freetdm/src/include/ftdm_declare.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libs/freetdm/src/include/ftdm_declare.h b/libs/freetdm/src/include/ftdm_declare.h index 88a76930f7..b443f2d5f5 100644 --- a/libs/freetdm/src/include/ftdm_declare.h +++ b/libs/freetdm/src/include/ftdm_declare.h @@ -178,18 +178,20 @@ typedef int ftdm_socket_t; /*! \brief FreeTDM APIs possible return codes */ typedef enum { FTDM_SUCCESS, /*!< Success */ - FTDM_FAIL, /*!< Failure, generic error return code, use ftdm_channel_get_last_error or ftdm_span_get_last_error for details */ - FTDM_MEMERR, /*!< Memory error, most likely allocation failure */ + FTDM_FAIL, /*!< Failure, generic error return code when no more specific return code can be used */ + + FTDM_MEMERR, /*!< Allocation failure */ + FTDM_ENOMEM = FTDM_MEMERR, + FTDM_TIMEOUT, /*!< Operation timed out (ie: polling on a device)*/ + FTDM_ETIMEDOUT = FTDM_TIMEOUT, + FTDM_NOTIMPL, /*!< Operation not implemented */ + FTDM_ENOSYS = FTDM_NOTIMPL, /*!< The function is not implemented */ + FTDM_BREAK, /*!< Request the caller to perform a break (context-dependant, ie: stop getting DNIS/ANI) */ /*!< Any new return codes should try to mimc unix style error codes, no need to reinvent */ - /* Remapping some of the codes that were before */ - FTDM_ENOMEM = FTDM_MEMERR, /*!< Memory error */ - FTDM_ETIMEDOUT = FTDM_TIMEOUT, /*!< Operation timedout */ - FTDM_ENOSYS = FTDM_NOTIMPL, /*!< The function is not implemented */ - FTDM_EINVAL, /*!< Invalid argument */ FTDM_ECANCELED, /*!< Operation cancelled */ FTDM_EBUSY, /*!< Device busy */ From 1842798e95eeeed61604455ebcd5001bdf35eeb1 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 27 Jan 2011 17:02:04 -0500 Subject: [PATCH 074/245] freetdm: ftmod_r2 - check for io dump file errors on open --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 0217a5172a..d86fb43195 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -729,16 +729,24 @@ static void dump_mf(openr2_chan_t *r2chan) snprintf(dfile, sizeof(dfile), logname ? "%s.s%dc%d.input.alaw" : "%s/s%dc%d.input.alaw", logname ? logname : r2data->logdir, ftdmchan->span_id, ftdmchan->chan_id); f = fopen(dfile, "wb"); - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO input in file %s\n", dfile); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_INPUT, f); - fclose(f); + if (f) { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO input in file %s\n", dfile); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_INPUT, f); + fclose(f); + } else { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Could not dump IO input in file %s, error: %s", dfile, strerror(errno)); + } snprintf(dfile, sizeof(dfile), logname ? "%s.s%dc%d.output.alaw" : "%s/s%dc%d.output.alaw", logname ? logname : r2data->logdir, ftdmchan->span_id, ftdmchan->chan_id); f = fopen(dfile, "wb"); - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO output in file %s\n", dfile); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_OUTPUT, f); - fclose(f); + if (f) { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO output in file %s\n", dfile); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_OUTPUT, f); + fclose(f); + } else { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Could not dump IO output in file %s, error: %s", dfile, strerror(errno)); + } } } From 189db0e7ad0f4ef29ffa703114ff1d94a20d0b8f Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 27 Jan 2011 17:27:50 -0500 Subject: [PATCH 075/245] freetdm: add WIN32_LEAN_AND_MEAN fix --- libs/freetdm/cyginstall.sh | 0 libs/freetdm/src/include/private/ftdm_core.h | 5 ++++- 2 files changed, 4 insertions(+), 1 deletion(-) mode change 100644 => 100755 libs/freetdm/cyginstall.sh diff --git a/libs/freetdm/cyginstall.sh b/libs/freetdm/cyginstall.sh old mode 100644 new mode 100755 diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index 7cf0934f57..ba16c7cb7f 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -94,7 +94,10 @@ !strcasecmp(expr, "active") || \ atoi(expr))) ? 1 : 0 - +#ifdef WIN32_LEAN_AND_MEAN +#include +#include +#endif #include #ifndef __WINDOWS__ From 9ade16e9291aa74b4483bb9b9d9db266e082f7cc Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 27 Jan 2011 18:38:16 -0600 Subject: [PATCH 076/245] swigall --- .../languages/mod_managed/freeswitch_wrap.cxx | 127 +++++++++++++++++ src/mod/languages/mod_managed/managed/swig.cs | 134 +++++++++++++++++- 2 files changed, 259 insertions(+), 2 deletions(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index aa2a84f3f6..3ee6ff62fd 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -7413,6 +7413,20 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_get_dmachine(void * jar } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_set_codec_slin(void * jarg1, void * jarg2) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_slin_data_t *arg2 = (switch_slin_data_t *) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (switch_slin_data_t *)jarg2; + result = (switch_status_t)switch_core_session_set_codec_slin(arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_core_get_uuid() { char * jresult ; char *result = 0 ; @@ -22794,6 +22808,119 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_api_interface(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_session_set(void * jarg1, void * jarg2) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_core_session_t *arg2 = (switch_core_session_t *) 0 ; + + arg1 = (switch_slin_data *)jarg1; + arg2 = (switch_core_session_t *)jarg2; + if (arg1) (arg1)->session = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_session_get(void * jarg1) { + void * jresult ; + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_core_session_t *result = 0 ; + + arg1 = (switch_slin_data *)jarg1; + result = (switch_core_session_t *) ((arg1)->session); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_write_frame_set(void * jarg1, void * jarg2) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_frame_t *arg2 = (switch_frame_t *) 0 ; + + arg1 = (switch_slin_data *)jarg1; + arg2 = (switch_frame_t *)jarg2; + if (arg1) (arg1)->write_frame = *arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_write_frame_get(void * jarg1) { + void * jresult ; + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_frame_t *result = 0 ; + + arg1 = (switch_slin_data *)jarg1; + result = (switch_frame_t *)& ((arg1)->write_frame); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_codec_set(void * jarg1, void * jarg2) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_codec_t *arg2 = (switch_codec_t *) 0 ; + + arg1 = (switch_slin_data *)jarg1; + arg2 = (switch_codec_t *)jarg2; + if (arg1) (arg1)->codec = *arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_codec_get(void * jarg1) { + void * jresult ; + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_codec_t *result = 0 ; + + arg1 = (switch_slin_data *)jarg1; + result = (switch_codec_t *)& ((arg1)->codec); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_frame_data_set(void * jarg1, char * jarg2) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + char *arg2 ; + + arg1 = (switch_slin_data *)jarg1; + arg2 = (char *)jarg2; + { + if (arg2) strncpy((char *)arg1->frame_data, (const char *)arg2, 4096); + else arg1->frame_data[0] = 0; + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_slin_data_frame_data_get(void * jarg1) { + char * jresult ; + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + char *result = 0 ; + + arg1 = (switch_slin_data *)jarg1; + result = (char *)(char *) ((arg1)->frame_data); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_slin_data() { + void * jresult ; + switch_slin_data *result = 0 ; + + result = (switch_slin_data *)new switch_slin_data(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_slin_data(void * jarg1) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + + arg1 = (switch_slin_data *)jarg1; + delete arg1; + +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_timetable_profile_created_set(void * jarg1, void * jarg2) { switch_channel_timetable *arg1 = (switch_channel_timetable *) 0 ; switch_time_t arg2 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 5a2188ac83..48d585e334 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -1357,6 +1357,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_core_session_set_codec_slin(SWIGTYPE_p_switch_core_session session, switch_slin_data data) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_set_codec_slin(SWIGTYPE_p_switch_core_session.getCPtr(session), switch_slin_data.getCPtr(data)); + return ret; + } + public static string switch_core_get_uuid() { string ret = freeswitchPINVOKE.switch_core_get_uuid(); return ret; @@ -7504,6 +7509,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_dmachine")] public static extern IntPtr switch_core_session_get_dmachine(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_set_codec_slin")] + public static extern int switch_core_session_set_codec_slin(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_uuid")] public static extern string switch_core_get_uuid(); @@ -11188,6 +11196,36 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_api_interface")] public static extern void delete_switch_api_interface(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_session_set")] + public static extern void switch_slin_data_session_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_session_get")] + public static extern IntPtr switch_slin_data_session_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_write_frame_set")] + public static extern void switch_slin_data_write_frame_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_write_frame_get")] + public static extern IntPtr switch_slin_data_write_frame_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_codec_set")] + public static extern void switch_slin_data_codec_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_codec_get")] + public static extern IntPtr switch_slin_data_codec_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_frame_data_set")] + public static extern void switch_slin_data_frame_data_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_frame_data_get")] + public static extern string switch_slin_data_frame_data_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_slin_data")] + public static extern IntPtr new_switch_slin_data(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_slin_data")] + public static extern void delete_switch_slin_data(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_timetable_profile_created_set")] public static extern void switch_channel_timetable_profile_created_set(HandleRef jarg1, HandleRef jarg2); @@ -28401,7 +28439,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) } } @@ -29437,6 +29476,96 @@ public enum switch_signal_t { namespace FreeSWITCH.Native { +using System; +using System.Runtime.InteropServices; + +public class switch_slin_data : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_slin_data(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_slin_data obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_slin_data() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_slin_data(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public SWIGTYPE_p_switch_core_session session { + set { + freeswitchPINVOKE.switch_slin_data_session_set(swigCPtr, SWIGTYPE_p_switch_core_session.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_session_get(swigCPtr); + SWIGTYPE_p_switch_core_session ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_core_session(cPtr, false); + return ret; + } + } + + public switch_frame write_frame { + set { + freeswitchPINVOKE.switch_slin_data_write_frame_set(swigCPtr, switch_frame.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_write_frame_get(swigCPtr); + switch_frame ret = (cPtr == IntPtr.Zero) ? null : new switch_frame(cPtr, false); + return ret; + } + } + + public switch_codec codec { + set { + freeswitchPINVOKE.switch_slin_data_codec_set(swigCPtr, switch_codec.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_codec_get(swigCPtr); + switch_codec ret = (cPtr == IntPtr.Zero) ? null : new switch_codec(cPtr, false); + return ret; + } + } + + public string frame_data { + set { + freeswitchPINVOKE.switch_slin_data_frame_data_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_slin_data_frame_data_get(swigCPtr); + return ret; + } + } + + public switch_slin_data() : this(freeswitchPINVOKE.new_switch_slin_data(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * 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 { + [System.Flags] public enum switch_speech_flag_enum_t { SWITCH_SPEECH_FLAG_NONE = 0, SWITCH_SPEECH_FLAG_HASTEXT = (1 << 0), @@ -30146,7 +30275,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, @@ -30163,6 +30292,7 @@ public enum switch_status_t { SWITCH_STATUS_TOO_SMALL, SWITCH_STATUS_FOUND, SWITCH_STATUS_CONTINUE, + SWITCH_STATUS_TERM, SWITCH_STATUS_NOT_INITALIZED } From c64b78577f65b586ff6d7af711c79d0427fc61c5 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Fri, 28 Jan 2011 09:01:47 +0000 Subject: [PATCH 077/245] .gitignore compressed files --- .gitignore | 7 ++++++- src/mod/endpoints/mod_gsmopen/.gitignore | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 304b42c1f9..c53d07d8a9 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,12 @@ *.ilk *.bsc *.pch +*.tar +*.gz +*.tgz +*.xz +*.bz2 +*.tbz2 core.* /Path /w32/Library/lastversion @@ -79,7 +85,6 @@ configure.lineno /scripts/fsxs /scripts/gentls_cert /a.out.dSYM -/freeswitch-sounds-* src/mod/applications/mod_easyroute/Makefile src/mod/applications/mod_lcr/Makefile src/mod/applications/mod_nibblebill/Makefile diff --git a/src/mod/endpoints/mod_gsmopen/.gitignore b/src/mod/endpoints/mod_gsmopen/.gitignore index 9fdeeb1412..fe8dc68bd5 100644 --- a/src/mod/endpoints/mod_gsmopen/.gitignore +++ b/src/mod/endpoints/mod_gsmopen/.gitignore @@ -1,2 +1,4 @@ !/gsmlib/gsmlib-*/aclocal.m4 !/gsmlib/gsmlib-*/configure +!/gsmlib/gsmlib-1.10.tar.gz +!/gsmlib/gsmlib_1.10-12ubuntu1.diff.gz From daa28cfccae9b171221408f3af4f8c10283e67b3 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Fri, 28 Jan 2011 09:19:03 -0600 Subject: [PATCH 078/245] add missing files --- libs/freetdm/msvc/freetdm.2010.vcxproj | 2 ++ libs/freetdm/msvc/freetdm.2010.vcxproj.filters | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/libs/freetdm/msvc/freetdm.2010.vcxproj b/libs/freetdm/msvc/freetdm.2010.vcxproj index 71eb6dbf22..aecb9ef79c 100644 --- a/libs/freetdm/msvc/freetdm.2010.vcxproj +++ b/libs/freetdm/msvc/freetdm.2010.vcxproj @@ -188,6 +188,7 @@ + @@ -209,6 +210,7 @@ + diff --git a/libs/freetdm/msvc/freetdm.2010.vcxproj.filters b/libs/freetdm/msvc/freetdm.2010.vcxproj.filters index ed642baf3d..e6dc40d372 100644 --- a/libs/freetdm/msvc/freetdm.2010.vcxproj.filters +++ b/libs/freetdm/msvc/freetdm.2010.vcxproj.filters @@ -71,6 +71,9 @@ Header Files + + Header Files + @@ -124,5 +127,8 @@ Source Files + + Source Files + \ No newline at end of file From 08f494b80802aacf101705382f149ca4b028eb57 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Fri, 28 Jan 2011 20:14:10 +0100 Subject: [PATCH 079/245] 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 080/245] 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 081/245] 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 082/245] 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 083/245] 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 084/245] 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 085/245] 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 086/245] 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 087/245] 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 088/245] 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 089/245] 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 090/245] 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 becb94052ac619290e6825c4f985917134c6bce2 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Fri, 26 Nov 2010 15:59:24 -0500 Subject: [PATCH 091/245] chlog: freetdm: ss7 - added support for RELAY --- libs/freetdm/Makefile.am | 3 +- libs/freetdm/configure.ac | 2 +- libs/freetdm/mod_freetdm/mod_freetdm.c | 62 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c | 547 ++- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 381 ++- .../ftmod_sangoma_ss7_cntrl.c | 374 ++- .../ftmod_sangoma_ss7_handle.c | 94 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c | 80 +- .../ftmod_sangoma_ss7_logger.c | 121 +- .../ftmod_sangoma_ss7_main.c | 305 +- .../ftmod_sangoma_ss7_main.h | 326 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 17 +- .../ftmod_sangoma_ss7_relay.c | 318 ++ .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c | 106 +- .../ftmod_sangoma_ss7_support.c | 267 +- .../ftmod_sangoma_ss7_timers.c | 2 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 2977 ++++++++++------- 17 files changed, 4192 insertions(+), 1790 deletions(-) create mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am index 96f1c9a10f..b3353f32de 100644 --- a/libs/freetdm/Makefile.am +++ b/libs/freetdm/Makefile.am @@ -240,7 +240,8 @@ ftmod_sangoma_ss7_la_SOURCES = \ $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c \ $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c \ $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c ftmod_sangoma_ss7_la_CFLAGS = $(AM_CFLAGS) $(FTDM_CFLAGS) -D_GNU_SOURCE ftmod_sangoma_ss7_la_LDFLAGS = -shared -module -avoid-version -lsng_ss7 diff --git a/libs/freetdm/configure.ac b/libs/freetdm/configure.ac index a070e994a3..1f4fc9c6ac 100644 --- a/libs/freetdm/configure.ac +++ b/libs/freetdm/configure.ac @@ -267,7 +267,7 @@ fi # HAVE_SNG_SS7="no" AC_MSG_RESULT([${as_nl}<<>> Sangoma SS7 stack]) -AC_CHECK_LIB([sng_ss7], [sng_isup_init], [HAVE_SNG_SS7="yes"]) +AC_CHECK_LIB([sng_ss7], [sng_isup_init_gen], [HAVE_SNG_SS7="yes"]) AC_MSG_RESULT([checking whether to build ftmod_sangoma_ss7... ${HAVE_SNG_SS7}]) AM_CONDITIONAL([HAVE_SNG_SS7], [test "${HAVE_SNG_SS7}" = "yes"]) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 970cb5b993..d972cd7406 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2360,8 +2360,9 @@ static int add_config_list_nodes(switch_xml_t swnode, ftdm_conf_node_t *rootnode static ftdm_conf_node_t *get_ss7_config_node(switch_xml_t cfg, const char *confname) { - switch_xml_t signode, ss7configs, isup; - ftdm_conf_node_t *rootnode; + switch_xml_t signode, ss7configs, isup, gen, param; + ftdm_conf_node_t *rootnode, *list; + char *var, *val; /* try to find the conf in the hash first */ rootnode = switch_core_hash_find(globals.ss7_configs, confname); @@ -2405,8 +2406,56 @@ static ftdm_conf_node_t *get_ss7_config_node(switch_xml_t cfg, const char *confn return NULL; } + /* add sng_gen */ + gen = switch_xml_child(isup, "sng_gen"); + if (gen == NULL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_gen for sng_isup config %s\n", confname); + ftdm_conf_node_destroy(rootnode); + return NULL; + } + + if ((FTDM_SUCCESS != ftdm_conf_node_create("sng_gen", &list, rootnode))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node for %s\n", "sng_gen", confname); + ftdm_conf_node_destroy(rootnode); + return NULL; + } + + for (param = switch_xml_child(gen, "param"); param; param = param->next) { + var = (char *) switch_xml_attr_soft(param, "name"); + val = (char *) switch_xml_attr_soft(param, "value"); + ftdm_conf_node_add_param(list, var, val); + } + + /* add relay channels */ + if (add_config_list_nodes(isup, rootnode, "sng_relay", "relay_channel", NULL, NULL)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_relay for sng_isup config %s\n", confname); + ftdm_conf_node_destroy(rootnode); + return NULL; + } + + /* add mtp1 links */ + if (add_config_list_nodes(isup, rootnode, "mtp1_links", "mtp1_link", NULL, NULL)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp1_links for sng_isup config %s\n", confname); + ftdm_conf_node_destroy(rootnode); + return NULL; + } + + /* add mtp2 links */ + if (add_config_list_nodes(isup, rootnode, "mtp2_links", "mtp2_link", NULL, NULL)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp2_links for sng_isup config %s\n", confname); + ftdm_conf_node_destroy(rootnode); + return NULL; + } + + /* add mtp3 links */ + if (add_config_list_nodes(isup, rootnode, "mtp3_links", "mtp3_link", NULL, NULL)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp3_links for sng_isup config %s\n", confname); + ftdm_conf_node_destroy(rootnode); + return NULL; + } + /* add mtp linksets */ - if (add_config_list_nodes(isup, rootnode, "mtp_linksets", "mtp_linkset", "mtp_links", "mtp_link")) { + if (add_config_list_nodes(isup, rootnode, "mtp_linksets", "mtp_linkset", NULL, NULL)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp_linksets for sng_isup config %s\n", confname); ftdm_conf_node_destroy(rootnode); return NULL; @@ -2426,6 +2475,13 @@ static ftdm_conf_node_t *get_ss7_config_node(switch_xml_t cfg, const char *confn return NULL; } + /* add cc spans */ + if (add_config_list_nodes(isup, rootnode, "cc_spans", "cc_span", NULL, NULL)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process cc_spans for sng_isup config %s\n", confname); + ftdm_conf_node_destroy(rootnode); + return NULL; + } + switch_core_hash_insert(globals.ss7_configs, confname, rootnode); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Added SS7 node configuration %s\n", confname); 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 e7378bf2ea..42b95a1863 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 @@ -44,6 +44,7 @@ /* PROTOTYPES *****************************************************************/ int ft_to_sngss7_cfg_all(void); +int ftmod_ss7_relay_gen_config(void); int ftmod_ss7_mtp1_gen_config(void); int ftmod_ss7_mtp2_gen_config(void); int ftmod_ss7_mtp3_gen_config(void); @@ -65,6 +66,8 @@ int ftmod_ss7_isup_ckt_config(int id); int ftmod_ss7_isup_isap_config(int id); int ftmod_ss7_cc_isap_config(int id); + +int ftmod_ss7_relay_chan_config(int id); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -75,6 +78,7 @@ int ft_to_sngss7_cfg_all(void) /* check if we have done gen_config already */ if (!(g_ftdm_sngss7_data.gen_config)) { + /* start of by checking if the license and sig file are valid */ if (sng_validate_license(g_ftdm_sngss7_data.cfg.license, g_ftdm_sngss7_data.cfg.signature, g_ftdm_sngss7_data.cfg.spc)) { @@ -83,50 +87,148 @@ int ft_to_sngss7_cfg_all(void) return 1; } - if (ftmod_ss7_mtp1_gen_config()) { - SS7_CRITICAL("MTP1 General configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("MTP1 General configuration DONE\n"); + /* if the procId is not 0 then we are using relay mode */ + if (g_ftdm_sngss7_data.cfg.procId != 0) { + /* set the desired procID value */ + sng_set_procId((uint16_t)g_ftdm_sngss7_data.cfg.procId); } - if (ftmod_ss7_mtp2_gen_config()) { - SS7_CRITICAL("MTP2 General configuration FAILED!\n"); + /* start up the stack manager */ + if (sng_isup_init_sm()) { + SS7_CRITICAL("Failed to start Stack Manager\n"); return 1; } else { - SS7_INFO("MTP2 General configuration DONE\n"); + SS7_INFO("Started Stack Manager!\n"); } - if (ftmod_ss7_mtp3_gen_config()) { - SS7_CRITICAL("MTP3 General configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("MTP3 General configuration DONE\n"); - } + /* check if the configuration had a Relay Channel */ + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY)) { + /* start up the relay task */ + if (sng_isup_init_relay()) { + SS7_CRITICAL("Failed to start Relay\n"); + return 1; + } else { + SS7_INFO("Started Relay!\n"); + } - if (ftmod_ss7_isup_gen_config()) { - SS7_CRITICAL("ISUP General configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("ISUP General configuration DONE\n"); - } + /* run general configuration on the relay task */ + if (ftmod_ss7_relay_gen_config()) { + SS7_CRITICAL("Relay General configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("Relay General configuration DONE\n"); + } - if (ftmod_ss7_cc_gen_config()) { - SS7_CRITICAL("CC General configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("CC General configuration DONE\n"); - } + } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY)) */ + + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC)) { + if (sng_isup_init_cc()) { + SS7_CRITICAL("Failed to start Call-Control\n"); + return 1; + } else { + SS7_INFO("Started Call-Control!\n"); + } + if (ftmod_ss7_cc_gen_config()) { + SS7_CRITICAL("CC General configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("CC General configuration DONE\n"); + } + if (ftmod_ss7_cc_isap_config(1)) { + SS7_CRITICAL("CC ISAP configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("CC ISAP configuration DONE!\n"); + } + } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC)) */ + + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) { + if (sng_isup_init_isup()) { + SS7_CRITICAL("Failed to start ISUP\n"); + return 1; + } else { + SS7_INFO("Started ISUP!\n"); + } + if (ftmod_ss7_isup_gen_config()) { + SS7_CRITICAL("ISUP General configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("ISUP General configuration DONE\n"); + } + } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) */ + + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3)) { + if (sng_isup_init_mtp3()) { + SS7_CRITICAL("Failed to start MTP3\n"); + return 1; + } else { + SS7_INFO("Started MTP3!\n"); + } + + if (ftmod_ss7_mtp3_gen_config()) { + SS7_CRITICAL("MTP3 General configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("MTP3 General configuration DONE\n"); + } + } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3)) */ + + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) { + if (sng_isup_init_mtp2()) { + SS7_CRITICAL("Failed to start MTP2\n"); + return 1; + } else { + SS7_INFO("Started MTP2!\n"); + } + if (sng_isup_init_mtp1()) { + SS7_CRITICAL("Failed to start MTP2\n"); + return 1; + } else { + SS7_INFO("Started MTP1!\n"); + } + if (ftmod_ss7_mtp1_gen_config()) { + SS7_CRITICAL("MTP1 General configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("MTP1 General configuration DONE\n"); + } + if (ftmod_ss7_mtp2_gen_config()) { + SS7_CRITICAL("MTP2 General configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("MTP2 General configuration DONE\n"); + } + } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) */ /* update the global gen_config so we don't do it again */ g_ftdm_sngss7_data.gen_config = 1; - } + } /* if (!(g_ftdm_sngss7_data.gen_config)) */ + /* go through all the relays channels and configure it */ + x = 1; + while (g_ftdm_sngss7_data.cfg.relay[x].id != 0) { + /* check if this relay channel has been configured already */ + if (!(g_ftdm_sngss7_data.cfg.relay[x].flags & SNGSS7_CONFIGURED)) { + + /* send the specific configuration */ + if (ftmod_ss7_relay_chan_config(x)) { + SS7_CRITICAL("Relay Channel %d configuration FAILED!\n", x); + return 1; + } else { + SS7_INFO("Relay Channel %d configuration DONE!\n", x); + } + + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.relay[x].flags |= SNGSS7_CONFIGURED; + } /* if !SNGSS7_CONFIGURED */ + x++; + } /* while (g_ftdm_sngss7_data.cfg.relay[x].id != 0) */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + while (x < (MAX_MTP_LINKS + 1)) { /* check if this link has been configured already */ - if (!(g_ftdm_sngss7_data.cfg.mtpLink[x].flags & CONFIGURED)) { + if (!(g_ftdm_sngss7_data.cfg.mtp1Link[x].flags & SNGSS7_CONFIGURED) && + (g_ftdm_sngss7_data.cfg.mtp1Link[x].id != 0)) { /* configure mtp1 */ if (ftmod_ss7_mtp1_psap_config(x)) { @@ -136,6 +238,18 @@ int ft_to_sngss7_cfg_all(void) SS7_INFO("MTP1 PSAP %d configuration DONE!\n", x); } + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.mtp1Link[x].flags |= SNGSS7_CONFIGURED; + } + x++; + } /* while (g_ftdm_sngss7_data.cfg.mtp1Link[x].id != 0) */ + + x = 1; + while (x < (MAX_MTP_LINKS + 1)) { + /* check if this link has been configured already */ + if (!(g_ftdm_sngss7_data.cfg.mtp2Link[x].flags & SNGSS7_CONFIGURED) && + (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0)) { + /* configure mtp2 */ if (ftmod_ss7_mtp2_dlsap_config(x)) { SS7_CRITICAL("MTP2 DLSAP %d configuration FAILED!\n",x); @@ -144,6 +258,18 @@ int ft_to_sngss7_cfg_all(void) SS7_INFO("MTP2 DLSAP %d configuration DONE!\n", x); } + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.mtp2Link[x].flags |= SNGSS7_CONFIGURED; + } + x++; + } /* while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) */ + + x = 1; + while (x < (MAX_MTP_LINKS + 1)) { + /* check if this link has been configured already */ + if (!(g_ftdm_sngss7_data.cfg.mtp3Link[x].flags & SNGSS7_CONFIGURED) && + (g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0)) { + /* configure mtp3 */ if (ftmod_ss7_mtp3_dlsap_config(x)) { SS7_CRITICAL("MTP3 DLSAP %d configuration FAILED!\n", x); @@ -152,17 +278,17 @@ int ft_to_sngss7_cfg_all(void) SS7_INFO("MTP3 DLSAP %d configuration DONE!\n", x); } - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.mtpLink[x].flags |= CONFIGURED; + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.mtp3Link[x].flags |= SNGSS7_CONFIGURED; } x++; - } /* while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) */ + } /* while (g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) */ x = 1; while (g_ftdm_sngss7_data.cfg.nsap[x].id != 0) { /* check if this link has been configured already */ - if (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & CONFIGURED)) { + 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); @@ -178,9 +304,9 @@ int ft_to_sngss7_cfg_all(void) SS7_INFO("ISUP NSAP %d configuration DONE!\n", x); } - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.nsap[x].flags |= CONFIGURED; - } /* if !CONFIGURED */ + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_CONFIGURED; + } /* if !SNGSS7_CONFIGURED */ x++; } /* while (g_ftdm_sngss7_data.cfg.nsap[x].id != 0) */ @@ -188,7 +314,7 @@ int ft_to_sngss7_cfg_all(void) x = 1; while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) { /* check if this link has been configured already */ - if (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & CONFIGURED)) { + if (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_CONFIGURED)) { if (ftmod_ss7_mtp3_linkset_config(x)) { SS7_CRITICAL("MTP3 LINKSET %d configuration FAILED!\n", x); @@ -197,9 +323,9 @@ int ft_to_sngss7_cfg_all(void) SS7_INFO("MTP3 LINKSET %d configuration DONE!\n", x); } - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= CONFIGURED; - } /* if !CONFIGURED */ + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_CONFIGURED; + } /* if !SNGSS7_CONFIGURED */ x++; } /* while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) */ @@ -207,7 +333,7 @@ int ft_to_sngss7_cfg_all(void) x = 1; while ((g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0)) { /* check if this link has been configured already */ - if (!(g_ftdm_sngss7_data.cfg.mtpRoute[x].flags & CONFIGURED)) { + if (!(g_ftdm_sngss7_data.cfg.mtpRoute[x].flags & SNGSS7_CONFIGURED)) { if (ftmod_ss7_mtp3_route_config(x)) { SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x); @@ -216,31 +342,33 @@ int ft_to_sngss7_cfg_all(void) SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x); } - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.mtpRoute[x].flags |= CONFIGURED; - } /* if !CONFIGURED */ + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.mtpRoute[x].flags |= SNGSS7_CONFIGURED; + } /* if !SNGSS7_CONFIGURED */ x++; } /* while (g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) */ - if (!(g_ftdm_sngss7_data.cfg.mtpRoute[0].flags & CONFIGURED)) { - - if (ftmod_ss7_mtp3_route_config(0)) { - SS7_CRITICAL("MTP3 ROUTE 0 configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("MTP3 ROUTE 0 configuration DONE!\n"); - } - - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.mtpRoute[0].flags |= CONFIGURED; - } /* if !CONFIGURED */ + if (g_ftdm_sngss7_data.cfg.mtpRoute[1].id != 0) { + if (!(g_ftdm_sngss7_data.cfg.mtpRoute[0].flags & SNGSS7_CONFIGURED)) { + + if (ftmod_ss7_mtp3_route_config(0)) { + SS7_CRITICAL("MTP3 ROUTE 0 configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("MTP3 ROUTE 0 configuration DONE!\n"); + } + + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.mtpRoute[0].flags |= SNGSS7_CONFIGURED; + } /* if !SNGSS7_CONFIGURED */ + } x = 1; while (g_ftdm_sngss7_data.cfg.isap[x].id != 0) { /* check if this link has been configured already */ - if (!(g_ftdm_sngss7_data.cfg.isap[x].flags & CONFIGURED)) { + if (!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_CONFIGURED)) { if (ftmod_ss7_isup_isap_config(x)) { SS7_CRITICAL("ISUP ISAP %d configuration FAILED!\n", x); @@ -249,57 +377,51 @@ int ft_to_sngss7_cfg_all(void) SS7_INFO("ISUP ISAP %d configuration DONE!\n", x); } - if (ftmod_ss7_cc_isap_config(x)) { - SS7_CRITICAL("CC ISAP %d configuration FAILED!\n", x); - return 1; - } else { - SS7_INFO("CC ISAP %d configuration DONE!\n", x); - } - - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.isap[x].flags |= CONFIGURED; - } /* if !CONFIGURED */ + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.isap[x].flags |= SNGSS7_CONFIGURED; + } /* if !SNGSS7_CONFIGURED */ x++; } /* while (g_ftdm_sngss7_data.cfg.isap[x].id != 0) */ - x = 1; - while (g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) { - /* check if this link has been configured already */ - if (!(g_ftdm_sngss7_data.cfg.isupIntf[x].flags & CONFIGURED)) { - - if (ftmod_ss7_isup_intf_config(x)) { - SS7_CRITICAL("ISUP INTF %d configuration FAILED!\n", x); - return 1; - } else { - SS7_INFO("ISUP INTF %d configuration DONE!\n", x); - /* set the interface to paused */ - sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[x], SNGSS7_PAUSED); - } - - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.isupIntf[x].flags |= CONFIGURED; - } /* if !CONFIGURED */ - - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) */ - - x = 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - /* check if this link has been configured already */ - if (!(g_ftdm_sngss7_data.cfg.isupCkt[x].flags & CONFIGURED)) { - if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == 0) { - if (ftmod_ss7_isup_ckt_config(x)) { - SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x); + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) { + x = 1; + while (g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) { + /* check if this link has been configured already */ + if (!(g_ftdm_sngss7_data.cfg.isupIntf[x].flags & SNGSS7_CONFIGURED)) { + + if (ftmod_ss7_isup_intf_config(x)) { + SS7_CRITICAL("ISUP INTF %d configuration FAILED!\n", x); return 1; } else { - SS7_INFO("ISUP CKT %d configuration DONE!\n", x); + SS7_INFO("ISUP INTF %d configuration DONE!\n", x); + /* set the interface to paused */ + sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[x], SNGSS7_PAUSED); } + + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.isupIntf[x].flags |= SNGSS7_CONFIGURED; + } /* if !SNGSS7_CONFIGURED */ + + x++; + } /* while (g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) */ + } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) */ + + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + if (ftmod_ss7_isup_ckt_config(x)) { + SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x); + return 1; + } else { + SS7_INFO("ISUP CKT %d configuration DONE!\n", x); } - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.isupCkt[x].flags |= CONFIGURED; - } /* if !CONFIGURED */ + } /* if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) */ + + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.isupCkt[x].flags |= SNGSS7_CONFIGURED; x++; } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ @@ -307,6 +429,44 @@ int ft_to_sngss7_cfg_all(void) return 0; } +/******************************************************************************/ +int ftmod_ss7_relay_gen_config(void) +{ + RyMngmt cfg; /*configuration structure*/ + Pst pst; /*post structure*/ + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTRY; + + /* clear the configuration structure */ + memset(&cfg, 0x0, sizeof(RyMngmt)); + + /* fill in some general sections of the header */ + smHdrInit(&cfg.hdr); + + /* fill in the post structure */ + smPstInit( &cfg.t.cfg.s.ryGenCfg.lmPst ); + + /*fill in the specific fields of the header */ + cfg.hdr.msgType = TCFG; + cfg.hdr.entId.ent = ENTRY; + cfg.hdr.entId.inst = S_INST; + cfg.hdr.elmId.elmnt = STGEN; + + cfg.t.cfg.s.ryGenCfg.lmPst.srcEnt = ENTRY; + cfg.t.cfg.s.ryGenCfg.lmPst.dstEnt = ENTSM; + + cfg.t.cfg.s.ryGenCfg.nmbChan = 10; + cfg.t.cfg.s.ryGenCfg.tmrRes = RY_PERIOD; + cfg.t.cfg.s.ryGenCfg.usta = 1; + + + return(sng_cfg_relay(&pst, &cfg)); +} + /******************************************************************************/ int ftmod_ss7_mtp1_gen_config(void) { @@ -575,7 +735,7 @@ int ftmod_ss7_mtp1_psap_config(int id) { L1Mngmt cfg; Pst pst; - sng_mtp_link_t *k = &g_ftdm_sngss7_data.cfg.mtpLink[id]; + sng_mtp1_link_t *k = &g_ftdm_sngss7_data.cfg.mtp1Link[id]; /* initalize the post structure */ smPstInit(&pst); @@ -597,8 +757,8 @@ int ftmod_ss7_mtp1_psap_config(int id) cfg.hdr.elmId.elmntInst1 = k->id; - cfg.t.cfg.s.l1PSAP.span = k->mtp1.span; - cfg.t.cfg.s.l1PSAP.chan = k->mtp1.chan; + cfg.t.cfg.s.l1PSAP.span = k->span; + cfg.t.cfg.s.l1PSAP.chan = k->chan; cfg.t.cfg.s.l1PSAP.spId = k->id; return(sng_cfg_mtp1(&pst, &cfg)); @@ -609,7 +769,7 @@ int ftmod_ss7_mtp2_dlsap_config(int id) { SdMngmt cfg; Pst pst; - sng_mtp_link_t *k = &g_ftdm_sngss7_data.cfg.mtpLink[id]; + sng_mtp2_link_t *k = &g_ftdm_sngss7_data.cfg.mtp2Link[id]; /* initalize the post structure */ smPstInit( &pst); @@ -633,10 +793,15 @@ int ftmod_ss7_mtp2_dlsap_config(int id) cfg.t.cfg.s.sdDLSAP.mem.region = S_REG; /* memory region */ cfg.t.cfg.s.sdDLSAP.mem.pool = S_POOL; /* memory pool */ - cfg.t.cfg.s.sdDLSAP.swtch = k->mtp2.linkType; /* protocol type */ + cfg.t.cfg.s.sdDLSAP.swtch = k->linkType; /* protocol type */ cfg.t.cfg.s.sdDLSAP.priorDl = PRIOR0; /* priority for data link layer */ cfg.t.cfg.s.sdDLSAP.routeDl = RTESPEC; /* route for data link layer */ cfg.t.cfg.s.sdDLSAP.selectorDl = 0; /* upper interface selector */ + if (k->mtp1ProcId > 0) { + cfg.t.cfg.s.sdDLSAP.dstProcId = k->mtp1ProcId; /* the procid of MAC/L1/MTP1 */ + } else { + cfg.t.cfg.s.sdDLSAP.dstProcId = SFndProcId(); /* the procid of MAC/L1/MTP1 */ + } cfg.t.cfg.s.sdDLSAP.dstProcId = SFndProcId(); /* the procid of MAC/L1/MTP1 */ cfg.t.cfg.s.sdDLSAP.entMac = ENTL1; /* entity for MAC */ cfg.t.cfg.s.sdDLSAP.instMac = S_INST; /* instance for MAC */ @@ -646,22 +811,22 @@ int ftmod_ss7_mtp2_dlsap_config(int id) cfg.t.cfg.s.sdDLSAP.memMac.region = S_REG; /* memory region and pool id for MAC */ cfg.t.cfg.s.sdDLSAP.memMac.pool = S_POOL; cfg.t.cfg.s.sdDLSAP.maxOutsFrms = MAX_SD_OUTSTANDING; /* maximum outstanding frames */ - cfg.t.cfg.s.sdDLSAP.errType = k->mtp2.errorType; + cfg.t.cfg.s.sdDLSAP.errType = k->errorType; cfg.t.cfg.s.sdDLSAP.t1.enb = TRUE; /* timer 1 - Alignment Ready Timer */ - cfg.t.cfg.s.sdDLSAP.t1.val = k->mtp2.t1; + cfg.t.cfg.s.sdDLSAP.t1.val = k->t1; cfg.t.cfg.s.sdDLSAP.t2.enb = TRUE; /* timer 2 - Not Aligned Timer */ - cfg.t.cfg.s.sdDLSAP.t2.val = k->mtp2.t2; + cfg.t.cfg.s.sdDLSAP.t2.val = k->t2; cfg.t.cfg.s.sdDLSAP.t3.enb = TRUE; /* timer 3 - Aligned Timer */ - cfg.t.cfg.s.sdDLSAP.t3.val = k->mtp2.t3; + cfg.t.cfg.s.sdDLSAP.t3.val = k->t3; cfg.t.cfg.s.sdDLSAP.t5.enb = TRUE; /* timer 5 - Sending SIB timer */ - cfg.t.cfg.s.sdDLSAP.t5.val = k->mtp2.t5; + cfg.t.cfg.s.sdDLSAP.t5.val = k->t5; cfg.t.cfg.s.sdDLSAP.t6.enb = TRUE; /* timer 6 - Remote Congestion Timer */ - cfg.t.cfg.s.sdDLSAP.t6.val = k->mtp2.t6; + cfg.t.cfg.s.sdDLSAP.t6.val = k->t6; cfg.t.cfg.s.sdDLSAP.t7.enb = TRUE; /* timer 7 - Excessive delay of acknowledgement timer */ - cfg.t.cfg.s.sdDLSAP.t7.val = k->mtp2.t7; - cfg.t.cfg.s.sdDLSAP.provEmrgcy = k->mtp2.t4e; /* emergency proving period */ - cfg.t.cfg.s.sdDLSAP.provNormal = k->mtp2.t4n; /* normal proving period */ - cfg.t.cfg.s.sdDLSAP.lssuLen = k->mtp2.lssuLength; /* one or two byte LSSU length */ + cfg.t.cfg.s.sdDLSAP.t7.val = k->t7; + cfg.t.cfg.s.sdDLSAP.provEmrgcy = k->t4e; /* emergency proving period */ + cfg.t.cfg.s.sdDLSAP.provNormal = k->t4n; /* normal proving period */ + cfg.t.cfg.s.sdDLSAP.lssuLen = k->lssuLength; /* one or two byte LSSU length */ cfg.t.cfg.s.sdDLSAP.maxFrmLen = MAX_SD_FRAME_LEN; /* max frame length for MSU */ cfg.t.cfg.s.sdDLSAP.congDisc = FALSE; /* congestion discard TRUE or FALSE */ cfg.t.cfg.s.sdDLSAP.sdT = MAX_SD_SUERM; /* SUERM error rate threshold */ @@ -670,7 +835,7 @@ int ftmod_ss7_mtp2_dlsap_config(int id) cfg.t.cfg.s.sdDLSAP.sdN1 = MAX_SD_MSU_RETRANS; /* maximum number of MSUs for retransmission */ cfg.t.cfg.s.sdDLSAP.sdN2 = MAX_SD_OCTETS_RETRANS; /* maximum number of MSU octets for retrans */ cfg.t.cfg.s.sdDLSAP.sdCp = MAX_SD_ALIGN_ATTEMPTS; /* maximum number of alignment attempts */ - cfg.t.cfg.s.sdDLSAP.spIdSE = k->mtp2.mtp1Id; /* service provider id */ + cfg.t.cfg.s.sdDLSAP.spIdSE = k->mtp1Id; /* service provider id */ cfg.t.cfg.s.sdDLSAP.sdtFlcStartTr = 256; /* SDT interface flow control start thresh */ cfg.t.cfg.s.sdDLSAP.sdtFlcEndTr = 512; /* SDT interface flow control end thresh */ @@ -707,7 +872,6 @@ int ftmod_ss7_mtp2_dlsap_config(int id) #endif /*RUG*/ return(sng_cfg_mtp2(&pst, &cfg)); - return 0; } /******************************************************************************/ @@ -715,7 +879,7 @@ int ftmod_ss7_mtp3_dlsap_config(int id) { Pst pst; SnMngmt cfg; - sng_mtp_link_t *k = &g_ftdm_sngss7_data.cfg.mtpLink[id]; + sng_mtp3_link_t *k = &g_ftdm_sngss7_data.cfg.mtp3Link[id]; /* initalize the post structure */ @@ -738,14 +902,14 @@ int ftmod_ss7_mtp3_dlsap_config(int id) cfg.hdr.elmId.elmntInst1 = k->id; - cfg.t.cfg.s.snDLSAP.lnkSetId = k->mtp3.linkSetId; /* link set ID */ - cfg.t.cfg.s.snDLSAP.opc = k->mtp3.spc; /* Originating Postatic int Code */ - cfg.t.cfg.s.snDLSAP.adjDpc = k->mtp3.apc; /* Adlacent Destination Postatic int Code */ + cfg.t.cfg.s.snDLSAP.lnkSetId = k->linkSetId; /* link set ID */ + cfg.t.cfg.s.snDLSAP.opc = k->spc; /* Originating Postatic int Code */ + cfg.t.cfg.s.snDLSAP.adjDpc = k->apc; /* Adlacent Destination Postatic int Code */ cfg.t.cfg.s.snDLSAP.lnkPrior = 0; /* link priority within the link set */ cfg.t.cfg.s.snDLSAP.msgSize = MAX_SN_MSG_SIZE; /* message length */ cfg.t.cfg.s.snDLSAP.msgPrior = 0; /* management message priority */ - cfg.t.cfg.s.snDLSAP.lnkType = k->mtp3.linkType; /* link type ANSI, ITU, BICI or CHINA */ - cfg.t.cfg.s.snDLSAP.upSwtch = k->mtp3.switchType; /* user part switch type */ + cfg.t.cfg.s.snDLSAP.lnkType = k->linkType; /* link type ANSI, ITU, BICI or CHINA */ + cfg.t.cfg.s.snDLSAP.upSwtch = k->switchType; /* user part switch type */ cfg.t.cfg.s.snDLSAP.maxSLTtry = MAX_SLTM_RETRIES; /* maximun times to retry SLTM */ cfg.t.cfg.s.snDLSAP.p0QLen = 32; /* size of the priority 0 Q */ cfg.t.cfg.s.snDLSAP.p1QLen = 32; /* size of the priority 1 Q */ @@ -756,7 +920,7 @@ int ftmod_ss7_mtp3_dlsap_config(int id) cfg.t.cfg.s.snDLSAP.maxCredit = MAX_SN_CREDIT; /* max credit */ #endif /* SDT2 */ cfg.t.cfg.s.snDLSAP.lnkId = 0; /* signalling link allocation procedure identity */ - cfg.t.cfg.s.snDLSAP.lnkTstSLC = k->mtp3.slc; /* link selection code for link test */ + cfg.t.cfg.s.snDLSAP.lnkTstSLC = k->slc; /* link selection code for link test */ cfg.t.cfg.s.snDLSAP.tstLen = 6; /* link test pattern length */ cfg.t.cfg.s.snDLSAP.tst[0] = 'K'; /* link test pattern */ cfg.t.cfg.s.snDLSAP.tst[1] = 'O'; /* link test pattern */ @@ -764,8 +928,8 @@ int ftmod_ss7_mtp3_dlsap_config(int id) cfg.t.cfg.s.snDLSAP.tst[3] = 'R'; /* link test pattern */ cfg.t.cfg.s.snDLSAP.tst[4] = 'A'; /* link test pattern */ cfg.t.cfg.s.snDLSAP.tst[5] = 'D'; /* link test pattern */ - cfg.t.cfg.s.snDLSAP.ssf = k->mtp3.ssf; /* sub service field */ - cfg.t.cfg.s.snDLSAP.dstProcId = SFndProcId(); /* destination processor id */ + cfg.t.cfg.s.snDLSAP.ssf = k->ssf; /* sub service field */ + cfg.t.cfg.s.snDLSAP.dstProcId = k->mtp2ProcId; /* destination processor id */ cfg.t.cfg.s.snDLSAP.dstEnt = ENTSD; /* entity */ cfg.t.cfg.s.snDLSAP.dstInst = S_INST; /* instance */ cfg.t.cfg.s.snDLSAP.prior = PRIOR0; /* priority */ @@ -773,9 +937,9 @@ int ftmod_ss7_mtp3_dlsap_config(int id) cfg.t.cfg.s.snDLSAP.selector = 0; /* lower layer selector */ cfg.t.cfg.s.snDLSAP.mem.region = S_REG; /* memory region id */ cfg.t.cfg.s.snDLSAP.mem.pool = S_POOL; /* memory pool id */ - cfg.t.cfg.s.snDLSAP.spId = k->mtp3.mtp2Id ;/* service provider id */ + cfg.t.cfg.s.snDLSAP.spId = k->mtp2Id; /* service provider id */ - switch (k->mtp3.linkType) { + switch (k->linkType) { /**************************************************************************/ case (LSN_SW_ANS): case (LSN_SW_ANS96): @@ -793,9 +957,9 @@ int ftmod_ss7_mtp3_dlsap_config(int id) cfg.t.cfg.s.snDLSAP.dpcLen = DPC14; /* dpc length 14 bits */ break; /**************************************************************************/ - } /* switch (k->mtp3.linkType) */ + } /* switch (k->linkType) */ - switch (k->mtp3.linkType) { + switch (k->linkType) { /**************************************************************************/ case (LSN_SW_ANS): case (LSN_SW_ANS96): @@ -811,51 +975,51 @@ int ftmod_ss7_mtp3_dlsap_config(int id) cfg.t.cfg.s.snDLSAP.flushContFlag = FALSE; /* flush continue handling */ break; /**************************************************************************/ - } /* switch (k->mtp3.linkType) */ + } /* switch (k->linkType) */ cfg.t.cfg.s.snDLSAP.tmr.t1.enb = TRUE; /* t1 - delay to avoid missequencing on changeover */ - cfg.t.cfg.s.snDLSAP.tmr.t1.val = k->mtp3.t1; + cfg.t.cfg.s.snDLSAP.tmr.t1.val = k->t1; cfg.t.cfg.s.snDLSAP.tmr.t2.enb = TRUE; /* t2 - waiting for changeover ack */ - cfg.t.cfg.s.snDLSAP.tmr.t2.val = k->mtp3.t2; + cfg.t.cfg.s.snDLSAP.tmr.t2.val = k->t2; cfg.t.cfg.s.snDLSAP.tmr.t3.enb = TRUE; /* t3 - delay to avoid missequencing on changeback */ - cfg.t.cfg.s.snDLSAP.tmr.t3.val = k->mtp3.t3; + cfg.t.cfg.s.snDLSAP.tmr.t3.val = k->t3; cfg.t.cfg.s.snDLSAP.tmr.t4.enb = TRUE; /* t4 - waiting for first changeback ack */ - cfg.t.cfg.s.snDLSAP.tmr.t4.val = k->mtp3.t4; + cfg.t.cfg.s.snDLSAP.tmr.t4.val = k->t4; cfg.t.cfg.s.snDLSAP.tmr.t5.enb = TRUE; /* t5 - waiting for second changeback ack */ - cfg.t.cfg.s.snDLSAP.tmr.t5.val = k->mtp3.t5; + cfg.t.cfg.s.snDLSAP.tmr.t5.val = k->t5; cfg.t.cfg.s.snDLSAP.tmr.t7.enb = TRUE; /* t7 - waiting for link connection ack */ - cfg.t.cfg.s.snDLSAP.tmr.t7.val = k->mtp3.t7; + cfg.t.cfg.s.snDLSAP.tmr.t7.val = k->t7; cfg.t.cfg.s.snDLSAP.tmr.t12.enb = TRUE; /* t12 - waiting for uninhibit ack */ - cfg.t.cfg.s.snDLSAP.tmr.t12.val = k->mtp3.t12; + cfg.t.cfg.s.snDLSAP.tmr.t12.val = k->t12; cfg.t.cfg.s.snDLSAP.tmr.t13.enb = TRUE; /* t13 - waiting for forced uninhibit */ - cfg.t.cfg.s.snDLSAP.tmr.t13.val = k->mtp3.t13; + cfg.t.cfg.s.snDLSAP.tmr.t13.val = k->t13; cfg.t.cfg.s.snDLSAP.tmr.t14.enb = TRUE; /* t14 - waiting for inhibition ack */ - cfg.t.cfg.s.snDLSAP.tmr.t14.val = k->mtp3.t14; + cfg.t.cfg.s.snDLSAP.tmr.t14.val = k->t14; cfg.t.cfg.s.snDLSAP.tmr.t17.enb = TRUE; /* t17 - delay to avoid oscillation of initial alignment failure */ - cfg.t.cfg.s.snDLSAP.tmr.t17.val = k->mtp3.t17; + cfg.t.cfg.s.snDLSAP.tmr.t17.val = k->t17; cfg.t.cfg.s.snDLSAP.tmr.t22.enb = TRUE; /* t22 - local inhibit test timer */ - cfg.t.cfg.s.snDLSAP.tmr.t22.val = k->mtp3.t22; + cfg.t.cfg.s.snDLSAP.tmr.t22.val = k->t22; cfg.t.cfg.s.snDLSAP.tmr.t23.enb = TRUE; /* t23 - remote inhibit test timer */ - cfg.t.cfg.s.snDLSAP.tmr.t23.val = k->mtp3.t23; + cfg.t.cfg.s.snDLSAP.tmr.t23.val = k->t23; cfg.t.cfg.s.snDLSAP.tmr.t24.enb = TRUE; /* t24 - stabilizing timer */ - cfg.t.cfg.s.snDLSAP.tmr.t24.val = k->mtp3.t24; + cfg.t.cfg.s.snDLSAP.tmr.t24.val = k->t24; cfg.t.cfg.s.snDLSAP.tmr.t31.enb = TRUE; /* t31 - BSN requested timer */ - cfg.t.cfg.s.snDLSAP.tmr.t31.val = k->mtp3.t31; + cfg.t.cfg.s.snDLSAP.tmr.t31.val = k->t31; cfg.t.cfg.s.snDLSAP.tmr.t32.enb = TRUE; /* t32 - SLT timer */ - cfg.t.cfg.s.snDLSAP.tmr.t32.val = k->mtp3.t32; + cfg.t.cfg.s.snDLSAP.tmr.t32.val = k->t32; cfg.t.cfg.s.snDLSAP.tmr.t33.enb = TRUE; /* t33 - connecting timer */ - cfg.t.cfg.s.snDLSAP.tmr.t33.val = k->mtp3.t33; + cfg.t.cfg.s.snDLSAP.tmr.t33.val = k->t33; cfg.t.cfg.s.snDLSAP.tmr.t34.enb = TRUE; /* t34 - periodic signalling link test timer */ - cfg.t.cfg.s.snDLSAP.tmr.t34.val = k->mtp3.t34; + cfg.t.cfg.s.snDLSAP.tmr.t34.val = k->t34; #if (SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || defined(TDS_ROLL_UPGRADE_SUPPORT)) cfg.t.cfg.s.snDLSAP.tmr.t35.enb = TRUE; /* t35 - false link congestion timer, same as t31 of ANSI'96*/ - cfg.t.cfg.s.snDLSAP.tmr.t35.val = k->mtp3.t35; + cfg.t.cfg.s.snDLSAP.tmr.t35.val = k->t35; cfg.t.cfg.s.snDLSAP.tmr.t36.enb = TRUE; /* t36 - false link congestion timer, same as t33 of ANSI'96*/ - cfg.t.cfg.s.snDLSAP.tmr.t36.val = k->mtp3.t36; + cfg.t.cfg.s.snDLSAP.tmr.t36.val = k->t36; cfg.t.cfg.s.snDLSAP.tmr.t37.enb = TRUE; /* t37 - false link congestion timer, same as t34 of ANSI'96*/ - cfg.t.cfg.s.snDLSAP.tmr.t37.val = k->mtp3.t37; + cfg.t.cfg.s.snDLSAP.tmr.t37.val = k->t37; cfg.t.cfg.s.snDLSAP.tmr.tCraft.enb = TRUE; /* link referral craft timer - T19 in ANSI */ - cfg.t.cfg.s.snDLSAP.tmr.tCraft.val = k->mtp3.tcraft; + cfg.t.cfg.s.snDLSAP.tmr.tCraft.val = k->tcraft; #endif #ifdef SDT2 cfg.t.cfg.s.snDLSAP.tmr.tFlc.enb = TRUE; /* flow control timer */ @@ -1217,6 +1381,11 @@ int ftmod_ss7_isup_ckt_config(int id) /* insert the destination Entity */ pst.dstEnt = ENTSI; + /* check the for the correct ProcId and make sure it goes to the right system */ + if (g_ftdm_sngss7_data.cfg.procId != 1) { + pst.dstProcId = 1; + } + /*clear the configuration structure*/ memset(&cfg, 0x0, sizeof(SiMngmt)); @@ -1417,11 +1586,11 @@ int ftmod_ss7_isup_isap_config(int id) } /******************************************************************************/ -int ftmod_ss7_cc_isap_config(int id) +int ftmod_ss7_cc_isap_config(int dstProcId) { CcMngmt cfg; Pst pst; - sng_isap_t *k = &g_ftdm_sngss7_data.cfg.isap[id]; + /* initalize the post structure */ smPstInit(&pst); @@ -1441,11 +1610,11 @@ int ftmod_ss7_cc_isap_config(int id) cfg.hdr.entId.inst = S_INST; cfg.hdr.elmId.elmnt = STISAP; - cfg.hdr.elmId.elmntInst1 = k->id; + cfg.hdr.elmId.elmntInst1 = 1; - cfg.t.cfg.s.ccISAP.suId = k->suId; - cfg.t.cfg.s.ccISAP.spId = k->spId; - cfg.t.cfg.s.ccISAP.pst.dstProcId = SFndProcId(); + cfg.t.cfg.s.ccISAP.suId = 1; + cfg.t.cfg.s.ccISAP.spId = 1; + cfg.t.cfg.s.ccISAP.pst.dstProcId = dstProcId; cfg.t.cfg.s.ccISAP.pst.dstEnt = ENTSI; cfg.t.cfg.s.ccISAP.pst.dstInst = S_INST; cfg.t.cfg.s.ccISAP.pst.srcProcId = SFndProcId(); @@ -1461,6 +1630,70 @@ int ftmod_ss7_cc_isap_config(int id) } /******************************************************************************/ +int ftmod_ss7_relay_chan_config(int id) +{ + RyMngmt cfg; /*configuration structure*/ + Pst pst; /*post structure*/ + sng_relay_t *k = &g_ftdm_sngss7_data.cfg.relay[id]; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTRY; + + /* clear the configuration structure */ + memset(&cfg, 0x0, sizeof(RyMngmt)); + + /* fill in some general sections of the header */ + smHdrInit(&cfg.hdr); + + /*fill in the specific fields of the header */ + cfg.hdr.msgType = TCFG; + cfg.hdr.entId.ent = ENTRY; + cfg.hdr.entId.inst = S_INST; + cfg.hdr.elmId.elmnt = STCHCFG; + + cfg.hdr.elmId.elmntInst1 = k->id; + + cfg.t.cfg.s.ryChanCfg.id = k->id; /* channel id */ + cfg.t.cfg.s.ryChanCfg.type = k->type; /* channel type */ +/* cfg.t.cfg.s.ryChanCfg.msInd =;*/ /* master/slave indicator */ + if (k->type == LRY_CT_TCP_LISTEN) { + cfg.t.cfg.s.ryChanCfg.low = 0; /* low proc id for channel */ + cfg.t.cfg.s.ryChanCfg.high = 0; /* high proc id for channel */ + } else { + cfg.t.cfg.s.ryChanCfg.low = k->procId; /* low proc id for channel */ + cfg.t.cfg.s.ryChanCfg.high = k->procId; /* high proc id for channel */ + } + cfg.t.cfg.s.ryChanCfg.nmbScanQ = MAX_RELAY_NMBSCAN; /* number of times to scan the queue */ + cfg.t.cfg.s.ryChanCfg.flags = LRY_FLG_INTR; /* flags */ + cfg.t.cfg.s.ryChanCfg.congThrsh = MAX_RELAY_CONGTHRSH; /* congestion threshold */ + cfg.t.cfg.s.ryChanCfg.dropThrsh = 0; /* drop threshold */ + cfg.t.cfg.s.ryChanCfg.contThrsh = MAX_RELAY_CONGTHRSH + 1; /* continue threshold */ + cfg.t.cfg.s.ryChanCfg.kaTxTmr.enb = 1; /* keep alive transmit timer config */ + cfg.t.cfg.s.ryChanCfg.kaTxTmr.val = RY_TX_KP_ALIVE_TMR; + cfg.t.cfg.s.ryChanCfg.kaRxTmr.enb = 1; /* keep alive receive timer config */ + cfg.t.cfg.s.ryChanCfg.kaRxTmr.val = RY_RX_KP_ALIVE_TMR; + cfg.t.cfg.s.ryChanCfg.btTmr.enb = 1; /* boot timer */ + cfg.t.cfg.s.ryChanCfg.btTmr.val = RY_BT_TMR; + cfg.t.cfg.s.ryChanCfg.region = S_REG; /* Relay region */ + cfg.t.cfg.s.ryChanCfg.pool = S_POOL; /* Relay pool */ +#if (RY_ENBUDPSOCK || RY_ENBTCPSOCK) + cfg.t.cfg.s.ryChanCfg.listenPortNo = k->port; /* Listen Port of Rx Relay Channel*/ + strncpy(cfg.t.cfg.s.ryChanCfg.transmittoHostName, k->hostname, (size_t)RY_REMHOSTNAME_SIZE); + cfg.t.cfg.s.ryChanCfg.transmittoPortNo = k->port; /* TransmitTo PortId for Tx Relay Channel */ + cfg.t.cfg.s.ryChanCfg.targetProcId = k->procId; /* procId of the node present in the other end of this channel */ +# ifdef LRY1 + cfg.t.cfg.s.ryChanCfg.sockParam =; /* Socket Parameters */ +# endif /* LRY1 */ +# ifdef LRYV2 + cfg.t.cfg.s.ryChanCfg.selfHostName[RY_REMHOSTNAME_SIZE]; +# endif /* LRY2 */ +#endif /* RY_ENBUDPSOCK || RY_ENBTCPSOCK */ + + return(sng_cfg_relay(&pst, &cfg)); +} /******************************************************************************/ /* For Emacs: 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 dc2d24f42a..4ab4359c93 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 @@ -46,6 +46,8 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream); +static ftdm_status_t handle_show_procId(ftdm_stream_handle_t *stream); + static ftdm_status_t handle_set_function_trace(ftdm_stream_handle_t *stream, int on, int level); static ftdm_status_t handle_set_message_trace(ftdm_stream_handle_t *stream, int on, int level); static ftdm_status_t handle_set_inhibit(ftdm_stream_handle_t *stream, char *name); @@ -67,6 +69,8 @@ static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int c static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); +static ftdm_status_t handle_bind_link(ftdm_stream_handle_t *stream, char *name); +static ftdm_status_t handle_unbind_link(ftdm_stream_handle_t *stream, char *name); static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *name); static ftdm_status_t handle_deactivate_link(ftdm_stream_handle_t *stream, char *name); @@ -76,9 +80,12 @@ static ftdm_status_t handle_deactivate_linkset(ftdm_stream_handle_t *stream, cha static ftdm_status_t handle_tx_lpo(ftdm_stream_handle_t *stream, char *name); static ftdm_status_t handle_tx_lpr(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t handle_status_link(ftdm_stream_handle_t *stream, char *name); +static ftdm_status_t handle_status_mtp3link(ftdm_stream_handle_t *stream, char *name); +static ftdm_status_t handle_status_mtp2link(ftdm_stream_handle_t *stream, char *name); static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *name); +static ftdm_status_t handle_status_relay(ftdm_stream_handle_t *stream, char *name); + static ftdm_status_t extract_span_chan(char *argv[10], int pos, int *span, int *chan); static ftdm_status_t check_arg_count(int args, int min); /******************************************************************************/ @@ -111,18 +118,29 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha if (!strcasecmp(argv[c], "status")) { /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; c++; - if (!strcasecmp(argv[c], "link")) { + if (!strcasecmp(argv[c], "mtp3")) { /******************************************************************/ c++; - handle_status_link(stream, argv[c]); + handle_status_mtp3link(stream, argv[c]); + /******************************************************************/ + } else if (!strcasecmp(argv[c], "mtp2")) { + /******************************************************************/ + c++; + handle_status_mtp2link(stream, argv[c]); /******************************************************************/ } else if (!strcasecmp(argv[c], "linkset")) { /******************************************************************/ c++; handle_status_linkset(stream, argv[c]); /******************************************************************/ + } else if (!strcasecmp(argv[c], "relay")) { + /******************************************************************/ + c++; + handle_status_relay(stream, argv[c]); + /******************************************************************/ } else if (!strcasecmp(argv[c], "span")) { /******************************************************************/ if (check_arg_count(argc, 6)) goto handle_cli_error_argc; @@ -256,6 +274,10 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha sts.rx_frm, sts.rx_err, sts.rx_fisu, sts.rx_lssu, sts.rx_msu); */ /**********************************************************************/ + } else if (!strcasecmp(argv[c], "procid")) { + /**********************************************************************/ + handle_show_procId(stream); + /**********************************************************************/ } else { /**********************************************************************/ stream->write_function(stream, "Unknown \"show\" command\n"); @@ -534,6 +556,44 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha /**********************************************************************/ } /**************************************************************************/ + } else if (!strcasecmp(argv[c], "bind")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "link")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_bind_link(stream, argv[c]); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"bind\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "unbind")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "link")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_unbind_link(stream, argv[c]); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"bind\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ } else if (!strcasecmp(argv[c], "activate")) { /**************************************************************************/ if (check_arg_count(argc, 2)) goto handle_cli_error_argc; @@ -649,6 +709,16 @@ static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream) return FTDM_SUCCESS; } +/******************************************************************************/ +static ftdm_status_t handle_show_procId(ftdm_stream_handle_t *stream) +{ + int procId = sng_get_procId(); + + stream->write_function(stream, "Local ProcId = %d\n", procId); + + return FTDM_SUCCESS; +} + /******************************************************************************/ static ftdm_status_t handle_set_function_trace(ftdm_stream_handle_t *stream, int on, int level) { @@ -693,7 +763,7 @@ static ftdm_status_t handle_show_free(ftdm_stream_handle_t *stream, int span, in int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; free = 0; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -756,7 +826,7 @@ static ftdm_status_t handle_show_inuse(ftdm_stream_handle_t *stream, int span, i int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; in_use = 0; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -826,7 +896,7 @@ static ftdm_status_t handle_show_inreset(ftdm_stream_handle_t *stream, int span, int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; in_reset = 0; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -848,10 +918,10 @@ static ftdm_status_t handle_show_inreset(ftdm_stream_handle_t *stream, int span, } if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - if ((sngss7_test_flag(ss7_info, FLAG_RESET_RX)) || - (sngss7_test_flag(ss7_info, FLAG_RESET_TX)) || - (sngss7_test_flag(ss7_info, FLAG_GRP_RESET_RX)) || - (sngss7_test_flag(ss7_info, FLAG_GRP_RESET_TX))) { + if ((sngss7_test_ckt_flag(ss7_info, FLAG_RESET_RX)) || + (sngss7_test_ckt_flag(ss7_info, FLAG_RESET_TX)) || + (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_RESET_RX)) || + (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_RESET_TX))) { if (verbose) { stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|in_reset=Y\n", @@ -862,7 +932,7 @@ static ftdm_status_t handle_show_inreset(ftdm_stream_handle_t *stream, int span, /*increment the count of circuits in reset */ in_reset++; - } /* if ((sngss7_test_flag(ss7_info, FLAG_RESET_RX) ... */ + } /* if ((sngss7_test_ckt_flag(ss7_info, FLAG_RESET_RX) ... */ } /* if ( span and chan) */ } /* if ( cic != 0) */ @@ -885,7 +955,7 @@ static ftdm_status_t handle_show_flags(ftdm_stream_handle_t *stream, int span, i int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; @@ -913,7 +983,7 @@ static ftdm_status_t handle_show_flags(ftdm_stream_handle_t *stream, int span, i for (bit = 0; bit < 33; bit++) { stream->write_function(stream, "|"); - if (ss7_info->flags & ( 0x1 << bit)) { + if (ss7_info->ckt_flags & ( 0x1 << bit)) { stream->write_function(stream, "%2d=1", bit); } else { stream->write_function(stream, "%2d=0", bit); @@ -941,7 +1011,7 @@ static ftdm_status_t handle_show_blocks(ftdm_stream_handle_t *stream, int span, int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; @@ -967,37 +1037,37 @@ static ftdm_status_t handle_show_blocks(ftdm_stream_handle_t *stream, int span, ftdmchan->physical_chan_id, ss7_info->circuit->cic); - if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) { + 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_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) { + 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_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) { + 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_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) { + 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_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX)) { + if(sngss7_test_ckt_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX)) { stream->write_function(stream, "l_mngmt=Y|"); }else { stream->write_function(stream, "l_mngmt=N|"); } - if(sngss7_test_flag(ss7_info, FLAG_CKT_UCIC_BLOCK)) { + if(sngss7_test_ckt_flag(ss7_info, FLAG_CKT_UCIC_BLOCK)) { stream->write_function(stream, "l_ucic=Y|"); }else { stream->write_function(stream, "l_ucic=N|"); @@ -1026,7 +1096,7 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN; sng_isup_ckt_t *ckt; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { /* extract the circuit to make it easier to work with */ ckt = &g_ftdm_sngss7_data.cfg.isupCkt[x]; @@ -1071,43 +1141,37 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, ftdm_signaling_status2str(sigstatus), ftdm_channel_state2str(ftdmchan->state)); - if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) { + 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_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) { + 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_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) { + 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_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) { + 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_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX)) { - stream->write_function(stream, "l_mngmt=Y|"); + + if(sngss7_test_ckt_flag(ss7_info, FLAG_RELAY_DOWN)) { + stream->write_function(stream, "relay=Y|"); }else { - stream->write_function(stream, "l_mngmt=N|"); - } + stream->write_function(stream, "relay=N|"); + } - if(sngss7_test_flag(ss7_info, FLAG_CKT_UCIC_BLOCK)) { - stream->write_function(stream, "l_ucic=Y|"); - }else { - stream->write_function(stream, "l_ucic=N|"); - } - - stream->write_function(stream, "flags=0x%X",ss7_info->flags); + stream->write_function(stream, "flags=0x%X",ss7_info->ckt_flags); stream->write_function(stream, "\n"); } /* if ( hole, sig, voice) */ @@ -1127,7 +1191,7 @@ static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int c int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; @@ -1162,7 +1226,7 @@ static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int c continue; } else { /* throw the ckt block flag */ - sngss7_set_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); + sngss7_set_ckt_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1193,7 +1257,7 @@ static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int c int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; @@ -1228,10 +1292,10 @@ static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int c continue; } else { /* throw the ckt block flag */ - sngss7_set_flag(ss7_info, FLAG_CKT_MN_UNBLK_TX); + sngss7_set_ckt_flag(ss7_info, FLAG_CKT_MN_UNBLK_TX); /* clear the block flag */ - sngss7_clear_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); + sngss7_clear_ckt_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1254,18 +1318,18 @@ static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int c } /******************************************************************************/ -static ftdm_status_t handle_status_link(ftdm_stream_handle_t *stream, char *name) +static ftdm_status_t handle_status_mtp3link(ftdm_stream_handle_t *stream, char *name) { int x = 0; SnMngmt sta; /* find the link request by it's name */ x = 1; - while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { /* send the status request */ - if (ftmod_ss7_mtplink_sta(x, &sta)) { + if (ftmod_ss7_mtp3link_sta(x, &sta)) { stream->write_function(stream, "Failed to read link=%s status\n", name); return FTDM_FAIL; } @@ -1273,9 +1337,9 @@ static ftdm_status_t handle_status_link(ftdm_stream_handle_t *stream, char *name /* print the results */ stream->write_function(stream, "%s|span=%d|chan=%d|sap=%d|state=%s|l_blk=%s|r_blk=%s|l_inhbt=%s|r_inhbt=%s\n", name, - g_ftdm_sngss7_data.cfg.mtpLink[x].mtp1.span, - g_ftdm_sngss7_data.cfg.mtpLink[x].mtp1.chan, - g_ftdm_sngss7_data.cfg.mtpLink[x].id, + g_ftdm_sngss7_data.cfg.mtp1Link[x].span, + g_ftdm_sngss7_data.cfg.mtp1Link[x].chan, + g_ftdm_sngss7_data.cfg.mtp3Link[x].id, DECODE_LSN_LINK_STATUS(sta.t.ssta.s.snDLSAP.state), (sta.t.ssta.s.snDLSAP.locBlkd) ? "Y":"N", (sta.t.ssta.s.snDLSAP.remBlkd) ? "Y":"N", @@ -1295,6 +1359,50 @@ success: return FTDM_SUCCESS; } +/******************************************************************************/ +static ftdm_status_t handle_status_mtp2link(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + SdMngmt sta; + + /* find the link request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp2Link[x].name, name)) { + + /* send the status request */ + if (ftmod_ss7_mtp2link_sta(x, &sta)) { + stream->write_function(stream, "Failed to read link=%s status\n", name); + return FTDM_FAIL; + } + + /* print the results */ + stream->write_function(stream, "%s|span=%d|chan=%d|sap=%d|state=%s|outsFrm=%d|drpdFrm=%d|lclStatus=%s|rmtStatus=%s|fsn=%d|bsn=%d\n", + name, + g_ftdm_sngss7_data.cfg.mtp1Link[x].span, + g_ftdm_sngss7_data.cfg.mtp1Link[x].chan, + g_ftdm_sngss7_data.cfg.mtp2Link[x].id, + DECODE_LSD_LINK_STATUS(sta.t.ssta.s.sdDLSAP.hlSt), + sta.t.ssta.s.sdDLSAP.psOutsFrm, + sta.t.ssta.s.sdDLSAP.cntMaDrop, + (sta.t.ssta.s.sdDLSAP.lclBsy) ? "Y":"N", + (sta.t.ssta.s.sdDLSAP.remBsy) ? "Y":"N", + sta.t.ssta.s.sdDLSAP.fsn, + sta.t.ssta.s.sdDLSAP.bsn); + + goto success; + } + + /* move to the next link */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Failed to find link=\"%s\"\n", name); + +success: + return FTDM_SUCCESS; +} + /******************************************************************************/ static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *name) { @@ -1338,17 +1446,17 @@ static ftdm_status_t handle_set_inhibit(ftdm_stream_handle_t *stream, char *name /* find the link request by it's name */ x = 1; - while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { /* send the inhibit request */ - if (ftmod_ss7_inhibit_mtplink(x)) { + if (ftmod_ss7_inhibit_mtp3link(x)) { stream->write_function(stream, "Failed to inhibit link=%s\n", name); return FTDM_FAIL; } /* print the new status of the link */ - handle_status_link(stream, &name[0]); + handle_status_mtp3link(stream, &name[0]); goto success; } @@ -1370,17 +1478,17 @@ static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *na /* find the link request by it's name */ x = 1; - while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { /* send the uninhibit request */ - if (ftmod_ss7_uninhibit_mtplink(x)) { + if (ftmod_ss7_uninhibit_mtp3link(x)) { stream->write_function(stream, "Failed to uninhibit link=%s\n", name); return FTDM_FAIL; } /* print the new status of the link */ - handle_status_link(stream, &name[0]); + handle_status_mtp3link(stream, &name[0]); goto success; } @@ -1404,7 +1512,7 @@ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int c int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; @@ -1429,7 +1537,7 @@ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int c ftdm_mutex_lock(ftdmchan->mutex); /* throw the reset flag */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); switch (ftdmchan->state) { /**************************************************************************/ @@ -1476,7 +1584,7 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c return FTDM_SUCCESS; } - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -1500,9 +1608,9 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c continue; } else { /* throw the grp reset flag */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX); if (ftdmchan->physical_chan_id == chan) { - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_BASE); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_BASE); sngss7_span->tx_grs.circuit = sngss7_info->circuit->id; sngss7_span->tx_grs.range = range-1; } @@ -1523,7 +1631,7 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c x++; } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -1565,7 +1673,7 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c return FTDM_SUCCESS; } - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -1582,7 +1690,7 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c ftdm_mutex_lock(ftdmchan->mutex); /* throw the grp maint. block flag */ - sngss7_set_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); /* bring the sig status down */ sigev.chan_id = ftdmchan->chan_id; @@ -1622,7 +1730,7 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c /* send the circuit group block */ ft_to_sngss7_cgb(main_chan); - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -1665,7 +1773,7 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c return FTDM_SUCCESS; } - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -1682,7 +1790,7 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c ftdm_mutex_lock(ftdmchan->mutex); /* throw the grp maint. block flag */ - sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); /* bring the sig status up */ sigev.chan_id = ftdmchan->chan_id; @@ -1722,7 +1830,7 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c /* send the circuit group block */ ft_to_sngss7_cgu(main_chan); - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -1745,6 +1853,68 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c return FTDM_SUCCESS; } +/******************************************************************************/ +static ftdm_status_t handle_bind_link(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the link request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { + + /* send the uninhibit request */ + if (ftmod_ss7_bind_mtp3link(g_ftdm_sngss7_data.cfg.mtp3Link[x].mtp2Id)) { + stream->write_function(stream, "Failed to bind link=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the link */ + handle_status_mtp3link(stream, &name[0]); + goto success; + } + + /* move to the next link */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find link=%s\n", name); + +success: + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static ftdm_status_t handle_unbind_link(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the link request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { + + /* send the uninhibit request */ + if (ftmod_ss7_unbind_mtp3link(g_ftdm_sngss7_data.cfg.mtp3Link[x].mtp2Id)) { + stream->write_function(stream, "Failed to bind link=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the link */ + handle_status_mtp3link(stream, &name[0]); + goto success; + } + + /* move to the next link */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find link=%s\n", name); + +success: + return FTDM_SUCCESS; +} + /******************************************************************************/ static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *name) { @@ -1752,17 +1922,17 @@ static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *na /* find the link request by it's name */ x = 1; - while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { /* send the uninhibit request */ - if (ftmod_ss7_activate_mtplink(x)) { + if (ftmod_ss7_activate_mtp3link(x)) { stream->write_function(stream, "Failed to activate link=%s\n", name); return FTDM_FAIL; } /* print the new status of the link */ - handle_status_link(stream, &name[0]); + handle_status_mtp3link(stream, &name[0]); goto success; } @@ -1783,17 +1953,17 @@ static ftdm_status_t handle_deactivate_link(ftdm_stream_handle_t *stream, char * /* find the link request by it's name */ x = 1; - while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { /* send the deactivate request */ - if (ftmod_ss7_deactivate2_mtplink(x)) { + if (ftmod_ss7_deactivate2_mtp3link(x)) { stream->write_function(stream, "Failed to deactivate link=%s\n", name); return FTDM_FAIL; } /* print the new status of the link */ - handle_status_link(stream, &name[0]); + handle_status_mtp3link(stream, &name[0]); goto success; } @@ -1877,17 +2047,17 @@ static ftdm_status_t handle_tx_lpo(ftdm_stream_handle_t *stream, char *name) /* find the link request by it's name */ x = 1; - while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { /* send the uninhibit request */ - if (ftmod_ss7_lpo_mtplink(x)) { + if (ftmod_ss7_lpo_mtp3link(x)) { stream->write_function(stream, "Failed set LPO link=%s\n", name); return FTDM_FAIL; } /* print the new status of the link */ - handle_status_link(stream, &name[0]); + handle_status_mtp3link(stream, &name[0]); goto success; } @@ -1908,17 +2078,17 @@ static ftdm_status_t handle_tx_lpr(ftdm_stream_handle_t *stream, char *name) /* find the link request by it's name */ x = 1; - while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { /* send the uninhibit request */ - if (ftmod_ss7_lpr_mtplink(x)) { + if (ftmod_ss7_lpr_mtp3link(x)) { stream->write_function(stream, "Failed set LPR link=%s\n", name); return FTDM_FAIL; } /* print the new status of the link */ - handle_status_link(stream, &name[0]); + handle_status_mtp3link(stream, &name[0]); goto success; } @@ -1932,6 +2102,47 @@ success: return FTDM_SUCCESS; } +/******************************************************************************/ +static ftdm_status_t handle_status_relay(ftdm_stream_handle_t *stream, char *name) +{ + RyMngmt sta; + int x = 0; + + memset(&sta, 0x0, sizeof(sta)); + + + /* find the channel request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.relay[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.relay[x].name, name)) { + + if (ftmod_ss7_relay_status(g_ftdm_sngss7_data.cfg.relay[x].id, &sta)) { + stream->write_function(stream, "Failed to read relay =%s status\n", name); + return FTDM_FAIL; + } + + /* print the results */ + stream->write_function(stream, "%s|sap=%d|type=%d|port=%d|hostname=%s|procId=%d|status=%s\n", + name, + g_ftdm_sngss7_data.cfg.relay[x].id, + g_ftdm_sngss7_data.cfg.relay[x].type, + g_ftdm_sngss7_data.cfg.relay[x].port, + g_ftdm_sngss7_data.cfg.relay[x].hostname, + g_ftdm_sngss7_data.cfg.relay[x].procId, + DECODE_LRY_CHAN_STATUS(sta.t.ssta.rySta.cStatus)); + + goto success; + } + + /* move to the next link */ + x++; + + } /* g_ftdm_sngss7_data.cfg.relay[x].id */ + +success: + return FTDM_SUCCESS; +} + /******************************************************************************/ static ftdm_status_t extract_span_chan(char *argv[10], int pos, int *span, int *chan) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c index 87733dd594..c1b18e529a 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c @@ -48,19 +48,31 @@ static int ftmod_ss7_enable_isap(int suId); static int ftmod_ss7_enable_nsap(int suId); static int ftmod_ss7_enable_mtpLinkSet(int lnkSetId); -int ftmod_ss7_inhibit_mtplink(uint32_t id); -int ftmod_ss7_uninhibit_mtplink(uint32_t id); +int ftmod_ss7_inhibit_mtp3link(uint32_t id); +int ftmod_ss7_uninhibit_mtp3link(uint32_t id); -int ftmod_ss7_activate_mtplink(uint32_t id); -int ftmod_ss7_deactivate_mtplink(uint32_t id); -int ftmod_ss7_deactivate2_mtplink(uint32_t id); +int ftmod_ss7_bind_mtp3link(uint32_t id); +int ftmod_ss7_unbind_mtp3link(uint32_t id); +int ftmod_ss7_activate_mtp3link(uint32_t id); +int ftmod_ss7_deactivate_mtp3link(uint32_t id); +int ftmod_ss7_deactivate2_mtp3link(uint32_t id); int ftmod_ss7_activate_mtplinkSet(uint32_t id); int ftmod_ss7_deactivate_mtplinkSet(uint32_t id); int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id); -int ftmod_ss7_lpo_mtplink(uint32_t id); -int ftmod_ss7_lpr_mtplink(uint32_t id); +int ftmod_ss7_lpo_mtp3link(uint32_t id); +int ftmod_ss7_lpr_mtp3link(uint32_t id); + +int ftmod_ss7_shutdown_isup(void); +int ftmod_ss7_shutdown_mtp3(void); +int ftmod_ss7_shutdown_mtp2(void); +int ftmod_ss7_shutdown_relay(void); + +int ftmod_ss7_disable_grp_mtp3Link(uint32_t procId); +int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId); + +int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -71,7 +83,7 @@ int ft_to_sngss7_activate_all(void) x = 1; while (g_ftdm_sngss7_data.cfg.isap[x].id != 0) { /* check if this link has already been actived */ - if (!(g_ftdm_sngss7_data.cfg.isap[x].flags & ACTIVE)) { + if (!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_ACTIVE)) { if (ftmod_ss7_enable_isap(x)) { SS7_CRITICAL("ISAP %d Enable: NOT OK\n", x); @@ -80,9 +92,9 @@ int ft_to_sngss7_activate_all(void) SS7_INFO("ISAP %d Enable: OK\n", x); } - /* set the ACTIVE flag */ - g_ftdm_sngss7_data.cfg.isap[x].flags |= ACTIVE; - } /* if !ACTIVE */ + /* set the SNGSS7_ACTIVE flag */ + g_ftdm_sngss7_data.cfg.isap[x].flags |= SNGSS7_ACTIVE; + } /* if !SNGSS7_ACTIVE */ x++; } /* while (g_ftdm_sngss7_data.cfg.isap[x].id != 0) */ @@ -90,7 +102,7 @@ int ft_to_sngss7_activate_all(void) x = 1; while (g_ftdm_sngss7_data.cfg.nsap[x].id != 0) { /* check if this link has already been actived */ - if (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & ACTIVE)) { + if (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_ACTIVE)) { if (ftmod_ss7_enable_nsap(x)) { SS7_CRITICAL("NSAP %d Enable: NOT OK\n", x); @@ -99,31 +111,33 @@ int ft_to_sngss7_activate_all(void) SS7_INFO("NSAP %d Enable: OK\n", x); } - /* set the ACTIVE flag */ - g_ftdm_sngss7_data.cfg.nsap[x].flags |= ACTIVE; - } /* if !ACTIVE */ + /* set the SNGSS7_ACTIVE flag */ + g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_ACTIVE; + } /* if !SNGSS7_ACTIVE */ x++; } /* while (g_ftdm_sngss7_data.cfg.nsap[x].id != 0) */ - x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) { - /* check if this link has already been actived */ - if (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & ACTIVE)) { - - if (ftmod_ss7_enable_mtpLinkSet(x)) { - SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name); - return 1; - } else { - SS7_INFO("LinkSet \"%s\" Enable: OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name); - } - - /* set the ACTIVE flag */ - g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= ACTIVE; - } /* if !ACTIVE */ - - x++; - } /* while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) */ + if (g_ftdm_sngss7_data.cfg.mtpRoute[1].id != 0) { + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) { + /* check if this link has already been actived */ + if (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_ACTIVE)) { + + if (ftmod_ss7_enable_mtpLinkSet(x)) { + SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name); + return 1; + } else { + SS7_INFO("LinkSet \"%s\" Enable: OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name); + } + + /* set the SNGSS7_ACTIVE flag */ + g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_ACTIVE; + } /* if !SNGSS7_ACTIVE */ + + x++; + } /* while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) */ + } return 0; } @@ -223,7 +237,7 @@ static int ftmod_ss7_enable_mtpLinkSet(int lnkSetId) } /******************************************************************************/ -int ftmod_ss7_inhibit_mtplink(uint32_t id) +int ftmod_ss7_inhibit_mtp3link(uint32_t id) { SnMngmt cntrl; Pst pst; @@ -253,7 +267,7 @@ int ftmod_ss7_inhibit_mtplink(uint32_t id) } /******************************************************************************/ -int ftmod_ss7_uninhibit_mtplink(uint32_t id) +int ftmod_ss7_uninhibit_mtp3link(uint32_t id) { SnMngmt cntrl; Pst pst; @@ -283,7 +297,7 @@ int ftmod_ss7_uninhibit_mtplink(uint32_t id) } /******************************************************************************/ -int ftmod_ss7_activate_mtplink(uint32_t id) +int ftmod_ss7_bind_mtp3link(uint32_t id) { SnMngmt cntrl; Pst pst; @@ -304,7 +318,67 @@ int ftmod_ss7_activate_mtplink(uint32_t id) cntrl.hdr.entId.ent = ENTSN; cntrl.hdr.entId.inst = S_INST; cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; + + cntrl.t.cntrl.action = ABND; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_unbind_mtp3link(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STDLSAP; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; + + cntrl.t.cntrl.action = AUBND_DIS; /* unbind and disable */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_activate_mtp3link(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STDLSAP; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; cntrl.t.cntrl.action = AENA; /* Activate */ cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ @@ -313,7 +387,7 @@ int ftmod_ss7_activate_mtplink(uint32_t id) } /******************************************************************************/ -int ftmod_ss7_deactivate_mtplink(uint32_t id) +int ftmod_ss7_deactivate_mtp3link(uint32_t id) { SnMngmt cntrl; Pst pst; @@ -334,7 +408,7 @@ int ftmod_ss7_deactivate_mtplink(uint32_t id) cntrl.hdr.entId.ent = ENTSN; cntrl.hdr.entId.inst = S_INST; cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; cntrl.t.cntrl.action = ADISIMM; /* Deactivate */ cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ @@ -343,7 +417,7 @@ int ftmod_ss7_deactivate_mtplink(uint32_t id) } /******************************************************************************/ -int ftmod_ss7_deactivate2_mtplink(uint32_t id) +int ftmod_ss7_deactivate2_mtp3link(uint32_t id) { SnMngmt cntrl; Pst pst; @@ -364,7 +438,7 @@ int ftmod_ss7_deactivate2_mtplink(uint32_t id) cntrl.hdr.entId.ent = ENTSN; cntrl.hdr.entId.inst = S_INST; cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; cntrl.t.cntrl.action = ADISIMM_L2; /* Deactivate...layer 2 only */ cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ @@ -463,7 +537,7 @@ int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id) } /******************************************************************************/ -int ftmod_ss7_lpo_mtplink(uint32_t id) +int ftmod_ss7_lpo_mtp3link(uint32_t id) { SnMngmt cntrl; Pst pst; @@ -484,7 +558,7 @@ int ftmod_ss7_lpo_mtplink(uint32_t id) cntrl.hdr.entId.ent = ENTSN; cntrl.hdr.entId.inst = S_INST; cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; cntrl.t.cntrl.action = ACTION_LPO; /* Activate */ cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ @@ -493,7 +567,7 @@ int ftmod_ss7_lpo_mtplink(uint32_t id) } /******************************************************************************/ -int ftmod_ss7_lpr_mtplink(uint32_t id) +int ftmod_ss7_lpr_mtp3link(uint32_t id) { SnMngmt cntrl; Pst pst; @@ -514,7 +588,7 @@ int ftmod_ss7_lpr_mtplink(uint32_t id) cntrl.hdr.entId.ent = ENTSN; cntrl.hdr.entId.inst = S_INST; cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; cntrl.t.cntrl.action = ACTION_LPR; /* Activate */ cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ @@ -523,6 +597,216 @@ int ftmod_ss7_lpr_mtplink(uint32_t id) } /******************************************************************************/ +int ftmod_ss7_shutdown_isup(void) +{ + SiMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSI; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SiMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSI; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STGEN; + + cntrl.t.cntrl.action = ASHUTDOWN; /* shutdown */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_isup(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_shutdown_mtp3(void) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STGEN; + + cntrl.t.cntrl.action = ASHUTDOWN; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_shutdown_mtp2(void) +{ + SdMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSD; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SdMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSD; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STGEN; + + cntrl.t.cntrl.action = ASHUTDOWN; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp2(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_shutdown_relay(void) +{ + RyMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTRY; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(RyMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTRY; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STGEN; + + cntrl.t.cntrl.action = ASHUTDOWN; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_relay(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_disable_grp_mtp3Link(uint32_t procId) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STGRDLSAP; /* group DLSAP */ + + cntrl.t.cntrl.ctlType.groupKey.dstProcId = procId; /* all SAPS to this ProcId */ + + cntrl.t.cntrl.action = AUBND_DIS; /* disable and unbind */ + cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); + +} + +/******************************************************************************/ +int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STGRDLSAP; /* group DLSAP */ + + cntrl.t.cntrl.ctlType.groupKey.dstProcId = procId; /* all SAPS to this ProcId */ + + cntrl.t.cntrl.action = ABND_ENA; /* bind and enable */ + cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); + +} + +/******************************************************************************/ +int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId) +{ + SdMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSD; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(cntrl)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSD; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STGRNSAP; /* group NSAP */ + + cntrl.t.cntrl.par.dstProcId = procId; /* all SAPS to this ProcId */ + + cntrl.t.cntrl.action = AUBND_DIS; /* disable and unbind */ + cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */ + + return (sng_cntrl_mtp2(&pst, &cntrl)); + +} /******************************************************************************/ /* For Emacs: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c index dcfb7f79e0..3a6fca7376 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c @@ -99,21 +99,21 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE)) { SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IAM (glare)\n", sngss7_info->circuit->cic); } else { SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IAM\n", sngss7_info->circuit->cic); } /* check if the circuit has a remote block */ - if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { /* as per Q.764, 2.8.2.3 xiv ... remove the block from this channel */ - sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - sngss7_clear_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); - sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); /* KONRAD FIX ME : check in case there is a ckt and grp block */ } @@ -134,7 +134,7 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdmchan->physical_chan_id); /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_flag(sngss7_info, FLAG_LOCAL_REL); + sngss7_set_ckt_flag(sngss7_info, FLAG_LOCAL_REL); ftdmchan->caller_data.hangup_cause = 41; @@ -253,26 +253,26 @@ handle_glare: sngss7_info->glare.circuit = circuit; memcpy(&sngss7_info->glare.iam, siConEvnt, sizeof(*siConEvnt)); - if (!(sngss7_test_flag(sngss7_info, FLAG_GLARE))) { + if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE))) { /* glare, throw the flag */ - sngss7_set_flag(sngss7_info, FLAG_GLARE); + sngss7_set_ckt_flag(sngss7_info, FLAG_GLARE); /* setup the hangup cause */ ftdmchan->caller_data.hangup_cause = 34; /* Circuit Congrestion */ /* this is a remote hangup request */ - sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); + sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); /* move the state of the channel to Terminating to end the call */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - } /* if (!(sngss7_test_flag(sngss7_info, FLAG_GLARE))) */ + } /* if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE))) */ break; /**************************************************************************/ default: /* should not have gotten an IAM while in this state */ SS7_ERROR_CHAN(ftdmchan, "Got IAM on channel in invalid state(%s)...reset!\n", ftdm_channel_state2str (ftdmchan->state)); /* reset the cic */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); /* move the state of the channel to RESTART to force a reset */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); @@ -341,7 +341,7 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdm_channel_state2str (ftdmchan->state)); /* reset the cic */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); /* go to RESTART */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); @@ -545,7 +545,7 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ANM/CON\n", sngss7_info->circuit->cic); /* throw the TX reset flag */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX); /* go to RESTART */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); @@ -597,7 +597,7 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ } /* this is a remote hangup request */ - sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); + sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); /* move the state of the channel to CANCEL to end the call */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); @@ -618,7 +618,7 @@ ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); } /* this is a remote hangup request */ - sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); + sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); /* move the state of the channel to TERMINATING to end the call */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); @@ -631,7 +631,7 @@ ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); /* since we need to acknowledge the hang up set the flag for remote release */ - sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); + sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); /* go to hangup complete to send the RLC */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); @@ -645,7 +645,7 @@ ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); default: /* throw the reset flag */ - sngss7_set_flag(sngss7_info, FLAG_RESET_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_RX); /* set the state to RESTART */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); @@ -1134,13 +1134,13 @@ ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t ci /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE)) { /* the glare flag is already up so it was caught ... do nothing */ SS7_DEBUG_CHAN(ftdmchan, "Glare flag is already up...nothing to do!%s\n", " "); } else { SS7_DEBUG_CHAN(ftdmchan, "Glare flag is not up yet...indicating glare from reattempt!%s\n", " "); /* glare, throw the flag */ - sngss7_set_flag(sngss7_info, FLAG_GLARE); + sngss7_set_ckt_flag(sngss7_info, FLAG_GLARE); /* clear any existing glare data from the channel */ memset(&sngss7_info->glare, 0x0, sizeof(sngss7_glare_data_t)); @@ -1149,7 +1149,7 @@ ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t ci ftdmchan->caller_data.hangup_cause = 34; /* Circuit Congrestion */ /* this is a remote hangup request */ - sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); + sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); /* move the state of the channel to Terminating to end the call */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); @@ -1179,7 +1179,7 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED); /* go through all the circuits now and find any other circuits on this infId */ - i = 1; + i = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { /* check that the infId matches and that this is not a siglink */ @@ -1200,7 +1200,7 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_IN_THREAD)) { SS7_DEBUG_CHAN(ftdmchan, "Rx PAUSE%s\n", ""); /* set the pause flag on the channel */ - sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED); + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); } /* unlock the channel again before we exit */ @@ -1234,7 +1234,7 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu sngss7_clear_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED); /* go through all the circuits now and find any other circuits on this infId */ - i = 1; + i = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { /* check that the infId matches and that this is not a siglink */ @@ -1252,14 +1252,14 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu ftdm_mutex_lock(ftdmchan->mutex); /* only resume if we are paused */ - if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) { SS7_DEBUG_CHAN(ftdmchan, "Rx RESUME%s\n", ""); /* set the resume flag on the channel */ - sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME); + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_RESUME); /* clear the paused flag */ - sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED); + sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); } /* unlock the channel again before we exit */ @@ -1421,12 +1421,12 @@ ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdm_mutex_lock(ftdmchan->mutex); /* check if the circuit is already blocked or not */ - if (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { SS7_WARN("Received BLO on circuit that is already blocked!\n"); } /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1484,15 +1484,15 @@ ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdm_mutex_lock(ftdmchan->mutex); /* check if the channel is blocked */ - if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX))) { + if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX))) { SS7_WARN("Received UBL on circuit that is not blocked!\n"); } /* throw the unblock flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_MN_UNBLK_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_MN_UNBLK_RX); /* clear the block flag */ - sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1550,7 +1550,7 @@ ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdm_mutex_lock(ftdmchan->mutex); /* throw the reset flag */ - sngss7_set_flag(sngss7_info, FLAG_RESET_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_RX); switch (ftdmchan->state) { /**************************************************************************/ @@ -1595,7 +1595,7 @@ ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_ ftdm_mutex_lock(ftdmchan->mutex); /* throw the reset flag */ - sngss7_set_flag(sngss7_info, FLAG_RESET_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_RX); switch (ftdmchan->state) { /**************************************************************************/ @@ -1643,9 +1643,9 @@ ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ /**********************************************************************/ case FTDM_CHANNEL_STATE_RESTART: - if ( sngss7_test_flag(sngss7_info, FLAG_RESET_TX) ) { + if ( sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX) ) { /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP); /* go to DOWN */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); @@ -1667,7 +1667,7 @@ ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP); /* go to DOWN */ /*ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);*/ @@ -1795,12 +1795,12 @@ ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t ci ftdm_mutex_lock(ftdmchan->mutex); /* check if the circuit is already blocked or not */ - if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { SS7_WARN("Received local BLO on circuit that is already blocked!\n"); } /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1831,12 +1831,12 @@ ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t ci ftdm_mutex_lock(ftdmchan->mutex); /* check if the circuit is already blocked or not */ - if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { SS7_WARN("Received local UBL on circuit that is already unblocked!\n"); } /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1878,7 +1878,7 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit ftdm_mutex_lock(ftdmchan->mutex); /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); + sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1982,11 +1982,11 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ switch (blockType) { /**********************************************************************/ case 0: /* maintenance oriented */ - sngss7_set_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); break; /**********************************************************************/ case 1: /* hardware failure oriented */ - sngss7_set_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); break; /**********************************************************************/ case 2: /* reserved for national use */ @@ -2113,11 +2113,11 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ switch (blockType) { /**********************************************************************/ case 0: /* maintenance oriented */ - sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); break; /**********************************************************************/ case 1: /* hardware failure oriented */ - sngss7_clear_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); break; /**********************************************************************/ case 2: /* reserved for national use */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c index 72bd1c3fb2..76984b907b 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c @@ -409,13 +409,80 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint sngss7_chan_data_t *sngss7_info = NULL; ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *sngss7_event = NULL; + uint32_t intfId; + int x; - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; - } + /* check if the eventType is a pause/resume */ + switch (evntType) { + /**************************************************************************/ + case (SIT_STA_PAUSEIND): + case (SIT_STA_RESUMEIND): + + /* the circuit for this type of event may not exist on the local system + * so first check if the circuit is local + */ + if ((circuit >= (g_ftdm_sngss7_data.cfg.procId * 1000)) && + (circuit < ((g_ftdm_sngss7_data.cfg.procId +1) * 1000))) { + + /* the circuit is on the local system, handle normally */ + goto sta_ind_local; + } + + /* the circuit is not local, so find a local circuit with the same intfId + * by finding the orginial circuit in our array first, finding the intfId + * from there, then go through the local circuits to see if we find a + * match and use that circuit instead + */ + intfId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; + + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; + while ((g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) && + (g_ftdm_sngss7_data.cfg.isupCkt[x].id < ((g_ftdm_sngss7_data.cfg.procId +1) * 1000))) { + /**********************************************************************/ + /* confirm this is a voice channel and not a gap/sig (no ftdmchan there) */ + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != VOICE) goto move_along; + + /* compare the intfIds */ + if (g_ftdm_sngss7_data.cfg.isupCkt[x].infId == intfId) { + /* we have a match, setup the pointers to the correct values */ + circuit = x; + + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + + /* bounce out of the loop */ + break; + } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].intfId == intfId) */ + +move_along: + /* move along ... nothing to see here */ + x++; + + /**********************************************************************/ + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ + + /* check if we found any circuits that are on the intfId, drop the message + * if none are found + */ + if (ftdmchan == NULL) goto sta_ind_end; + + break; + /**************************************************************************/ + default: +sta_ind_local: + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + + break; + /**************************************************************************/ + } /* switch (evntType) */ /* initalize the sngss7_event */ sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); @@ -440,6 +507,7 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint /* enqueue this event */ ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); +sta_ind_end: SS7_FUNC_TRACE_EXIT(__FUNCTION__); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c index 3f507d6648..1dfcab4555 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c @@ -48,6 +48,8 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta); void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta); void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta); void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta); +void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta); + /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -132,17 +134,17 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /* find the name for the sap in question */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { break; } x++; } - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); } @@ -173,17 +175,17 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /* find the name for the sap in question */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { break; } x++; } - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); } ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n", @@ -196,17 +198,17 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /* find the name for the sap in question */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { break; } x++; } - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); } ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n", @@ -220,17 +222,17 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /* find the name for the sap in question */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { break; } x++; } - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); } ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : RTB Queue Len(%d)|Oldest BSN(%d)|Tx Queue Len(%d)|Outstanding Frames(%d)\n", @@ -246,17 +248,17 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /* find the name for the sap in question */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { break; } x++; } - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); } ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : RTB Queue Len(%d)\n", @@ -269,17 +271,17 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /* find the name for the sap in question */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { break; } x++; } - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); } ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %d\n", @@ -290,9 +292,11 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /**********************************************************************/ case (LCM_EVENT_UI_INV_EVT): case (LCM_EVENT_LI_INV_EVT): - ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s : %s : Primitive (%d)\n", + ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s(%d) : %s(%d) : Primitive (%d)\n", DECODE_LSD_EVENT(sta->t.usta.alarm.event), + sta->t.usta.alarm.event, DECODE_LCM_CAUSE(sta->t.usta.alarm.cause), + sta->t.usta.alarm.cause, sta->t.usta.evntParm[0]); break; /**********************************************************************/ @@ -362,22 +366,23 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta) /* find the name for the sap in question */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->hdr.elmId.elmntInst1) { + while (g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp3Link[x].id == sta->hdr.elmId.elmntInst1) { break; } x++; } - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + if (g_ftdm_sngss7_data.cfg.mtp3Link[x].id == 0) { sprintf(buf, "[SAPID:%d]", sta->hdr.elmId.elmntInst1); } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp3Link[x].name); } switch (sta->t.usta.alarm.event) { /**********************************************************************/ case (LSN_EVENT_INV_OPC_OTHER_END): + ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s : %s : OPC(0x%X%X%X%X)\n", buf, DECODE_LSN_EVENT(sta->t.usta.alarm.event), @@ -460,7 +465,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta) break; /**********************************************************************/ default: - ftdm_log(FTDM_LOG_ERROR,"[MTP3][DPC:0x%d%d%d%d] %s : %s\n", + ftdm_log(FTDM_LOG_ERROR,"[MTP3][DPC:0x%X%X%X%X] %s : %s\n", sta->t.usta.evntParm[0], sta->t.usta.evntParm[1], sta->t.usta.evntParm[2], @@ -744,7 +749,63 @@ void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta) return; } /* handle_cc_alarm */ + /******************************************************************************/ +void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta) +{ + + + switch (sta->hdr.elmId.elmnt) { + /**************************************************************************/ + case (LRY_USTA_ERR): /* ERROR */ + ftdm_log(FTDM_LOG_ERROR,"[RELAY] Error: tx procId %d: err procId %d: channel %d: seq %s: reason %s\n", + sta->t.usta.s.ryErrUsta.sendPid, + sta->t.usta.s.ryErrUsta.errPid, + sta->t.usta.s.ryErrUsta.id, + DECODE_LRY_SEQ(sta->t.usta.s.ryErrUsta.sequence), + DECODE_LRY_REASON(sta->t.usta.s.ryErrUsta.reason)); + + /* process the event */ + handle_relay_disconnect_on_error(sta); + + break; + /**************************************************************************/ + case (LRY_USTA_CNG): /* Congestion */ + ftdm_log(FTDM_LOG_ERROR,"[RELAY] Congestion: tx procId %d: rem procId %d: channel %d: %s\n", + sta->t.usta.s.ryCongUsta.sendPid, + sta->t.usta.s.ryCongUsta.remPid, + sta->t.usta.s.ryCongUsta.id, + DECODE_LRY_CONG_FLAGS(sta->t.usta.s.ryCongUsta.flags)); + break; + /**************************************************************************/ + case (LRY_USTA_UP): /* channel up */ + ftdm_log(FTDM_LOG_ERROR,"[RELAY] Channel UP: tx procId %d: channel %d\n", + sta->t.usta.s.ryUpUsta.sendPid, + sta->t.usta.s.ryUpUsta.id); + + /* process the event */ + handle_relay_connect(sta); + + break; + /**************************************************************************/ + case (LRY_USTA_DN): /* channel down */ + ftdm_log(FTDM_LOG_ERROR,"[RELAY] Channel DOWN: tx procId %d: channel %d\n", + sta->t.usta.s.ryUpUsta.sendPid, + sta->t.usta.s.ryUpUsta.id); + + /* process the event */ + handle_relay_disconnect_on_down(sta); + + break; + /**************************************************************************/ + default: + ftdm_log(FTDM_LOG_ERROR,"Unknown Relay Alram\n"); + break; + /**************************************************************************/ + } /* switch (sta->hdr.elmId.elmnt) */ + + return; +} /******************************************************************************/ /* For Emacs: 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 9016771671..c971179f1a 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 @@ -543,7 +543,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) ftdmchan->caller_data.hangup_cause = 41; /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_flag (sngss7_info, FLAG_LOCAL_REL); + sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL); /* end the call */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_CANCEL); @@ -673,7 +673,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* set the flag to indicate this hangup is started from the remote side */ - sngss7_set_flag (sngss7_info, FLAG_REMOTE_REL); + sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL); /*this state is set when the line is hanging up */ sigev.event_id = FTDM_SIGEVENT_STOP; @@ -689,15 +689,15 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* check for remote hangup flag */ - if (sngss7_test_flag (sngss7_info, FLAG_REMOTE_REL)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_REMOTE_REL)) { /* remote release ...do nothing here */ SS7_DEBUG_CHAN(ftdmchan,"Hanging up remotely requested call!%s\n", ""); - } else if (sngss7_test_flag (sngss7_info, FLAG_GLARE)) { + } else if (sngss7_test_ckt_flag (sngss7_info, FLAG_GLARE)) { /* release due to glare */ SS7_DEBUG_CHAN(ftdmchan,"Hanging up requested call do to glare%s\n", ""); } else { /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_flag (sngss7_info, FLAG_LOCAL_REL); + sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL); /*this state is set when FS is hanging up...so tell the stack */ ft_to_sngss7_rel (ftdmchan); @@ -718,16 +718,16 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) break; } - if (sngss7_test_flag (sngss7_info, FLAG_REMOTE_REL)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_REMOTE_REL)) { /* check if this hangup is from a tx RSC */ - if (sngss7_test_flag (sngss7_info, FLAG_RESET_TX)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX)) { /* go to RESTART State until RSCa is received */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RESTART); } else { /* if the hangup is from a rx RSC, rx GRS, or glare don't sent RLC */ - if (!(sngss7_test_flag(sngss7_info, FLAG_RESET_RX)) && - !(sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) && - !(sngss7_test_flag(sngss7_info, FLAG_GLARE))) { + if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_RX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE))) { /* send out the release complete */ ft_to_sngss7_rlc (ftdmchan); @@ -738,17 +738,17 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } SS7_DEBUG_CHAN(ftdmchan,"Completing remotely requested hangup!%s\n", ""); - } else if (sngss7_test_flag (sngss7_info, FLAG_LOCAL_REL)) { + } else if (sngss7_test_ckt_flag (sngss7_info, FLAG_LOCAL_REL)) { /* if this hang up is do to a rx RESET we need to sit here till the RSP arrives */ - if (sngss7_test_flag (sngss7_info, FLAG_RESET_TX_RSP)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX_RSP)) { /* go to the down state as we have already received RSC-RLC */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_DOWN); } /* if it's a local release the user sends us to down */ SS7_DEBUG_CHAN(ftdmchan,"Completing locally requested hangup!%s\n", ""); - } else if (sngss7_test_flag (sngss7_info, FLAG_GLARE)) { + } else if (sngss7_test_ckt_flag (sngss7_info, FLAG_GLARE)) { SS7_DEBUG_CHAN(ftdmchan,"Completing requested hangup due to glare!%s\n", ""); ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_DOWN); @@ -767,18 +767,18 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* check if there is a reset response that needs to be sent */ - if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_RX)) { /* send a RSC-RLC */ ft_to_sngss7_rsca (ftdmchan); /* clear the reset flag */ clear_rx_rsc_flags(sngss7_info); - } /* if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) */ + } /* if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_RX)) */ /* check if there was a GRS that needs a GRA */ - if ((sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) && - (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) && - (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT))) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX)) && + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) && + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT))) { /* check if this is the base circuit and send out the GRA * we insure that this is the last circuit to have the state change queued @@ -794,40 +794,40 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* clear the grp reset flag */ clear_rx_grs_flags(sngss7_info); - }/* if ( sngss7_test_flag ( sngss7_info, FLAG_GRP_RESET_RX ) ) */ + }/* if ( sngss7_test_ckt_flag ( sngss7_info, FLAG_GRP_RESET_RX ) ) */ /* check if we got the reset response */ - if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX_RSP)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP)) { /* clear the reset flag */ clear_tx_rsc_flags(sngss7_info); - } /* if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX_RSP)) */ + } /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP)) */ - if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) { /* clear the reset flag */ clear_tx_grs_flags(sngss7_info); /* clean out the spans GRA structure */ clear_rx_gra_data(sngss7_info); - } /* if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) */ + } /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) */ /* check if we came from reset (aka we just processed a reset) */ if ((ftdmchan->last_state == FTDM_CHANNEL_STATE_RESTART) || (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED)) { /* check if reset flags are up indicating there is more processing to do yet */ - if (!(sngss7_test_flag (sngss7_info, FLAG_RESET_TX)) && - !(sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) && - !(sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) && - !(sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX))) { + if (!(sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX)) && + !(sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_RX)) && + !(sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_TX)) && + !(sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX))) { /* now check if there is an active block */ - if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) && - !(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) && - !(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) && - !(sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) && - !(sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) && - !(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) && - !(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) { + if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) { /* check if the sig status is down, and bring it up if it isn't */ if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) { @@ -839,7 +839,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) */ } /* if !blocked */ } else { - SS7_DEBUG_CHAN(ftdmchan,"Reset flags present (0x%X)\n", sngss7_info->flags); + SS7_DEBUG_CHAN(ftdmchan,"Reset flags present (0x%X)\n", sngss7_info->ckt_flags); /* there is still another reset pending so go back to reset*/ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); @@ -858,8 +858,8 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) sngss7_info->spId = 0; /* clear any call related flags */ - sngss7_clear_flag (sngss7_info, FLAG_REMOTE_REL); - sngss7_clear_flag (sngss7_info, FLAG_LOCAL_REL); + sngss7_clear_ckt_flag (sngss7_info, FLAG_REMOTE_REL); + sngss7_clear_ckt_flag (sngss7_info, FLAG_LOCAL_REL); if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OPEN)) { @@ -869,10 +869,10 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OPEN)) */ /* check if there is a glared call that needs to be processed */ - if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE)) { /* clear the glare flag */ - sngss7_clear_flag (sngss7_info, FLAG_GLARE); + sngss7_clear_ckt_flag (sngss7_info, FLAG_GLARE); /* check if we have an IAM stored...if we don't have one just exit */ if (sngss7_info->glare.circuit != 0) { @@ -885,23 +885,23 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* clear the glare info */ memset(&sngss7_info->glare, 0x0, sizeof(sngss7_glare_data_t)); } /* if (sngss7_info->glare.circuit != 0) */ - } /* if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) */ + } /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE)) */ break; /**************************************************************************/ case FTDM_CHANNEL_STATE_RESTART: /* CICs needs a Reset */ - if (sngss7_test_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK)) { - if ((sngss7_test_flag(sngss7_info, FLAG_RESET_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX))) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK)) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX))) { SS7_DEBUG_CHAN(ftdmchan,"Incoming Reset request on CIC in UCIC block, removing UCIC block%s\n", ""); /* set the unblk flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK); + sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK); /* clear the block flag */ - sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); + sngss7_clear_ckt_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); /* process the flag */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -915,28 +915,28 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) * we can also check if we are in a PAUSED state (no point in sending message */ if ((ftdmchan->last_state != FTDM_CHANNEL_STATE_HANGUP_COMPLETE) && - (!sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED))) { + (!sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED))) { /* check if this is an outgoing RSC */ - if ((sngss7_test_flag(sngss7_info, FLAG_RESET_TX)) && - !(sngss7_test_flag(sngss7_info, FLAG_RESET_SENT))) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_SENT))) { /* send a reset request */ ft_to_sngss7_rsc (ftdmchan); - sngss7_set_flag(sngss7_info, FLAG_RESET_SENT); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_SENT); - } /* if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX)) */ + } /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX)) */ /* check if this is the first channel of a GRS (this flag is thrown when requesting reset) */ - if ( (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) && - !(sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_SENT)) && - (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_BASE))) { + if ( (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_TX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_SENT)) && + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_BASE))) { /* send out the grs */ ft_to_sngss7_grs (ftdmchan); - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_SENT); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_SENT); - }/* if ( sngss7_test_flag ( sngss7_info, FLAG_GRP_RESET_TX ) ) */ + }/* if ( sngss7_test_ckt_flag ( sngss7_info, FLAG_GRP_RESET_TX ) ) */ } /* if ( last_state != HANGUP && !PAUSED */ /* if the sig_status is up...bring it down */ @@ -946,10 +946,10 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) ftdm_span_send_signal (ftdmchan->span, &sigev); } - if (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX)) { /* set the grp reset done flag so we know we have finished this reset */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_DN); - } /* if (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX)) */ + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN); + } /* if (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX)) */ if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_INUSE)) { @@ -987,17 +987,17 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* switch (ftdmchan->last_state) */ } else { /* check if this an incoming RSC or we have a response already */ - if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX) || - sngss7_test_flag (sngss7_info, FLAG_RESET_TX_RSP) || - sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX_RSP) || - sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX_CMPLT)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_RX) || + sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX_RSP) || + sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_TX_RSP) || + sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX_CMPLT)) { - SS7_DEBUG_CHAN(ftdmchan, "Reset processed moving to DOWN (0x%X)\n", sngss7_info->flags); + SS7_DEBUG_CHAN(ftdmchan, "Reset processed moving to DOWN (0x%X)\n", sngss7_info->ckt_flags); /* go to a down state to clear the channel and send the response */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_DOWN); } else { - SS7_DEBUG_CHAN(ftdmchan, "Waiting on Reset Rsp/Grp Reset to move to DOWN (0x%X)\n", sngss7_info->flags); + SS7_DEBUG_CHAN(ftdmchan, "Waiting on Reset Rsp/Grp Reset to move to DOWN (0x%X)\n", sngss7_info->ckt_flags); } } @@ -1005,20 +1005,20 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /**************************************************************************/ case FTDM_CHANNEL_STATE_SUSPENDED: /* circuit has been blocked */ - SS7_DEBUG_CHAN(ftdmchan,"Current flags: 0x%X\n", sngss7_info->flags); + SS7_DEBUG_CHAN(ftdmchan,"Current flags: 0x%X\n", sngss7_info->ckt_flags); /**********************************************************************/ - if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_RESUME)) { SS7_DEBUG_CHAN(ftdmchan, "Processing RESUME%s\n", ""); /* clear the RESUME flag */ - sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME); + sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); /* if there are any resets present */ - if ((sngss7_test_flag (sngss7_info, FLAG_RESET_TX)) || - (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) || - (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) || - (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX))) { + if ((sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX)) || + (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_RX)) || + (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_TX)) || + (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX))) { /* go back to the reset state */ goto suspend_goto_restart; @@ -1034,7 +1034,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) goto suspend_goto_last; } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) */ - if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) { SS7_DEBUG_CHAN(ftdmchan, "Processing PAUSE%s\n", ""); /* bring the sig status down */ @@ -1044,9 +1044,9 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* go back to the last state */ goto suspend_goto_last; - } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { */ + } /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) { */ /**********************************************************************/ - if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_RX flag %s\n", ""); /* bring the sig status down */ @@ -1061,11 +1061,11 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) goto suspend_goto_last; } - if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX)){ + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX)){ SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_UNBLK_RX flag %s\n", ""); /* clear the unblock flag */ - sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX); + sngss7_clear_ckt_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX); /* bring the sig status up */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; @@ -1080,7 +1080,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /**********************************************************************/ - if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_TX)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_MN_BLOCK_TX)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_TX flag %s\n", ""); /* bring the sig status down */ @@ -1095,11 +1095,11 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) goto suspend_goto_last; } - if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX)){ + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX)){ SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_UNBLK_TX flag %s\n", ""); /* clear the unblock flag */ - sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX); + sngss7_clear_ckt_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX); /* bring the sig status up */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; @@ -1114,7 +1114,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /**********************************************************************/ - if (sngss7_test_flag (sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_LC_BLOCK_RX flag %s\n", ""); /* send a BLA */ @@ -1124,11 +1124,11 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) goto suspend_goto_last; } - if (sngss7_test_flag (sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_LC_UNBLK_RX flag %s\n", ""); /* clear the unblock flag */ - sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX); + sngss7_clear_ckt_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX); /* send a uba */ /*ft_to_sngss7_uba(ftdmchan);*/ @@ -1137,7 +1137,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) goto suspend_goto_last; } /**********************************************************************/ - if (sngss7_test_flag (sngss7_info, FLAG_CKT_UCIC_BLOCK)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_UCIC_BLOCK)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_BLOCK flag %s\n", ""); /* bring the channel signaling status to down */ @@ -1157,17 +1157,17 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) goto suspend_goto_last; } - if (sngss7_test_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_UNBLK flag %s\n", "");; /* remove the UCIC block flag */ - sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); + sngss7_clear_ckt_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); /* remove the UCIC unblock flag */ - sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK); + sngss7_clear_ckt_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK); /* throw the channel into reset to sync states */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); /* bring the channel into restart again */ goto suspend_goto_restart; @@ -1232,9 +1232,9 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call) } /* check if there is a remote block */ - if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { /* the channel is blocked...can't send any calls here */ SS7_ERROR_CHAN(ftdmchan, "Requested channel is remotely blocked, re-hunt channel!%s\n", " "); @@ -1242,9 +1242,9 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call) } /* check if there is a local block */ - if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) { /* KONRAD FIX ME : we should check if this is a TEST call and allow it */ @@ -1339,48 +1339,6 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span) SS7_INFO ("Starting span %s:%u.\n", span->name, span->span_id); - /* throw the channels in pause */ - for (x = 1; x < (span->chan_count + 1); x++) { - /* extract the channel structure and sngss7 channel data */ - ftdmchan = span->channels[x]; - if (ftdmchan->call_data == NULL) continue; - sngss7_info = ftdmchan->call_data; - sngss7_span = ftdmchan->span->signal_data; - sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; - - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if the interface is paused or resumed */ - if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { - /* throw the pause flag */ - sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME); - sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED); - } else { - /* throw the pause flag */ - sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED); - sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME); - } -#if 0 - /* throw the grp reset flag */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); - if (x == 1) { - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_BASE); - sngss7_span->tx_grs.circuit = sngss7_info->circuit->id; - sngss7_span->tx_grs.range = span->chan_count -1; - } -#else - /* throw the channel into reset */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX); -#endif - /* throw the channel to suspend */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - } - /* clear the monitor thread stop flag */ ftdm_clear_flag (span, FTDM_SPAN_STOP_THREAD); ftdm_clear_flag (span, FTDM_SPAN_IN_THREAD); @@ -1397,6 +1355,52 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span) return FTDM_FAIL; } + /* confirm the state of all isup interfaces*/ + check_status_of_all_isup_intf(); + + /* throw the channels in pause */ + for (x = 1; x < (span->chan_count + 1); x++) { + /* extract the channel structure and sngss7 channel data */ + ftdmchan = span->channels[x]; + if (ftdmchan->call_data == NULL) continue; + sngss7_info = ftdmchan->call_data; + sngss7_span = ftdmchan->span->signal_data; + sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if the interface is paused or resumed */ + if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { + SS7_DEBUG_CHAN(ftdmchan, "ISUP intf %d is PAUSED\n", sngss7_intf->id); + /* throw the pause flag */ + sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); + } else { + SS7_DEBUG_CHAN(ftdmchan, "ISUP intf %d is RESUMED\n", sngss7_intf->id); + /* throw the resume flag */ + sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_RESUME); + } +#if 0 + /* throw the grp reset flag */ + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX); + if (x == 1) { + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_BASE); + sngss7_span->tx_grs.circuit = sngss7_info->circuit->id; + sngss7_span->tx_grs.range = span->chan_count -1; + } +#else + /* throw the channel into reset */ + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); +#endif + /* throw the channel to suspend */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + } + SS7_DEBUG ("Finished starting span %s:%u.\n", span->name, span->span_id); return FTDM_SUCCESS; @@ -1537,7 +1541,6 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) sng_event.cc.sng_umsg_ind = sngss7_umsg_ind; sng_event.cc.sng_susp_ind = sngss7_susp_ind; sng_event.cc.sng_resm_ind = sngss7_resm_ind; - sng_event.cc.sng_ssp_sta_cfm = sngss7_ssp_sta_cfm; sng_event.sm.sng_log = handle_sng_log; sng_event.sm.sng_mtp1_alarm = handle_sng_mtp1_alarm; @@ -1545,9 +1548,10 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) sng_event.sm.sng_mtp3_alarm = handle_sng_mtp3_alarm; sng_event.sm.sng_isup_alarm = handle_sng_isup_alarm; sng_event.sm.sng_cc_alarm = handle_sng_cc_alarm; + sng_event.sm.sng_relay_alarm = handle_sng_relay_alarm; /* initalize sng_ss7 library */ - sng_isup_init (&sng_event); + sng_isup_init_gen(&sng_event); /* print the version of the library being used */ sng_isup_version(&major, &minor, &build); @@ -1566,7 +1570,32 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_ss7_unload) ftdm_log (FTDM_LOG_INFO, "Starting ftmod_sangoma_ss7 unload...\n"); - sng_isup_free(); + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC)) { + sng_isup_free_cc(); + } + + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) { + ftmod_ss7_shutdown_isup(); + sng_isup_free_isup(); + } + + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3)) { + ftmod_ss7_shutdown_mtp3(); + sng_isup_free_mtp3(); + } + + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) { + ftmod_ss7_shutdown_mtp2(); + sng_isup_free_mtp2(); + sng_isup_free_mtp1(); + } + + ftmod_ss7_shutdown_relay(); + sng_isup_free_relay(); + + sng_isup_free_sm(); + + sng_isup_free_gen(); ftdm_log (FTDM_LOG_INFO, "Finished ftmod_sangoma_ss7 unload!\n"); return FTDM_SUCCESS; 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 f28547f9fe..5272aa8bac 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 @@ -82,12 +82,6 @@ typedef enum { HOLE } sng_ckt_type_t; -typedef enum { - CONFIGURED = (1 << 0), - ACTIVE = (1 << 1), - SNGSS7_PAUSED = (1 << 7) -} sng_flag_t; - typedef enum { SNGSS7_LPA_FOR_COT = (1 << 0), /* send LPA when COT arrives */ SNGSS7_ACM_OBCI_BITA = (1 << 10) /* in-band indication */ @@ -98,84 +92,124 @@ typedef enum { SNG_CALLING = 2 } sng_addr_type_t; -typedef struct sng_mtp_link { - char name[MAX_NAME_LEN]; - uint32_t id; - uint32_t flags; - struct { - uint32_t span; - uint32_t chan; - } mtp1; - struct { - uint32_t lssuLength; - uint32_t errorType; - uint32_t linkType; - uint32_t mtp1Id; - uint32_t t1; - uint32_t t2; - uint32_t t3; - uint32_t t4n; - uint32_t t4e; - uint32_t t5; - uint32_t t6; - uint32_t t7; - } mtp2; - struct { - uint32_t priority; - uint32_t linkType; - uint32_t switchType; - uint32_t apc; - uint32_t spc; - uint32_t ssf; - uint32_t slc; - uint32_t linkSetId; - uint32_t mtp2Id; - uint32_t t1; - uint32_t t2; - uint32_t t3; - uint32_t t4; - uint32_t t5; - uint32_t t6; - uint32_t t7; - uint32_t t8; - uint32_t t9; - uint32_t t10; - uint32_t t11; - uint32_t t12; - uint32_t t13; - uint32_t t14; - uint32_t t15; - uint32_t t16; - uint32_t t17; - uint32_t t18; - uint32_t t19; - uint32_t t20; - uint32_t t21; - uint32_t t22; - uint32_t t23; - uint32_t t24; - uint32_t t25; - uint32_t t27; - uint32_t t28; - uint32_t t29; - uint32_t t30; - uint32_t t31; - uint32_t t32; - uint32_t t33; - uint32_t t34; - uint32_t t35; - uint32_t t36; - uint32_t t37; - uint32_t tcraft; - uint32_t tflc; - uint32_t tbnd; - } mtp3; -} sng_mtp_link_t; +typedef struct sng_mtp2_error_type { + int init; + char sng_type[MAX_NAME_LEN]; + uint32_t tril_type; +} sng_mtp2_error_type_t; + +typedef struct sng_link_type { + int init; + char sng_type[MAX_NAME_LEN]; + uint32_t tril_mtp2_type; + uint32_t tril_mtp3_type; +} sng_link_type_t; + +typedef struct sng_switch_type { + int init; + char sng_type[MAX_NAME_LEN]; + uint32_t tril_mtp3_type; + uint32_t tril_isup_type; +} sng_switch_type_t; + +typedef struct sng_ssf_type { + int init; + char sng_type[MAX_NAME_LEN]; + uint32_t tril_type; +} sng_ssf_type_t; + +typedef struct sng_cic_cntrl_type { + int init; + char sng_type[MAX_NAME_LEN]; + uint32_t tril_type; +} sng_cic_cntrl_type_t; + +typedef struct sng_mtp1_link { + char name[MAX_NAME_LEN]; + uint32_t flags; + uint32_t id; + uint32_t span; + uint32_t chan; +} sng_mtp1_link_t; + +typedef struct sng_mtp2_link { + char name[MAX_NAME_LEN]; + uint32_t flags; + uint32_t id; + uint32_t lssuLength; + uint32_t errorType; + uint32_t linkType; + uint32_t mtp1Id; + uint32_t mtp1ProcId; + uint32_t t1; + uint32_t t2; + uint32_t t3; + uint32_t t4n; + uint32_t t4e; + uint32_t t5; + uint32_t t6; + uint32_t t7; +} sng_mtp2_link_t; + +typedef struct sng_mtp3_link { + char name[MAX_NAME_LEN]; + uint32_t flags; + uint32_t id; + uint32_t priority; + uint32_t linkType; + uint32_t switchType; + uint32_t apc; + uint32_t spc; + uint32_t ssf; + uint32_t slc; + uint32_t linkSetId; + uint32_t mtp2Id; + uint32_t mtp2ProcId; + uint32_t t1; + uint32_t t2; + uint32_t t3; + uint32_t t4; + uint32_t t5; + uint32_t t6; + uint32_t t7; + uint32_t t8; + uint32_t t9; + uint32_t t10; + uint32_t t11; + uint32_t t12; + uint32_t t13; + uint32_t t14; + uint32_t t15; + uint32_t t16; + uint32_t t17; + uint32_t t18; + uint32_t t19; + uint32_t t20; + uint32_t t21; + uint32_t t22; + uint32_t t23; + uint32_t t24; + uint32_t t25; + uint32_t t27; + uint32_t t28; + uint32_t t29; + uint32_t t30; + uint32_t t31; + uint32_t t32; + uint32_t t33; + uint32_t t34; + uint32_t t35; + uint32_t t36; + uint32_t t37; + uint32_t tcraft; + uint32_t tflc; + uint32_t tbnd; +} sng_mtp3_link_t; typedef struct sng_link_set { - uint32_t id; char name[MAX_NAME_LEN]; uint32_t flags; + uint32_t id; uint32_t apc; uint32_t linkType; uint32_t switchType; @@ -186,9 +220,9 @@ typedef struct sng_link_set { } sng_link_set_t; typedef struct sng_route { - uint32_t id; char name[MAX_NAME_LEN]; uint32_t flags; + uint32_t id; uint32_t dpc; uint32_t cmbLinkSetId; uint32_t linkSetId; @@ -211,10 +245,10 @@ typedef struct sng_route { } sng_route_t; typedef struct sng_isup_intf { - uint32_t id; char name[MAX_NAME_LEN]; uint32_t options; uint32_t flags; + uint32_t id; uint32_t spc; uint32_t dpc; uint32_t switchType; @@ -222,9 +256,6 @@ typedef struct sng_isup_intf { uint32_t mtpRouteId; uint32_t ssf; uint32_t isap; - uint32_t clg_nadi; - uint32_t cld_nadi; - uint32_t min_digits; uint16_t t4; uint32_t t10; uint32_t t11; @@ -241,7 +272,6 @@ typedef struct sng_isup_intf { uint32_t t29; uint32_t t30; uint32_t t32; - uint32_t t35; uint32_t t37; uint32_t t38; uint32_t t39; @@ -251,15 +281,23 @@ typedef struct sng_isup_intf { } sng_isup_inf_t; typedef struct sng_isup_ckt { - uint32_t id; + uint32_t options; uint32_t flags; + uint32_t ckt_flags; + uint32_t procId; + uint32_t id; + uint32_t ccSpanId; uint32_t span; uint32_t chan; uint32_t type; /* VOICE/SIG/HOLE */ uint32_t cic; uint32_t infId; - uint32_t ssf; uint32_t typeCntrl; + uint32_t ssf; + uint32_t switchType; + uint32_t clg_nadi; + uint32_t cld_nadi; + uint32_t min_digits; void *obj; uint16_t t3; uint16_t t12; @@ -268,12 +306,13 @@ typedef struct sng_isup_ckt { uint16_t t15; uint16_t t16; uint16_t t17; + uint32_t t35; uint16_t tval; } sng_isup_ckt_t; typedef struct sng_nsap { - uint32_t id; uint32_t flags; + uint32_t id; uint32_t suId; uint32_t spId; uint32_t nwId; @@ -311,15 +350,30 @@ typedef struct sng_isap { uint32_t tfnlrelrsp; } sng_isap_t; +typedef struct sng_relay { + uint32_t id; + char name[MAX_NAME_LEN]; + uint32_t flags; + uint32_t type; + uint32_t port; + char hostname[RY_REMHOSTNAME_SIZE]; + uint32_t procId; +} sng_relay_t; + typedef struct sng_ss7_cfg { uint32_t spc; + uint32_t procId; char license[MAX_PATH]; char signature[MAX_PATH]; - sng_mtp_link_t mtpLink[MAX_MTP_LINKS+1]; + uint32_t flags; + sng_relay_t relay[MAX_RELAY_CHANNELS+1]; + sng_mtp1_link_t mtp1Link[MAX_MTP_LINKS+1]; + sng_mtp2_link_t mtp2Link[MAX_MTP_LINKS+1]; + sng_mtp3_link_t mtp3Link[MAX_MTP_LINKS+1]; sng_link_set_t mtpLinkSet[MAX_MTP_LINKSETS+1]; sng_route_t mtpRoute[MAX_MTP_ROUTES+1]; sng_isup_inf_t isupIntf[MAX_ISUP_INFS+1]; - sng_isup_ckt_t isupCkt[MAX_ISUP_CKTS+1]; + sng_isup_ckt_t isupCkt[10000]; /* KONRAD - only need 2000 ( and 0-1000 aren't used) since other servers are registerd else where */ sng_nsap_t nsap[MAX_NSAPS+1]; sng_isap_t isap[MAX_ISAPS+1]; }sng_ss7_cfg_t; @@ -365,7 +419,7 @@ typedef struct sngss7_chan_data { uint32_t spInstId; uint32_t spId; uint8_t globalFlg; - uint32_t flags; + uint32_t ckt_flags; sngss7_glare_data_t glare; sngss7_timer_data_t t35; }sngss7_chan_data_t; @@ -407,8 +461,6 @@ typedef struct sngss7_event_data } sngss7_event_data_t; - - typedef enum { FLAG_RESET_RX = (1 << 0), FLAG_RESET_TX = (1 << 1), @@ -439,15 +491,39 @@ typedef enum { FLAG_GRP_MN_BLOCK_RX = (1 << 26), FLAG_GRP_MN_BLOCK_TX = (1 << 27), FLAG_GRP_HW_UNBLK_TX = (1 << 28), - FLAG_GRP_MN_UNBLK_TX = (1 << 29) -} flag_t; + FLAG_GRP_MN_UNBLK_TX = (1 << 29), + FLAG_RELAY_DOWN = (1 << 30) +} sng_ckt_flag_t; + +/* valid for every cfg array except circuits */ +typedef enum { + SNGSS7_CONFIGURED = (1 << 0), + SNGSS7_ACTIVE = (1 << 1), + SNGSS7_RELAY_INIT = (1 << 3), + SNGSS7_PAUSED = (1 << 7) /* for isup interfaces */ +} sng_cfg_flag_t; + +typedef enum { + SNGSS7_SM = (1 << 0), + SNGSS7_RY = (1 << 1), + SNGSS7_MTP1 = (1 << 2), + SNGSS7_MTP2 = (1 << 3), + SNGSS7_MTP3 = (1 << 4), + SNGSS7_ISUP = (1 << 5), + SNGSS7_CC = (1 << 6) +} sng_task_flag_t; /******************************************************************************/ /* GLOBALS ********************************************************************/ -extern ftdm_sngss7_data_t g_ftdm_sngss7_data; -extern uint32_t sngss7_id; -extern ftdm_sched_t *sngss7_sched; -extern int cmbLinkSetId; +extern ftdm_sngss7_data_t g_ftdm_sngss7_data; +extern sng_ssf_type_t sng_ssf_type_map[]; +extern sng_switch_type_t sng_switch_type_map[]; +extern sng_link_type_t sng_link_type_map[]; +extern sng_mtp2_error_type_t sng_mtp2_error_type_map[]; +extern sng_cic_cntrl_type_t sng_cic_cntrl_type_map[]; +extern uint32_t sngss7_id; +extern ftdm_sched_t *sngss7_sched; +extern int cmbLinkSetId; /******************************************************************************/ /* PROTOTYPES *****************************************************************/ @@ -461,6 +537,12 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta); void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta); void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta); void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta); +void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta); + +/* in ftmod_sangoma_ss7_relay.c */ +ftdm_status_t handle_relay_connect(RyMngmt *sta); +ftdm_status_t handle_relay_disconnect_on_down(RyMngmt *sta); +ftdm_status_t handle_relay_disconnect_on_error(RyMngmt *sta); /* in ftmod_sangoma_ss7_cfg.c */ int ft_to_sngss7_cfg_all(void); @@ -484,20 +566,36 @@ int ftmod_ss7_cc_isap_config(int id); /* in ftmod_sangoma_ss7_cntrl.c */ int ft_to_sngss7_activate_all(void); -int ftmod_ss7_inhibit_mtplink(uint32_t id); -int ftmod_ss7_uninhibit_mtplink(uint32_t id); -int ftmod_ss7_activate_mtplink(uint32_t id); -int ftmod_ss7_deactivate_mtplink(uint32_t id); -int ftmod_ss7_deactivate2_mtplink(uint32_t id); +int ftmod_ss7_inhibit_mtp3link(uint32_t id); +int ftmod_ss7_uninhibit_mtp3link(uint32_t id); +int ftmod_ss7_bind_mtp3link(uint32_t id); +int ftmod_ss7_unbind_mtp3link(uint32_t id); +int ftmod_ss7_activate_mtp3link(uint32_t id); +int ftmod_ss7_deactivate_mtp3link(uint32_t id); +int ftmod_ss7_deactivate2_mtp3link(uint32_t id); int ftmod_ss7_activate_mtplinkSet(uint32_t id); int ftmod_ss7_deactivate_mtplinkSet(uint32_t id); int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id); -int ftmod_ss7_lpo_mtplink(uint32_t id); -int ftmod_ss7_lpr_mtplink(uint32_t id); +int ftmod_ss7_lpo_mtp3link(uint32_t id); +int ftmod_ss7_lpr_mtp3link(uint32_t id); + +int ftmod_ss7_shutdown_isup(void); +int ftmod_ss7_shutdown_mtp3(void); +int ftmod_ss7_shutdown_mtp2(void); +int ftmod_ss7_shutdown_relay(void); + +int ftmod_ss7_disable_grp_mtp3Link(uint32_t procId); +int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId); + +int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId); /* in ftmod_sangoma_ss7_sta.c */ -int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm); +int ftmod_ss7_mtp1link_sta(uint32_t id, L1Mngmt *cfm); +int ftmod_ss7_mtp2link_sta(uint32_t id, SdMngmt *cfm); +int ftmod_ss7_mtp3link_sta(uint32_t id, SnMngmt *cfm); int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm); +int ftmod_ss7_isup_intf_sta(uint32_t id, uint8_t *status); +int ftmod_ss7_relay_status(uint32_t id, RyMngmt *cfm); /* in ftmod_sangoma_ss7_out.c */ @@ -607,6 +705,14 @@ ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info); ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type); ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type); +int find_mtp2_error_type_in_map(const char *err_type); +int find_link_type_in_map(const char *linkType); +int find_switch_type_in_map(const char *switchType); +int find_ssf_type_in_map(const char *ssfType); +int find_cic_cntrl_in_map(const char *cntrlType); + +ftdm_status_t check_status_of_all_isup_intf(void); + /* in ftmod_sangoma_ss7_timers.c */ void handle_isup_t35(void *userdata); /******************************************************************************/ @@ -739,6 +845,10 @@ void handle_isup_t35(void *userdata); #define sngss7_clear_flag(obj, flag) ((obj)->flags &= ~(flag)) #define sngss7_set_flag(obj, flag) ((obj)->flags |= (flag)) +#define sngss7_test_ckt_flag(obj, flag) ((obj)->ckt_flags & flag) +#define sngss7_clear_ckt_flag(obj, flag) ((obj)->ckt_flags &= ~(flag)) +#define sngss7_set_ckt_flag(obj, flag) ((obj)->ckt_flags |= (flag)) + #define sngss7_test_options(obj, option) ((obj)->options & option) #define sngss7_clear_options(obj, option) ((obj)->options &= ~(option)) #define sngss7_set_options(obj, option) ((obj)->options |= (option)) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c index ec8d7df12a..06b0b2183e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c @@ -125,9 +125,9 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) iam.txMedReq.trMedReq.pres = PRSNT_NODEF; iam.txMedReq.trMedReq.val = ftdmchan->caller_data.bearer_capability; - if ((g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].switchType == LSI_SW_ANS88) || - (g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].switchType == LSI_SW_ANS92) || - (g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].switchType == LSI_SW_ANS95)) { + if ((g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS88) || + (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS92) || + (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS95)) { /* include only if we're running ANSI */ iam.fwdCallInd.transCallNInd.pres = PRSNT_NODEF; @@ -178,7 +178,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) iam.usrServInfoA.rateMultiplier.pres = PRSNT_NODEF; iam.usrServInfoA.rateMultiplier.val = 0x1; /* 1x rate multipler */ } /* if ANSI */ - + /* copy down the called number information */ copy_cdPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cdPtyNum); @@ -192,7 +192,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling NADI value \"%s\"\n", clg_nadi); iam.cgPtyNum.natAddrInd.val = atoi(clg_nadi); } else { - iam.cgPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].clg_nadi; + iam.cgPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].clg_nadi; SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLG, using \"%d\"\n", iam.cgPtyNum.natAddrInd.val); } @@ -201,7 +201,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called NADI value \"%s\"\n", cld_nadi); iam.cdPtyNum.natAddrInd.val = atoi(cld_nadi); } else { - iam.cdPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].cld_nadi; + iam.cdPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].cld_nadi; SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLD, using \"%d\"\n", iam.cdPtyNum.natAddrInd.val); } @@ -310,7 +310,6 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) SS7_FUNC_TRACE_ENTER (__FUNCTION__); sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - sng_isup_inf_t *isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; SiCnStEvnt acm; memset (&acm, 0x0, sizeof (acm)); @@ -360,8 +359,8 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) acm.bckCallInd.sccpMethInd.val = SCCPMTH_NOIND; /* fill in any optional parameters */ - if (sngss7_test_options(isup_intf, SNGSS7_ACM_OBCI_BITA)) { - SS7_DEBUG_CHAN(ftdmchan, "Found ACM_OBCI_BITA flag:0x%X\n", isup_intf->options); + if (sngss7_test_options(&g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id], SNGSS7_ACM_OBCI_BITA)) { + SS7_DEBUG_CHAN(ftdmchan, "Found ACM_OBCI_BITA flag:0x%X\n", g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].options); acm.optBckCalInd.eh.pres = PRSNT_NODEF; acm.optBckCalInd.inbndInfoInd.pres = PRSNT_NODEF; acm.optBckCalInd.inbndInfoInd.val = 0x1; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c new file mode 100644 index 0000000000..05ea69ea69 --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2009|Konrad Hammel + * All rights reserved. + * + * Redistribution and use in source and binary forms|with or without + * modification|are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice|this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice|this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES|INCLUDING|BUT NOT + * LIMITED TO|THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT|INDIRECT|INCIDENTAL|SPECIAL, + * EXEMPLARY|OR CONSEQUENTIAL DAMAGES (INCLUDING|BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE|DATA|OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* INCLUDE ********************************************************************/ +#include "ftmod_sangoma_ss7_main.h" +/******************************************************************************/ + +/* DEFINES ********************************************************************/ +/******************************************************************************/ + +/* GLOBALS ********************************************************************/ +/******************************************************************************/ + +/* PROTOTYPES *****************************************************************/ +ftdm_status_t handle_relay_connect(RyMngmt *sta); +ftdm_status_t handle_relay_disconnect(RyMngmt *sta); + +static ftdm_status_t enable_all_ckts_for_relay(void); +static ftdm_status_t reconfig_all_ckts_for_relay(void); +static ftdm_status_t disable_all_ckts_for_relay(void); +static ftdm_status_t block_all_ckts_for_relay(uint32_t procId); +static ftdm_status_t disable_all_sigs_for_relay(uint32_t procId); +static ftdm_status_t disble_all_mtp2_sigs_for_relay(void); +/******************************************************************************/ + +/* FUNCTIONS ******************************************************************/ +ftdm_status_t handle_relay_connect(RyMngmt *sta) +{ + sng_relay_t *sng_relay = &g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id]; + + + /* test if this is the first time the channel comes up */ + if (!sngss7_test_flag(sng_relay, SNGSS7_RELAY_INIT)) { + SS7_DEBUG("Relay Channel %d initial connection UP\n", sng_relay->id); + + /* mark the channel as being up */ + sngss7_set_flag(sng_relay, SNGSS7_RELAY_INIT); + } else { + SS7_DEBUG("Relay Channel %d connection UP\n", sng_relay->id); + + /* react based on type of channel */ + switch (sng_relay->type) { + /******************************************************************/ + case (LRY_CT_TCP_CLIENT): + /* reconfigure all ISUP ckts, since the main system would have lost all configs */ + if (reconfig_all_ckts_for_relay()) { + SS7_ERROR("Failed to reconfigure ISUP Ckts!\n"); + + /* we're done....this is very bad! */ + } else { + enable_all_ckts_for_relay(); + } + + break; + /******************************************************************/ + case (LRY_CT_TCP_SERVER): + /*unblock_all_ckts_for_relay(sta->t.usta.s.ryErrUsta.errPid);*/ + ftmod_ss7_enable_grp_mtp3Link(sta->t.usta.s.ryUpUsta.id); + + break; + /******************************************************************/ + default: + break; + /******************************************************************/ + } /* switch (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id].type) */ + } /* intial up? */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_relay_disconnect_on_error(RyMngmt *sta) +{ + + /* check which procId is in error, if it is 1, disable the ckts */ + if (sta->t.usta.s.ryErrUsta.errPid == 1 ) { + disable_all_ckts_for_relay(); + + disble_all_mtp2_sigs_for_relay(); + } + + /* check if the channel is a server, means we just lost a MGW */ + if (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryErrUsta.errPid].type == LRY_CT_TCP_SERVER) { + block_all_ckts_for_relay(sta->t.usta.s.ryErrUsta.errPid); + + disable_all_sigs_for_relay(sta->t.usta.s.ryErrUsta.errPid); + } + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_relay_disconnect_on_down(RyMngmt *sta) +{ + + /* check if the channel is a server, means we just lost a MGW */ + if (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id].type == LRY_CT_TCP_SERVER) { + block_all_ckts_for_relay(sta->t.usta.s.ryUpUsta.id); + + disable_all_sigs_for_relay(sta->t.usta.s.ryUpUsta.id); + } + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t disable_all_ckts_for_relay(void) +{ + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + int x; + + SS7_INFO("Disabling all ckts becuase of Relay loss\n"); + + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + /**********************************************************************/ + /* make sure this is voice channel */ + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(g_ftdm_sngss7_data.cfg.isupCkt[x].id, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", g_ftdm_sngss7_data.cfg.isupCkt[x].id); + x++; + continue; + } + + /* throw the relay_down flag */ + sngss7_set_ckt_flag(sngss7_info, FLAG_RELAY_DOWN); + + /* throw the channel infId status flags to PAUSED ... they will be executed next process cycle */ + sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); + } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) */ + + /* move along */ + x++; + /**********************************************************************/ + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t enable_all_ckts_for_relay(void) +{ + sngss7_chan_data_t *sngss7_info = NULL; + sng_isup_inf_t *sngIntf = NULL; + ftdm_channel_t *ftdmchan = NULL; + int x; + + SS7_INFO("Enabling all ckts becuase of Relay connection\n"); + + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + /**********************************************************************/ + /* make sure this is voice channel */ + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(g_ftdm_sngss7_data.cfg.isupCkt[x].id, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", g_ftdm_sngss7_data.cfg.isupCkt[x].id); + x++; + continue; + } + + /* bring the relay_down flag down */ + sngss7_clear_ckt_flag(sngss7_info, FLAG_RELAY_DOWN); + + sngIntf = &g_ftdm_sngss7_data.cfg.isupIntf[g_ftdm_sngss7_data.cfg.isupCkt[x].infId]; + + /* check if the interface is paused or resumed */ + if (sngss7_test_flag(sngIntf, SNGSS7_PAUSED)) { + /* don't bring the channel resume flag up...the interface is down */ + SS7_DEBUG_CHAN(ftdmchan, "ISUP interface (%d) set to paused, not resuming channel\n", sngIntf->id); + } else { + SS7_DEBUG_CHAN(ftdmchan, "ISUP interface (%d) set to resume, resuming channel\n", sngIntf->id); + /* throw the channel infId status flags to PAUSED ... they will be executed next process cycle */ + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_RESUME); + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); + } + } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) */ + + /* move along */ + x++; + /**********************************************************************/ + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t reconfig_all_ckts_for_relay(void) +{ +#if 1 + int x; + int ret; + + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + ret = ftmod_ss7_isup_ckt_config(x); + if (ret) { + SS7_CRITICAL("ISUP CKT %d configuration FAILED (%d)!\n", x, ret); + return 1; + } else { + SS7_INFO("ISUP CKT %d configuration DONE!\n", x); + } + + } /* if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) */ + + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.isupCkt[x].flags |= SNGSS7_CONFIGURED; + + x++; + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ +#endif + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t block_all_ckts_for_relay(uint32_t procId) +{ + int x; + + SS7_INFO("BLOcking all ckts on ProcID = %d\n", procId); + + /* we just lost connection to this procId, send out a block for all these circuits */ + x = (procId * 1000) + 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + /**************************************************************************/ + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + /* send out a BLO */ + sng_cc_sta_request (1, + 0, + 0, + g_ftdm_sngss7_data.cfg.isupCkt[x].id, + 0, + SIT_STA_CIRBLOREQ, + NULL); + + } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) */ + + /* move along */ + x++; + /**************************************************************************/ + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t disable_all_sigs_for_relay(uint32_t procId) +{ + SS7_INFO("Disalbing all sig links on ProcID = %d\n", procId); + + ftmod_ss7_disable_grp_mtp3Link(procId); + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t disble_all_mtp2_sigs_for_relay(void) +{ + /* check if there is a local mtp2 link*/ + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) { + SS7_INFO("Disalbing all mtp2 sig links on local system\n"); + + ftmod_ss7_disable_grp_mtp2Link(1); + } + + return FTDM_SUCCESS; + +} + +/******************************************************************************/ +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ +/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c index 1235238452..2f507a2ad4 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c @@ -42,12 +42,43 @@ /******************************************************************************/ /* PROTOTYPES *****************************************************************/ -int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm); +int ftmod_ss7_mtp1link_sta(uint32_t id, L1Mngmt *cfm); +int ftmod_ss7_mtp2link_sta(uint32_t id, SdMngmt *cfm); +int ftmod_ss7_mtp3link_sta(uint32_t id, SnMngmt *cfm); int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm); +int ftmod_ss7_isup_intf_sta(uint32_t id, uint8_t *status); +int ftmod_ss7_relay_status(uint32_t id, RyMngmt *cfm); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ -int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm) +int ftmod_ss7_mtp1link_sta(uint32_t id, L1Mngmt *cfm) +{ + + return 1; +} + +/******************************************************************************/ +int ftmod_ss7_mtp2link_sta(uint32_t id, SdMngmt *cfm) +{ + SdMngmt sta; + Pst pst; + + memset(&sta, 0x0, sizeof(sta)); + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSD; + + sta.hdr.elmId.elmnt = STDLSAP; + sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp2Link[id].id; + + return(sng_sta_mtp2(&pst, &sta, cfm)); +} + +/******************************************************************************/ +int ftmod_ss7_mtp3link_sta(uint32_t id, SnMngmt *cfm) { SnMngmt sta; Pst pst; @@ -60,8 +91,13 @@ int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm) /* insert the destination Entity */ pst.dstEnt = ENTSN; + /* check the for the correct ProcId and make sure it goes to the right system */ + if (g_ftdm_sngss7_data.cfg.procId != 1) { + pst.dstProcId = 1; + } + sta.hdr.elmId.elmnt = STDLSAP; - sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; return(sng_sta_mtp3(&pst, &sta, cfm)); } @@ -80,13 +116,77 @@ int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm) /* insert the destination Entity */ pst.dstEnt = ENTSN; + /* check the for the correct ProcId and make sure it goes to the right system */ + if (g_ftdm_sngss7_data.cfg.procId != 1) { + pst.dstProcId = 1; + } + sta.hdr.elmId.elmnt = STLNKSET; sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; sta.hdr.elmId.elmntInst2 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].links[0]; return(sng_sta_mtp3(&pst, &sta, cfm)); } + /******************************************************************************/ +int ftmod_ss7_isup_intf_sta(uint32_t id, uint8_t *status) +{ + SiMngmt sta; + SiMngmt cfm; + Pst pst; + int ret; + + memset(&sta, 0x0, sizeof(sta)); + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSI; + + /* check the for the correct ProcId and make sure it goes to the right system */ + if (g_ftdm_sngss7_data.cfg.procId != 1) { + pst.dstProcId = 1; + } + + /* request the status of an inftId */ + sta.hdr.entId.ent = ENTSI; + sta.hdr.entId.inst = S_INST; + sta.hdr.msgType = TSSTA; + sta.hdr.elmId.elmnt = SI_STINTF; + + sta.t.ssta.elmntId.intfId = id; + + ret = sng_sta_isup(&pst, &sta, &cfm); + + *status = cfm.t.ssta.cfm.s.intf.state; + + return(ret); +} + +/******************************************************************************/ +int ftmod_ss7_relay_status(uint32_t id, RyMngmt *cfm) +{ + RyMngmt sta; + Pst pst; + + memset(&sta, 0x0, sizeof(sta)); + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTRY; + + sta.hdr.entId.ent = ENTRY; + sta.hdr.entId.inst = S_INST; + sta.hdr.msgType = TSSTA; + sta.hdr.elmId.elmnt = STCHSTA; + sta.hdr.elmId.elmntInst1 = id; + + + return(sng_sta_relay(&pst, &sta, cfm)); +} /******************************************************************************/ /* For Emacs: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c index 23617c9147..683caf2352 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c @@ -75,6 +75,14 @@ ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info); ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type); ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type); + +int find_mtp2_error_type_in_map(const char *err_type); +int find_link_type_in_map(const char *linkType); +int find_switch_type_in_map(const char *switchType); +int find_ssf_type_in_map(const char *ssfType); +int find_cic_cntrl_in_map(const char *cntrlType); + +ftdm_status_t check_status_of_all_isup_intf(void); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -432,7 +440,7 @@ int check_cics_in_range(sngss7_chan_data_t *sngss7_info) } /* check if the channel still has the reset flag done is up */ - if (!sngss7_test_flag(tmp_sngss7_info, FLAG_GRP_RESET_RX_DN)) { + if (!sngss7_test_ckt_flag(tmp_sngss7_info, FLAG_GRP_RESET_RX_DN)) { SS7_DEBUG_CHAN(tmp_ftdmchan, "[CIC:%d] Still processing reset...\n", tmp_sngss7_info->circuit->cic); return 0; } @@ -475,19 +483,19 @@ ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_in int check_for_reset(sngss7_chan_data_t *sngss7_info) { - if (sngss7_test_flag(sngss7_info,FLAG_RESET_RX)) { + if (sngss7_test_ckt_flag(sngss7_info,FLAG_RESET_RX)) { return 1; } - if (sngss7_test_flag(sngss7_info,FLAG_RESET_TX)) { + if (sngss7_test_ckt_flag(sngss7_info,FLAG_RESET_TX)) { return 1; } - if (sngss7_test_flag(sngss7_info,FLAG_GRP_RESET_RX)) { + if (sngss7_test_ckt_flag(sngss7_info,FLAG_GRP_RESET_RX)) { return 1; } - if (sngss7_test_flag(sngss7_info,FLAG_GRP_RESET_TX)) { + if (sngss7_test_ckt_flag(sngss7_info,FLAG_GRP_RESET_TX)) { return 1; } @@ -498,11 +506,13 @@ int check_for_reset(sngss7_chan_data_t *sngss7_info) /******************************************************************************/ unsigned long get_unique_id(void) { + int procId = sng_get_procId(); - if (sngss7_id < 420000000) { + /* id values are between (procId * 1,000,000) and ((procId + 1) * 1,000,000) */ + if (sngss7_id < ((procId + 1) * 1000000) ) { sngss7_id++; } else { - sngss7_id = 1; + sngss7_id = procId * 1000000; } return(sngss7_id); @@ -525,7 +535,7 @@ ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan) } /* check if the GRP_RESET_RX flag is already up */ - if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX)) { /* we have already processed this channel...move along */ continue; } @@ -543,7 +553,7 @@ ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan) (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic + sngss7_span->rx_grs.range)); /* flag the channel as having received a reset */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX); switch (ftdmchan->state) { /**************************************************************************/ @@ -598,10 +608,10 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan) /* check if there is a state change pending on the channel */ if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { /* check the state to the GRP_RESET_RX_DN flag */ - if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) { + if (!sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) { /* this channel is still resetting...do nothing */ goto GRS_UNLOCK_ALL; - } /* if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */ + } /* if (!sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */ } else { /* state change pending */ goto GRS_UNLOCK_ALL; @@ -625,16 +635,16 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan) } /* throw the GRP reset flag complete flag */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); /* move the channel to the down state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); /* update the status map if the ckt is in blocked state */ - if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { sngss7_span->rx_grs.status[byte] = (sngss7_span->rx_grs.status[byte] | (1 << bit)); } /* if blocked */ @@ -679,7 +689,7 @@ ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan) } /* check if the channel is already procoessing the GRA */ - if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) { /* move along */ continue; } @@ -701,7 +711,7 @@ ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan) case FTDM_CHANNEL_STATE_RESTART: /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); /* go to DOWN */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); @@ -720,7 +730,7 @@ ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan) case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); break; /**********************************************************************/ @@ -775,7 +785,7 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan) sigev.channel = ftdmchan; /* if we have the PAUSED flag and the sig status is still UP */ - if ((sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) && + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) && (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) { /* clear up any pending state changes */ @@ -790,7 +800,7 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan) /* if the RESUME flag is up go to SUSPENDED to process the flag */ /* after doing this the flag will be cleared */ - if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_RESUME)) { /* clear up any pending state changes */ while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { @@ -839,7 +849,7 @@ ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan) } /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); + sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -858,9 +868,9 @@ ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan) ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info) { /* clear all the flags related to an incoming GRS */ - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_DN); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); return FTDM_SUCCESS; } @@ -892,10 +902,10 @@ ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info) ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info) { /* clear all the flags related to an outgoing GRS */ - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_BASE); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_SENT); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_BASE); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_SENT); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); return FTDM_SUCCESS; } @@ -918,7 +928,7 @@ ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info) ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info) { /* clear all the flags related to an incoming RSC */ - sngss7_clear_flag(sngss7_info, FLAG_RESET_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_RESET_RX); return FTDM_SUCCESS; } @@ -927,9 +937,9 @@ ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info) ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info) { /* clear all the flags related to an outgoing RSC */ - sngss7_clear_flag(sngss7_info, FLAG_RESET_TX); - sngss7_clear_flag(sngss7_info, FLAG_RESET_SENT); - sngss7_clear_flag(sngss7_info, FLAG_RESET_TX_RSP); + sngss7_clear_ckt_flag(sngss7_info, FLAG_RESET_TX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_RESET_SENT); + sngss7_clear_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP); return FTDM_SUCCESS; } @@ -1147,6 +1157,197 @@ ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int typ return FTDM_SUCCESS; } +/******************************************************************************/ +int find_mtp2_error_type_in_map(const char *err_type) +{ + int i = 0; + + while (sng_mtp2_error_type_map[i].init == 1) { + /* check if string matches the sng_type name */ + if (!strcasecmp(err_type, sng_mtp2_error_type_map[i].sng_type)) { + /* we've found a match break from the loop */ + break; + } else { + /* move on to the next on */ + i++; + } + } /* while (sng_mtp2_error_type_map[i].init == 1) */ + + /* check how we exited the loop */ + if (sng_mtp2_error_type_map[i].init == 0) { + return -1; + } else { + return i; + } /* if (sng_mtp2_error_type_map[i].init == 0) */ +} + +/******************************************************************************/ +int find_link_type_in_map(const char *linkType) +{ + int i = 0; + + while (sng_link_type_map[i].init == 1) { + /* check if string matches the sng_type name */ + if (!strcasecmp(linkType, sng_link_type_map[i].sng_type)) { + /* we've found a match break from the loop */ + break; + } else { + /* move on to the next on */ + i++; + } + } /* while (sng_link_type_map[i].init == 1) */ + + /* check how we exited the loop */ + if (sng_link_type_map[i].init == 0) { + return -1; + } else { + return i; + } /* if (sng_link_type_map[i].init == 0) */ +} + +/******************************************************************************/ +int find_switch_type_in_map(const char *switchType) +{ + int i = 0; + + while (sng_switch_type_map[i].init == 1) { + /* check if string matches the sng_type name */ + if (!strcasecmp(switchType, sng_switch_type_map[i].sng_type)) { + /* we've found a match break from the loop */ + break; + } else { + /* move on to the next on */ + i++; + } + } /* while (sng_switch_type_map[i].init == 1) */ + + /* check how we exited the loop */ + if (sng_switch_type_map[i].init == 0) { + return -1; + } else { + return i; + } /* if (sng_switch_type_map[i].init == 0) */ +} + +/******************************************************************************/ +int find_ssf_type_in_map(const char *ssfType) +{ + int i = 0; + + while (sng_ssf_type_map[i].init == 1) { + /* check if string matches the sng_type name */ + if (!strcasecmp(ssfType, sng_ssf_type_map[i].sng_type)) { + /* we've found a match break from the loop */ + break; + } else { + /* move on to the next on */ + i++; + } + } /* while (sng_ssf_type_map[i].init == 1) */ + + /* check how we exited the loop */ + if (sng_ssf_type_map[i].init == 0) { + return -1; + } else { + return i; + } /* if (sng_ssf_type_map[i].init == 0) */ +} + +/******************************************************************************/ +int find_cic_cntrl_in_map(const char *cntrlType) +{ + int i = 0; + + while (sng_cic_cntrl_type_map[i].init == 1) { + /* check if string matches the sng_type name */ + if (!strcasecmp(cntrlType, sng_cic_cntrl_type_map[i].sng_type)) { + /* we've found a match break from the loop */ + break; + } else { + /* move on to the next on */ + i++; + } + } /* while (sng_cic_cntrl_type_map[i].init == 1) */ + + /* check how we exited the loop */ + if (sng_cic_cntrl_type_map[i].init == 0) { + return -1; + } else { + return i; + } /* if (sng_cic_cntrl_type_map[i].init == 0) */ +} + +/******************************************************************************/ +ftdm_status_t check_status_of_all_isup_intf(void) +{ + sng_isup_inf_t *sngss7_intf = NULL; + uint8_t status = 0xff; + int x; + + /* go through all the isupIntfs and ask the stack to give their current state */ + x = 1; + for (x = 1; x < (MAX_ISUP_INFS + 1); x++) { + /**************************************************************************/ + + if (g_ftdm_sngss7_data.cfg.isupIntf[x].id == 0) continue; + + sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[x]; + + if (ftmod_ss7_isup_intf_sta(sngss7_intf->id, &status)) { + SS7_ERROR("Failed to get status of ISUP intf %d\n", sngss7_intf->id); + continue; + } + + switch (status){ + /**********************************************************************/ + case (SI_INTF_AVAIL): + SS7_DEBUG("State of ISUP intf %d = AVAIL\n", sngss7_intf->id); + + /* check the current state for interface that we know */ + if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { + /* we thing the intf is paused...put into resume */ + sngss7_clear_flag(sngss7_intf, SNGSS7_PAUSED); + } else { + /* nothing to since we already know that interface is active */ + } + break; + /**********************************************************************/ + case (SI_INTF_UNAVAIL): + SS7_DEBUG("State of ISUP intf %d = UNAVAIL\n", sngss7_intf->id); + /* check the current state for interface that we know */ + if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { + /* nothing to since we already know that interface is active */ + } else { + /* put the interface into pause */ + sngss7_set_flag(sngss7_intf, SNGSS7_PAUSED); + } + break; + /**********************************************************************/ + case (SI_INTF_CONG1): + SS7_DEBUG("State of ISUP intf %d = Congestion 1\n", sngss7_intf->id); + break; + /**********************************************************************/ + case (SI_INTF_CONG2): + SS7_DEBUG("State of ISUP intf %d = Congestion 2\n", sngss7_intf->id); + break; + /**********************************************************************/ + case (SI_INTF_CONG3): + SS7_DEBUG("State of ISUP intf %d = Congestion 3\n", sngss7_intf->id); + break; + /**********************************************************************/ + default: + /* should do something here to handle the possiblity of an unknown case */ + SS7_ERROR("Unknown ISUP intf Status code (%d) for Intf = %d\n", status, sngss7_intf->id); + break; + /**********************************************************************/ + } /* switch (status) */ + + /**************************************************************************/ + } /* for (x = 1; x < MAX_ISUP_INFS + 1); i++) */ + + return FTDM_SUCCESS; +} + /******************************************************************************/ /* For Emacs: * Local Variables: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c index 75b32d6892..c2d493f34e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c @@ -61,7 +61,7 @@ void handle_isup_t35(void *userdata) SS7_ERROR("[Call-Control] Timer 35 expired on CIC = %d\n", sngss7_info->circuit->cic); /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_flag(sngss7_info, FLAG_LOCAL_REL); + sngss7_set_ckt_flag(sngss7_info, FLAG_LOCAL_REL); /* hang up on timer expiry */ ftdmchan->caller_data.hangup_cause = 28; 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 d4fd1ca9b3..277951c5d1 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 @@ -39,6 +39,60 @@ /******************************************************************************/ /* GLOBALS ********************************************************************/ +sng_ssf_type_t sng_ssf_type_map[] = +{ + { 1, "nat" , SSF_NAT }, + { 1, "int" , SSF_INTL }, + { 1, "spare" , SSF_SPARE }, + { 1, "res" , SSF_RES }, + { 0, "", 0 }, +}; + +sng_switch_type_t sng_switch_type_map[] = +{ + { 1, "itu88" , LSI_SW_ITU , LSI_SW_ITU }, + { 1, "itu92" , LSI_SW_ITU , LSI_SW_ITU }, + { 1, "itu97" , LSI_SW_ITU97 , LSI_SW_ITU97 }, + { 1, "itu00" , LSI_SW_ITU2000 , LSI_SW_ITU2000 }, + { 1, "ansi88" , LSI_SW_ANS88 , LSI_SW_ANS88 }, + { 1, "ansi92" , LSI_SW_ANS92 , LSI_SW_ANS92 }, + { 1, "ansi95" , LSI_SW_ANS92 , LSI_SW_ANS92 }, + { 1, "etsiv2" , LSI_SW_ETSI , LSI_SW_ETSI }, + { 1, "etsiv3" , LSI_SW_ETSIV3 , LSI_SW_ETSIV3 }, + { 1, "india" , LSI_SW_INDIA , LSI_SW_INDIA }, + { 1, "uk" , LSI_SW_UK , LSI_SW_UK }, + { 1, "russia" , LSI_SW_RUSSIA , LSI_SW_RUSSIA }, + { 0, "", 0, 0 }, +}; + +sng_link_type_t sng_link_type_map[] = +{ + { 1, "itu88" , LSD_SW_ITU88 , LSN_SW_ITU }, + { 1, "itu92" , LSD_SW_ITU92 , LSN_SW_ITU }, + { 1, "etsi" , LSD_SW_ITU92 , LSN_SW_ITU }, + { 1, "ansi88" , LSD_SW_ANSI88, LSN_SW_ANS }, + { 1, "ansi92" , LSD_SW_ANSI92, LSN_SW_ANS }, + { 1, "ansi96" , LSD_SW_ANSI92, LSN_SW_ANS96 }, + { 0, "", 0, 0 }, +}; + +sng_mtp2_error_type_t sng_mtp2_error_type_map[] = +{ + { 1, "basic", SD_ERR_NRM }, + { 1, "pcr" , SD_ERR_CYC }, + { 0, "", 0 }, +}; + +sng_cic_cntrl_type_t sng_cic_cntrl_type_map[] = +{ + { 1, "bothway" , BOTHWAY }, + { 1, "incoming" , INCOMING }, + { 1, "outgoing" , OUTGOING }, + { 1, "controlling" , CONTROLLING }, + { 1, "controlled" , CONTROLLED }, + { 0, "", 0 }, +}; + typedef struct sng_timeslot { int channel; @@ -47,13 +101,28 @@ typedef struct sng_timeslot int hole; }sng_timeslot_t; -typedef struct sng_isupCkt +typedef struct sng_span { + char name[MAX_NAME_LEN]; ftdm_span_t *span; - uint32_t cicbase; - uint32_t typeCntrl; - char ch_map[MAX_CIC_MAP_LENGTH]; + uint32_t ccSpanId; +} sng_span_t; + +typedef struct sng_ccSpan +{ + char name[MAX_NAME_LEN]; + uint32_t options; + uint32_t id; + uint32_t procId; uint32_t isupInf; + uint32_t cicbase; + char ch_map[MAX_CIC_MAP_LENGTH]; + uint32_t typeCntrl; + uint32_t switchType; + uint32_t ssf; + uint32_t clg_nadi; + uint32_t cld_nadi; + uint32_t min_digits; uint32_t t3; uint32_t t12; uint32_t t13; @@ -61,8 +130,9 @@ typedef struct sng_isupCkt uint32_t t15; uint32_t t16; uint32_t t17; + uint32_t t35; uint32_t tval; -} sng_isupCkt_t; +} sng_ccSpan_t; int cmbLinkSetId; /******************************************************************************/ @@ -72,9 +142,22 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup); +static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen); + +static int ftmod_ss7_parse_sng_relay(ftdm_conf_node_t *sng_relay); +static int ftmod_ss7_parse_relay_channel(ftdm_conf_node_t *relay_chan); + +static int ftmod_ss7_parse_mtp1_links(ftdm_conf_node_t *mtp1_links); +static int ftmod_ss7_parse_mtp1_link(ftdm_conf_node_t *mtp1_link); + +static int ftmod_ss7_parse_mtp2_links(ftdm_conf_node_t *mtp2_links); +static int ftmod_ss7_parse_mtp2_link(ftdm_conf_node_t *mtp2_link); + +static int ftmod_ss7_parse_mtp3_links(ftdm_conf_node_t *mtp3_links); +static int ftmod_ss7_parse_mtp3_link(ftdm_conf_node_t *mtp3_link); + static int ftmod_ss7_parse_mtp_linksets(ftdm_conf_node_t *mtp_linksets); static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset); -static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *mtpLink); static int ftmod_ss7_parse_mtp_routes(ftdm_conf_node_t *mtp_routes); static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route); @@ -82,19 +165,22 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route); static int ftmod_ss7_parse_isup_interfaces(ftdm_conf_node_t *isup_interfaces); static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface); -static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink); +static int ftmod_ss7_parse_cc_spans(ftdm_conf_node_t *cc_spans); +static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span); +static int ftmod_ss7_fill_in_relay_channel(sng_relay_t *relay_channel); +static int ftmod_ss7_fill_in_mtp1_link(sng_mtp1_link_t *mtp1Link); +static int ftmod_ss7_fill_in_mtp2_link(sng_mtp2_link_t *mtp1Link); +static int ftmod_ss7_fill_in_mtp3_link(sng_mtp3_link_t *mtp1Link); 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); static int ftmod_ss7_fill_in_nsap(sng_route_t *mtp3_route); - static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup); static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap); - +static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan); static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, int ssf); +static int ftmod_ss7_fill_in_circuits(sng_span_t *sngSpan); -static int ftmod_ss7_fill_in_circuits(sng_isupCkt_t *isupCkt); static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot); /******************************************************************************/ @@ -103,18 +189,17 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot); int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span) { int i = 0; - int x = 0; const char *var = NULL; const char *val = NULL; ftdm_conf_node_t *ptr = NULL; sng_route_t self_route; - sng_isupCkt_t isupCkt; + sng_span_t sngSpan; /* clean out the isup ckt */ - memset(&isupCkt, 0x0, sizeof(sng_isupCkt_t)); + memset(&sngSpan, 0x0, sizeof(sngSpan)); /* clean out the self route */ - memset(&self_route, 0x0, sizeof(sng_route_t)); + memset(&self_route, 0x0, sizeof(self_route)); var = ftdm_parameters[i].var; val = ftdm_parameters[i].val; @@ -136,92 +221,23 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa i++; while (ftdm_parameters[i].var != NULL) { + /**************************************************************************/ var = ftdm_parameters[i].var; val = ftdm_parameters[i].val; - if (!strcasecmp(var, "ch_map")) { + if (!strcasecmp(var, "dialplan")) { /**********************************************************************/ - strncpy(isupCkt.ch_map, val, MAX_CIC_MAP_LENGTH-1); - SS7_DEBUG("\tFound channel map \"%s\"\n", isupCkt.ch_map); - /**********************************************************************/ - } else if (!strcasecmp(var, "typeCntrl")) { - if (!strcasecmp(val, "bothway")) { - isupCkt.typeCntrl = BOTHWAY; - SS7_DEBUG("\tFound control type \"bothway\"\n"); - } else if (!strcasecmp(val, "incoming")) { - isupCkt.typeCntrl = INCOMING; - SS7_DEBUG("\tFound control type \"incoming\"\n"); - } else if (!strcasecmp(val, "outgoing")) { - isupCkt.typeCntrl = OUTGOING; - SS7_DEBUG("\tFound control type \"outgoing\"\n"); - } else if (!strcasecmp(val, "controlled")) { - isupCkt.typeCntrl = CONTROLLED; - SS7_DEBUG("\tFound control type \"controlled\"\n"); - } else if (!strcasecmp(val, "controlling")) { - isupCkt.typeCntrl = CONTROLLING; - SS7_DEBUG("\tFound control type \"controlling\"\n"); - } else { - SS7_ERROR("Found invalid circuit control type \"%s\"!", val); - goto ftmod_ss7_parse_xml_error; - } - /**********************************************************************/ - } else if (!strcasecmp(var, "cicbase")) { - isupCkt.cicbase = atoi(val); - SS7_DEBUG("\tFound cicbase = %d\n", isupCkt.cicbase); - /**********************************************************************/ - } else if (!strcasecmp(var, "dialplan")) { /* do i give a shit about this??? */ /**********************************************************************/ } else if (!strcasecmp(var, "context")) { + /**********************************************************************/ /* do i give a shit about this??? */ /**********************************************************************/ - } else if (!strcasecmp(var, "isup_interface")) { - /* go through all the existing interfaces and see if we find a match */ - x = 1; - while (g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.isupIntf[x].name, val)) { - /* we have a match so break out of this loop */ - break; - } - /* move on to the next one */ - x++; - } - - isupCkt.isupInf = x; - SS7_DEBUG("\tFound isup_interface = %s\n",g_ftdm_sngss7_data.cfg.isupIntf[x].name); + } else if (!strcasecmp(var, "ccSpanId")) { /**********************************************************************/ - } else if (!strcasecmp(var, "isup.t3")) { - isupCkt.t3 = atoi(val); - SS7_DEBUG("\tFound isup t3 = \"%d\"\n", isupCkt.t3); - /**********************************************************************/ - } else if (!strcasecmp(var, "isup.t12")) { - isupCkt.t12 = atoi(val); - SS7_DEBUG("\tFound isup t12 = \"%d\"\n", isupCkt.t12); - /**********************************************************************/ - } else if (!strcasecmp(var, "isup.t13")) { - isupCkt.t13 = atoi(val); - SS7_DEBUG("\tFound isup t13 = \"%d\"\n", isupCkt.t13); - /**********************************************************************/ - } else if (!strcasecmp(var, "isup.t14")) { - isupCkt.t14 = atoi(val); - SS7_DEBUG("\tFound isup t14 = \"%d\"\n", isupCkt.t14); - /**********************************************************************/ - } else if (!strcasecmp(var, "isup.t15")) { - isupCkt.t15 = atoi(val); - SS7_DEBUG("\tFound isup t15 = \"%d\"\n", isupCkt.t15); - /**********************************************************************/ - } else if (!strcasecmp(var, "isup.t16")) { - isupCkt.t16 = atoi(val); - SS7_DEBUG("\tFound isup t16 = \"%d\"\n", isupCkt.t16); - /**********************************************************************/ - } else if (!strcasecmp(var, "isup.t17")) { - isupCkt.t17 = atoi(val); - SS7_DEBUG("\tFound isup t17 = \"%d\"\n", isupCkt.t17); - /**********************************************************************/ - } else if (!strcasecmp(var, "isup.tval")) { - isupCkt.tval = atoi(val); - SS7_DEBUG("\tFound isup tval = \"%d\"\n", isupCkt.tval); + sngSpan.ccSpanId = atoi(val); + SS7_DEBUG("Found an ccSpanId = %d\n",sngSpan.ccSpanId); /**********************************************************************/ } else { SS7_ERROR("Unknown parameter found =\"%s\"...ignoring it!\n", var); @@ -231,24 +247,11 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa i++; } /* while (ftdm_parameters[i].var != NULL) */ - /* setup the self mtp3 route */ - i = g_ftdm_sngss7_data.cfg.isupIntf[x].mtpRouteId; - - if(ftmod_ss7_fill_in_self_route(g_ftdm_sngss7_data.cfg.isupIntf[x].spc, - g_ftdm_sngss7_data.cfg.mtpRoute[i].linkType, - g_ftdm_sngss7_data.cfg.mtpRoute[i].switchType, - g_ftdm_sngss7_data.cfg.mtpRoute[i].ssf)) { - - SS7_ERROR("Failed to fill in self route structure!\n"); - goto ftmod_ss7_parse_xml_error; - - } - /* fill the pointer to span into isupCkt */ - isupCkt.span = span; + sngSpan.span = span; /* setup the circuits structure */ - if(ftmod_ss7_fill_in_circuits(&isupCkt)) { + if(ftmod_ss7_fill_in_circuits(&sngSpan)) { SS7_ERROR("Failed to fill in circuits structure!\n"); goto ftmod_ss7_parse_xml_error; } @@ -262,9 +265,15 @@ ftmod_ss7_parse_xml_error: /******************************************************************************/ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup) { + ftdm_conf_node_t *gen_config = NULL; + ftdm_conf_node_t *relay_channels = NULL; + ftdm_conf_node_t *mtp1_links = NULL; + ftdm_conf_node_t *mtp2_links = NULL; + ftdm_conf_node_t *mtp3_links = NULL; ftdm_conf_node_t *mtp_linksets = NULL; ftdm_conf_node_t *mtp_routes = NULL; ftdm_conf_node_t *isup_interfaces = NULL; + ftdm_conf_node_t *cc_spans = NULL; ftdm_conf_node_t *tmp_node = NULL; /* confirm that we are looking at sng_isup */ @@ -275,51 +284,145 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup) SS7_DEBUG("Parsing \"sng_isup\"...\n"); } - /* extract the 3 main sections of the sng_isup block */ + /* extract the main sections of the sng_isup block */ tmp_node = sng_isup->child; - while (tmp_node != NULL) { - if (!strcasecmp(tmp_node->name, "mtp_linksets")) { + while (tmp_node != NULL) { + /**************************************************************************/ + /* check the type of structure */ + if (!strcasecmp(tmp_node->name, "sng_gen")) { + /**********************************************************************/ + if (gen_config == NULL) { + gen_config = tmp_node; + SS7_DEBUG("Found a \"sng_gen\" section!\n"); + } else { + SS7_ERROR("Found a second \"sng_gen\" section\n!"); + return FTDM_FAIL; + } + /**********************************************************************/ + } else if (!strcasecmp(tmp_node->name, "sng_relay")) { + /**********************************************************************/ + if (relay_channels == NULL) { + relay_channels = tmp_node; + SS7_DEBUG("Found a \"sng_relay\" section!\n"); + } else { + SS7_ERROR("Found a second \"sng_relay\" section\n!"); + return FTDM_FAIL; + } + /**********************************************************************/ + }else if (!strcasecmp(tmp_node->name, "mtp1_links")) { + /**********************************************************************/ + if (mtp1_links == NULL) { + mtp1_links = tmp_node; + SS7_DEBUG("Found a \"mtp1_links\" section!\n"); + } else { + SS7_ERROR("Found a second \"mtp1_links\" section!\n"); + return FTDM_FAIL; + } + /**********************************************************************/ + } else if (!strcasecmp(tmp_node->name, "mtp2_links")) { + /**********************************************************************/ + if (mtp2_links == NULL) { + mtp2_links = tmp_node; + SS7_DEBUG("Found a \"mtp2_links\" section!\n"); + } else { + SS7_ERROR("Found a second \"mtp2_links\" section!\n"); + return FTDM_FAIL; + } + /**********************************************************************/ + } else if (!strcasecmp(tmp_node->name, "mtp3_links")) { + /**********************************************************************/ + if (mtp3_links == NULL) { + mtp3_links = tmp_node; + SS7_DEBUG("Found a \"mtp3_links\" section!\n"); + } else { + SS7_ERROR("Found a second \"mtp3_links\" section!\n"); + return FTDM_FAIL; + } + /**********************************************************************/ + } else if (!strcasecmp(tmp_node->name, "mtp_linksets")) { + /**********************************************************************/ if (mtp_linksets == NULL) { mtp_linksets = tmp_node; - SS7_DEBUG("\tFound a \"mtp_linksets section!\n"); + SS7_DEBUG("Found a \"mtp_linksets\" section!\n"); } else { - SS7_ERROR("\tFound a second \"mtp_linksets\" section!\n"); + SS7_ERROR("Found a second \"mtp_linksets\" section!\n"); return FTDM_FAIL; } + /**********************************************************************/ } else if (!strcasecmp(tmp_node->name, "mtp_routes")) { + /**********************************************************************/ if (mtp_routes == NULL) { mtp_routes = tmp_node; - SS7_DEBUG("\tFound a \"mtp_routes\" section!\n"); + SS7_DEBUG("Found a \"mtp_routes\" section!\n"); } else { - SS7_ERROR("\tFound a second \"mtp_routes\" section!\n"); + SS7_ERROR("Found a second \"mtp_routes\" section!\n"); return FTDM_FAIL; } + /**********************************************************************/ } else if (!strcasecmp(tmp_node->name, "isup_interfaces")) { + /**********************************************************************/ if (isup_interfaces == NULL) { isup_interfaces = tmp_node; - SS7_DEBUG("\tFound a \"isup_interfaces\" section!\n"); + SS7_DEBUG("Found a \"isup_interfaces\" section!\n"); } else { - SS7_ERROR("\tFound a second \"isup_interfaces\" section\n!"); + SS7_ERROR("Found a second \"isup_interfaces\" section\n!"); return FTDM_FAIL; } + /**********************************************************************/ + } else if (!strcasecmp(tmp_node->name, "cc_spans")) { + /**********************************************************************/ + if (cc_spans == NULL) { + cc_spans = tmp_node; + SS7_DEBUG("Found a \"cc_spans\" section!\n"); + } else { + SS7_ERROR("Found a second \"cc_spans\" section\n!"); + return FTDM_FAIL; + } + /**********************************************************************/ } else { + /**********************************************************************/ SS7_ERROR("\tFound an unknown section \"%s\"!\n", tmp_node->name); return FTDM_FAIL; - } + /**********************************************************************/ + } /* go to the next sibling */ tmp_node = tmp_node->next; - } /* while (tmp_node != NULL) */ /* now try to parse the sections */ + if (ftmod_ss7_parse_sng_gen(gen_config)) { + SS7_ERROR("Failed to parse \"gen_config\"!\n"); + return FTDM_FAIL; + } + + if (ftmod_ss7_parse_sng_relay(relay_channels)) { + SS7_ERROR("Failed to parse \"relay_channels\"!\n"); + return FTDM_FAIL; + } + + if (ftmod_ss7_parse_mtp1_links(mtp1_links)) { + SS7_ERROR("Failed to parse \"mtp1_links\"!\n"); + return FTDM_FAIL; + } + + if (ftmod_ss7_parse_mtp2_links(mtp2_links)) { + SS7_ERROR("Failed to parse \"mtp2_links\"!\n"); + return FTDM_FAIL; + } + + if (ftmod_ss7_parse_mtp3_links(mtp3_links)) { + SS7_ERROR("Failed to parse \"mtp3_links\"!\n"); + return FTDM_FAIL; + } + if (ftmod_ss7_parse_mtp_linksets(mtp_linksets)) { SS7_ERROR("Failed to parse \"mtp_linksets\"!\n"); return FTDM_FAIL; } - if (ftmod_ss7_parse_mtp_routes(mtp_routes)) { + if (ftmod_ss7_parse_mtp_routes(mtp_routes)) { SS7_ERROR("Failed to parse \"mtp_routes\"!\n"); return FTDM_FAIL; } @@ -329,6 +432,700 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup) return FTDM_FAIL; } + if (ftmod_ss7_parse_cc_spans(cc_spans)) { + SS7_ERROR("Failed to parse \"cc_spans\"!\n"); + return FTDM_FAIL; + } + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen) +{ + ftdm_conf_parameter_t *parm = sng_gen->parameters; + int num_parms = sng_gen->n_parameters; + int i = 0; + + /* extract all the information from the parameters */ + for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + + if (!strcasecmp(parm->var, "procId")) { + /**********************************************************************/ + g_ftdm_sngss7_data.cfg.procId = atoi(parm->val); + SS7_DEBUG("Found a procId = %d\n", g_ftdm_sngss7_data.cfg.procId); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "license")) { + /**********************************************************************/ + strcpy(g_ftdm_sngss7_data.cfg.license, parm->val); + strcpy(g_ftdm_sngss7_data.cfg.signature, parm->val); + strcat(g_ftdm_sngss7_data.cfg.signature, ".sig"); + 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); + return FTDM_FAIL; + /**********************************************************************/ + } + + /* move to the next parmeter */ + parm = parm + 1; + } /* for (i = 0; i < num_parms; i++) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_sng_relay(ftdm_conf_node_t *sng_relay) +{ + ftdm_conf_node_t *relay_chan = NULL; + + /* confirm that we are looking at sng_relay */ + if (strcasecmp(sng_relay->name, "sng_relay")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"sng_relay\"!\n",sng_relay->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"sng_relay\"...\n"); + } + + relay_chan = sng_relay->child; + + if (relay_chan != NULL) { + while (relay_chan != NULL) { + /* try to the parse relay_channel */ + if (ftmod_ss7_parse_relay_channel(relay_chan)) { + SS7_ERROR("Failed to parse \"relay_channels\"!\n"); + return FTDM_FAIL; + } + + /* move on to the next linkset */ + relay_chan = relay_chan->next; + } /* while (relay_chan != NULL) */ + } /* if (relay_chan != NULL) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_relay_channel(ftdm_conf_node_t *relay_chan) +{ + sng_relay_t tmp_chan; + ftdm_conf_parameter_t *parm = relay_chan->parameters; + int num_parms = relay_chan->n_parameters; + int i = 0; + + /* confirm that we are looking at relay_channel */ + if (strcasecmp(relay_chan->name, "relay_channel")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"relay_channel\"!\n",relay_chan->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"relay_channel\"...\n"); + } + + /* initalize the tmp_chan structure */ + memset(&tmp_chan, 0x0, sizeof(tmp_chan)); + + /* extract all the information from the parameters */ + for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + + if (!strcasecmp(parm->var, "name")) { + /**********************************************************************/ + strcpy((char *)tmp_chan.name, parm->val); + SS7_DEBUG("Found an relay_channel named = %s\n", tmp_chan.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "type")) { + /**********************************************************************/ + if (!strcasecmp(parm->val, "listen")) { + tmp_chan.type = LRY_CT_TCP_LISTEN; + SS7_DEBUG("Found a type = LISTEN\n"); + } else if (!strcasecmp(parm->val, "server")) { + tmp_chan.type = LRY_CT_TCP_SERVER; + SS7_DEBUG("Found a type = SERVER\n"); + } else if (!strcasecmp(parm->val, "client")) { + tmp_chan.type = LRY_CT_TCP_CLIENT; + SS7_DEBUG("Found a type = CLIENT\n"); + } else { + SS7_ERROR("Found an invalid \"type\" = %s\n", parm->var); + return FTDM_FAIL; + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "hostname")) { + /**********************************************************************/ + strcpy((char *)tmp_chan.hostname, parm->val); + SS7_DEBUG("Found a hostname = %s\n", tmp_chan.hostname); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "port")) { + /**********************************************************************/ + tmp_chan.port = atoi(parm->val); + SS7_DEBUG("Found a port = %d\n", tmp_chan.port); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "procId")) { + /**********************************************************************/ + tmp_chan.procId = atoi(parm->val); + SS7_DEBUG("Found a procId = %d\n", tmp_chan.procId); + /**********************************************************************/ + } else { + /**********************************************************************/ + SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); + return FTDM_FAIL; + /**********************************************************************/ + } + + /* move to the next parmeter */ + parm = parm + 1; + } /* for (i = 0; i < num_parms; i++) */ + + /* store the channel in the global structure */ + ftmod_ss7_fill_in_relay_channel(&tmp_chan); + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_mtp1_links(ftdm_conf_node_t *mtp1_links) +{ + ftdm_conf_node_t *mtp1_link = NULL; + + /* confirm that we are looking at mtp1_links */ + if (strcasecmp(mtp1_links->name, "mtp1_links")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp1_links\"!\n",mtp1_links->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"mtp1_links\"...\n"); + } + + /* extract the mtp_links */ + mtp1_link = mtp1_links->child; + + /* run through all of the links found */ + while (mtp1_link != NULL) { + /* try to the parse mtp_link */ + if (ftmod_ss7_parse_mtp1_link(mtp1_link)) { + SS7_ERROR("Failed to parse \"mtp1_link\"!\n"); + return FTDM_FAIL; + } + + /* move on to the next link */ + mtp1_link = mtp1_link->next; + + } /* while (mtp_linkset != NULL) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_mtp1_link(ftdm_conf_node_t *mtp1_link) +{ + sng_mtp1_link_t mtp1Link; + ftdm_conf_parameter_t *parm = mtp1_link->parameters; + int num_parms = mtp1_link->n_parameters; + int i; + + /* initalize the mtp1Link structure */ + memset(&mtp1Link, 0x0, sizeof(mtp1Link)); + + /* confirm that we are looking at an mtp_link */ + if (strcasecmp(mtp1_link->name, "mtp1_link")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp1_link\"!\n",mtp1_link->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"mtp1_link\"...\n"); + } + + for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + + if (!strcasecmp(parm->var, "name")) { + /**********************************************************************/ + strcpy((char *)mtp1Link.name, parm->val); + SS7_DEBUG("Found an mtp1_link named = %s\n", mtp1Link.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "id")) { + /**********************************************************************/ + mtp1Link.id = atoi(parm->val); + SS7_DEBUG("Found an mtp1_link id = %d\n", mtp1Link.id); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "span")) { + /**********************************************************************/ + mtp1Link.span = atoi(parm->val); + SS7_DEBUG("Found an mtp1_link span = %d\n", mtp1Link.span); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "chan")) { + /**********************************************************************/ + mtp1Link.chan = atoi(parm->val); + SS7_DEBUG("Found an mtp1_link chan = %d\n", mtp1Link.chan); + /**********************************************************************/ + } else { + /**********************************************************************/ + SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); + return FTDM_FAIL; + /**********************************************************************/ + } + + /* move to the next parmeter */ + parm = parm + 1; + + /**************************************************************************/ + } /* for (i = 0; i < num_parms; i++) */ + + /* store the link in global structure */ + ftmod_ss7_fill_in_mtp1_link(&mtp1Link); + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_mtp2_links(ftdm_conf_node_t *mtp2_links) +{ + ftdm_conf_node_t *mtp2_link = NULL; + + /* confirm that we are looking at mtp2_links */ + if (strcasecmp(mtp2_links->name, "mtp2_links")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp2_links\"!\n",mtp2_links->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"mtp2_links\"...\n"); + } + + /* extract the mtp_links */ + mtp2_link = mtp2_links->child; + + /* run through all of the links found */ + while (mtp2_link != NULL) { + /* try to the parse mtp_linkset */ + if (ftmod_ss7_parse_mtp2_link(mtp2_link)) { + SS7_ERROR("Failed to parse \"mtp2_link\"!\n"); + return FTDM_FAIL; + } + + /* move on to the next link */ + mtp2_link = mtp2_link->next; + + } /* while (mtp_linkset != NULL) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_mtp2_link(ftdm_conf_node_t *mtp2_link) +{ + sng_mtp2_link_t mtp2Link; + ftdm_conf_parameter_t *parm = mtp2_link->parameters; + int num_parms = mtp2_link->n_parameters; + int i; + int ret; + + /* initalize the mtp1Link structure */ + memset(&mtp2Link, 0x0, sizeof(mtp2Link)); + + /* confirm that we are looking at an mtp2_link */ + if (strcasecmp(mtp2_link->name, "mtp2_link")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp2_link\"!\n",mtp2_link->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"mtp2_link\"...\n"); + } + + for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + + if (!strcasecmp(parm->var, "name")) { + /**********************************************************************/ + strcpy((char *)mtp2Link.name, parm->val); + SS7_DEBUG("Found an mtp2_link named = %s\n", mtp2Link.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "id")) { + /**********************************************************************/ + mtp2Link.id = atoi(parm->val); + SS7_DEBUG("Found an mtp2_link id = %d\n", mtp2Link.id); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "mtp1Id")) { + /**********************************************************************/ + mtp2Link.mtp1Id = atoi(parm->val); + SS7_DEBUG("Found an mtp2_link mtp1Id = %d\n", mtp2Link.mtp1Id); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "errorType")) { + /**********************************************************************/ + ret = find_mtp2_error_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid mtp2_link errorType = %s\n", parm->var); + return FTDM_FAIL; + } else { + mtp2Link.errorType = sng_mtp2_error_type_map[ret].tril_type; + SS7_DEBUG("Found an mtp2_link errorType = %s\n", sng_mtp2_error_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "lssuLength")) { + /**********************************************************************/ + mtp2Link.lssuLength = atoi(parm->val); + SS7_DEBUG("Found an mtp2_link lssuLength = %d\n", mtp2Link.lssuLength); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "linkType")) { + /**********************************************************************/ + ret = find_link_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid mtp2_link linkType = %s\n", parm->var); + return FTDM_FAIL; + } else { + mtp2Link.linkType = sng_link_type_map[ret].tril_mtp2_type; + SS7_DEBUG("Found an mtp2_link linkType = %s\n", sng_link_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t1")) { + /**********************************************************************/ + mtp2Link.t1 = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t1 = \"%d\"\n",mtp2Link.t1); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t2")) { + /**********************************************************************/ + mtp2Link.t2 = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t2 = \"%d\"\n",mtp2Link.t2); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t3")) { + /**********************************************************************/ + mtp2Link.t3 = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t3 = \"%d\"\n",mtp2Link.t3); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t4n")) { + /**********************************************************************/ + mtp2Link.t4n = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t4n = \"%d\"\n",mtp2Link.t4n); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t4e")) { + /**********************************************************************/ + mtp2Link.t4e = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t4e = \"%d\"\n",mtp2Link.t4e); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t5")) { + /**********************************************************************/ + mtp2Link.t5 = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t5 = \"%d\"\n",mtp2Link.t5); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t6")) { + /**********************************************************************/ + mtp2Link.t6 = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t6 = \"%d\"\n",mtp2Link.t6); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t7")) { + /**********************************************************************/ + mtp2Link.t7 = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t7 = \"%d\"\n",mtp2Link.t7); + /**********************************************************************/ + } else { + /**********************************************************************/ + SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); + return FTDM_FAIL; + /**********************************************************************/ + } + + /* move to the next parmeter */ + parm = parm + 1; + + /**************************************************************************/ + } /* for (i = 0; i < num_parms; i++) */ + + /* store the link in global structure */ + ftmod_ss7_fill_in_mtp2_link(&mtp2Link); + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_mtp3_links(ftdm_conf_node_t *mtp3_links) +{ + ftdm_conf_node_t *mtp3_link = NULL; + + /* confirm that we are looking at mtp3_links */ + if (strcasecmp(mtp3_links->name, "mtp3_links")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp3_links\"!\n",mtp3_links->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"mtp3_links\"...\n"); + } + + /* extract the mtp_links */ + mtp3_link = mtp3_links->child; + + /* run through all of the links found */ + while (mtp3_link != NULL) { + /* try to the parse mtp_linkset */ + if (ftmod_ss7_parse_mtp3_link(mtp3_link)) { + SS7_ERROR("Failed to parse \"mtp3_link\"!\n"); + return FTDM_FAIL; + } + + /* move on to the next link */ + mtp3_link = mtp3_link->next; + + } /* while (mtp_linkset != NULL) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_mtp3_link(ftdm_conf_node_t *mtp3_link) +{ + sng_mtp3_link_t mtp3Link; + ftdm_conf_parameter_t *parm = mtp3_link->parameters; + int num_parms = mtp3_link->n_parameters; + int i; + int ret; + + /* initalize the mtp3Link structure */ + memset(&mtp3Link, 0x0, sizeof(mtp3Link)); + + /* confirm that we are looking at an mtp_link */ + if (strcasecmp(mtp3_link->name, "mtp3_link")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp3_link\"!\n",mtp3_link->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"mtp3_link\"...\n"); + } + + for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + if (!strcasecmp(parm->var, "name")) { + /**********************************************************************/ + strcpy((char *)mtp3Link.name, parm->val); + SS7_DEBUG("Found an mtp3_link named = %s\n", mtp3Link.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "id")) { + /**********************************************************************/ + mtp3Link.id = atoi(parm->val); + SS7_DEBUG("Found an mtp3_link id = %d\n", mtp3Link.id); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "mtp2Id")) { + /**********************************************************************/ + mtp3Link.mtp2Id = atoi(parm->val); + SS7_DEBUG("Found an mtp3_link mtp2Id = %d\n", mtp3Link.mtp2Id); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "mtp2ProcId")) { + /**********************************************************************/ + mtp3Link.mtp2ProcId = atoi(parm->val); + SS7_DEBUG("Found an mtp3_link mtp2ProcId = %d\n", mtp3Link.mtp2ProcId); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "priority")) { + /**********************************************************************/ + mtp3Link.priority = atoi(parm->val); + SS7_DEBUG("Found an mtp3 Link priority = %d\n",mtp3Link.priority); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "linkType")) { + /**********************************************************************/ + ret = find_link_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid mtp3_link linkType = %s\n", parm->var); + return FTDM_FAIL; + } else { + mtp3Link.linkType = sng_link_type_map[ret].tril_mtp3_type; + SS7_DEBUG("Found an mtp3_link linkType = %s\n", sng_link_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "switchType")) { + /**********************************************************************/ + ret = find_switch_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid mtp3_link switchType = %s\n", parm->var); + return FTDM_FAIL; + } else { + mtp3Link.switchType = sng_switch_type_map[ret].tril_mtp3_type; + SS7_DEBUG("Found an mtp3_link switchType = %s\n", sng_switch_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "ssf")) { + /**********************************************************************/ + ret = find_ssf_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid mtp3_link ssf = %s\n", parm->var); + return FTDM_FAIL; + } else { + mtp3Link.ssf = sng_ssf_type_map[ret].tril_type; + SS7_DEBUG("Found an mtp3_link ssf = %s\n", sng_ssf_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "slc")) { + /**********************************************************************/ + mtp3Link.slc = atoi(parm->val); + SS7_DEBUG("Found an mtp3 Link slc = %d\n",mtp3Link.slc); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "linkset")) { + /**********************************************************************/ + mtp3Link.linkSetId = atoi(parm->val); + SS7_DEBUG("Found an mtp3 Link linkset = %d\n",mtp3Link.linkSetId); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t1")) { + /**********************************************************************/ + mtp3Link.t1 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t1 = %d\n",mtp3Link.t1); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t2")) { + /**********************************************************************/ + mtp3Link.t2 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t2 = %d\n",mtp3Link.t2); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t3")) { + /**********************************************************************/ + mtp3Link.t3 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t3 = %d\n",mtp3Link.t3); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t4")) { + /**********************************************************************/ + mtp3Link.t4 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t4 = %d\n",mtp3Link.t4); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t5")) { + /**********************************************************************/ + mtp3Link.t5 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t5 = %d\n",mtp3Link.t5); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t7")) { + /**********************************************************************/ + mtp3Link.t7 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t7 = %d\n",mtp3Link.t7); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t12")) { + /**********************************************************************/ + mtp3Link.t12 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t12 = %d\n",mtp3Link.t12); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t13")) { + /**********************************************************************/ + mtp3Link.t13 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t13 = %d\n",mtp3Link.t13); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t14")) { + /**********************************************************************/ + mtp3Link.t14 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t14 = %d\n",mtp3Link.t14); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t17")) { + /**********************************************************************/ + mtp3Link.t17 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t17 = %d\n",mtp3Link.t17); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t22")) { + /**********************************************************************/ + mtp3Link.t22 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t22 = %d\n",mtp3Link.t22); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t23")) { + /**********************************************************************/ + mtp3Link.t23 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t23 = %d\n",mtp3Link.t23); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t24")) { + /**********************************************************************/ + mtp3Link.t24 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t24 = %d\n",mtp3Link.t24); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t31")) { + mtp3Link.t31 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t31 = %d\n",mtp3Link.t31); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t32")) { + /**********************************************************************/ + mtp3Link.t32 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t32 = %d\n",mtp3Link.t32); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t33")) { + /**********************************************************************/ + mtp3Link.t33 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t33 = %d\n",mtp3Link.t33); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t34")) { + /**********************************************************************/ + mtp3Link.t34 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t34 = %d\n",mtp3Link.t34); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t35")) { + /**********************************************************************/ + mtp3Link.t35 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t35 = %d\n",mtp3Link.t35); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t36")) { + /**********************************************************************/ + mtp3Link.t36 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t36 = %d\n",mtp3Link.t36); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t37")) { + /**********************************************************************/ + mtp3Link.t37 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t37 = %d\n",mtp3Link.t37); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "tcraft")) { + /**********************************************************************/ + mtp3Link.tcraft = atoi(parm->val); + SS7_DEBUG("Found an mtp3 tcraft = %d\n",mtp3Link.tcraft); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "tflc")) { + /**********************************************************************/ + mtp3Link.tflc = atoi(parm->val); + SS7_DEBUG("Found an mtp3 tflc = %d\n",mtp3Link.tflc); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "tbnd")) { + /**********************************************************************/ + mtp3Link.tbnd = atoi(parm->val); + SS7_DEBUG("Found an mtp3 tbnd = %d\n",mtp3Link.tbnd); + /**********************************************************************/ + } else { + /**********************************************************************/ + SS7_ERROR("Found an invalid parameter %s!\n", parm->val); + return FTDM_FAIL; + /**********************************************************************/ + } + + /* move to the next parmeter */ + parm = parm + 1; + + /**************************************************************************/ + } /* for (i = 0; i < num_parms; i++) */ + + /* store the link in global structure */ + ftmod_ss7_fill_in_mtp3_link(&mtp3Link); + + /* move the linktype, switchtype and ssf to the linkset */ + if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].linkType == 0) { + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].linkType = mtp3Link.linkType; + } else if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].linkType != mtp3Link.linkType) { + SS7_ERROR("Trying to add an MTP3 Link to a Linkset with a different linkType: mtp3.id=%d, mtp3.name=%s, mtp3.linktype=%d, linkset.id=%d, linkset.linktype=%d\n", + mtp3Link.id, mtp3Link.name, mtp3Link.linkType, + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].id, g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].linkType); + return FTDM_FAIL; + } else { + /* should print that all is ok...*/ + } + + if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].switchType == 0) { + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].switchType = mtp3Link.switchType; + } else if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].switchType != mtp3Link.switchType) { + SS7_ERROR("Trying to add an MTP3 Link to a Linkset with a different switchType: mtp3.id=%d, mtp3.name=%s, mtp3.switchtype=%d, linkset.id=%d, linkset.switchtype=%d\n", + mtp3Link.id, mtp3Link.name, mtp3Link.switchType, + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].id, g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].switchType); + return FTDM_FAIL; + } else { + /* should print that all is ok...*/ + } + + if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].ssf == 0) { + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].ssf = mtp3Link.ssf; + } else if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].ssf != mtp3Link.ssf) { + SS7_ERROR("Trying to add an MTP3 Link to a Linkset with a different ssf: mtp3.id=%d, mtp3.name=%s, mtp3.ssf=%d, linkset.id=%d, linkset.ssf=%d\n", + mtp3Link.id, mtp3Link.name, mtp3Link.ssf, + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].id, g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].ssf); + return FTDM_FAIL; + } else { + /* should print that all is ok...*/ + } + + return FTDM_SUCCESS; } @@ -367,18 +1164,12 @@ static int ftmod_ss7_parse_mtp_linksets(ftdm_conf_node_t *mtp_linksets) /******************************************************************************/ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset) { + sng_link_set_t mtpLinkSet; ftdm_conf_parameter_t *parm = mtp_linkset->parameters; - int num_parms = mtp_linkset->n_parameters; - ftdm_conf_node_t *mtp_link = NULL; - sng_mtp_link_t mtpLink[MAX_MTP_LINKS+1]; - sng_link_set_t mtpLinkSet; - int count; - int i; + int num_parms = mtp_linkset->n_parameters; + int i; - /* initialize the mtp_link structures */ - for (i = 0; i < (MAX_MTP_LINKS + 1); i++) { - memset(&mtpLink[i], 0x0, sizeof(mtpLink[i])); - } + /* initalize the mtpLinkSet structure */ memset(&mtpLinkSet, 0x0, sizeof(mtpLinkSet)); /* confirm that we are looking at mtp_linkset */ @@ -391,387 +1182,52 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset) /* extract all the information from the parameters */ for (i = 0; i < num_parms; i++) { - /**********************************************************************/ + /**************************************************************************/ + if (!strcasecmp(parm->var, "name")) { - strncpy((char *)mtpLinkSet.name, parm->val, MAX_NAME_LEN-1); - SS7_DEBUG("\tFound an \"mtp_linkset\" named = %s\n", mtpLinkSet.name); + /**********************************************************************/ + strcpy((char *)mtpLinkSet.name, parm->val); + SS7_DEBUG("Found an mtpLinkSet named = %s\n", mtpLinkSet.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "id")) { + /**********************************************************************/ + mtpLinkSet.id = atoi(parm->val); + SS7_DEBUG("Found mtpLinkSet id = %d\n", mtpLinkSet.id); /**********************************************************************/ } else if (!strcasecmp(parm->var, "apc")) { + /**********************************************************************/ mtpLinkSet.apc = atoi(parm->val); - SS7_DEBUG("\tFound mtpLinkSet->apc = %d\n", mtpLinkSet.apc); + SS7_DEBUG("Found mtpLinkSet apc = %d\n", mtpLinkSet.apc); /**********************************************************************/ } else if (!strcasecmp(parm->var, "minActive")) { + /**********************************************************************/ mtpLinkSet.minActive = atoi(parm->val); - SS7_DEBUG("\tFound mtpLinkSet->minActive = %d\n", mtpLinkSet.minActive); + SS7_DEBUG("Found mtpLinkSet minActive = %d\n", mtpLinkSet.minActive); /**********************************************************************/ } else { - SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); + /**********************************************************************/ + SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); return FTDM_FAIL; + /**********************************************************************/ } /* move to the next parmeter */ parm = parm + 1; - + /**************************************************************************/ } /* for (i = 0; i < num_parms; i++) */ - /* grab the first mtp-link (which sits below the mtp_links section) */ - mtp_link = mtp_linkset->child->child; - - /* initalize the link counter */ - count = 0; - - /* run through all of the mtp_links found */ - while (mtp_link != NULL) { - /* try to the parse mtp_linkset */ - if (ftmod_ss7_parse_mtp_link(mtp_link, &mtpLink[count] )) { - SS7_ERROR("Failed to parse \"mtp_link\"!\n"); - return FTDM_FAIL; - } - - /* incremenet the link counter */ - count++; - - /* move on to the next link */ - mtp_link = mtp_link->next; - - } /* while (mtp_link != NULL) */ - - /* confirm we have the right number of links */ - if (count < 1 || count > 15 ) { - SS7_ERROR("Invalid number of mtp_links found (%d)\n", count); - return FTDM_FAIL; - } - - /* now we need to see if this linkset exists already or not and grab an Id */ - i = 1; - while (g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id != 0) { - if (!strcasecmp((const char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[i].name, (const char *)mtpLinkSet.name)) { - /* we've found the linkset...so it has already been configured */ - break; - } - i++; - /* add in error check to make sure we don't go out-of-bounds */ - } - - /* if the id value is 0 that means we didn't find the linkset */ - if (g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id == 0) { - mtpLinkSet.id = i; - SS7_DEBUG("found new mtpLinkSet, id is = %d\n", mtpLinkSet.id); - } else { - mtpLinkSet.id = i; - SS7_DEBUG("found existing mtpLinkSet, id is = %d\n", mtpLinkSet.id); - } - - /* we now have all the information to fill in the Libsng_ss7 structures */ - i = 0; - count = 0; - while (mtpLink[i].mtp1.span != 0 ){ - - /* have to grab a couple of values from the linkset */ - mtpLink[i].mtp3.apc = mtpLinkSet.apc; - mtpLink[i].mtp3.linkSetId = mtpLinkSet.id; - - ftmod_ss7_fill_in_mtpLink(&mtpLink[i]); - - /* increment the links counter */ - count++; - - /* increment the index value */ - i++; - } - - mtpLinkSet.linkType = mtpLink[0].mtp3.linkType; - mtpLinkSet.switchType = mtpLink[0].mtp3.switchType; - mtpLinkSet.ssf = mtpLink[0].mtp3.ssf; - ftmod_ss7_fill_in_mtpLinkSet(&mtpLinkSet); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *mtpLink) -{ - ftdm_conf_parameter_t *parm = mtp_link->parameters; - int num_parms = mtp_link->n_parameters; - int i; - - /* confirm that we are looking at an mtp_link */ - if (strcasecmp(mtp_link->name, "mtp_link")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp_link\"!\n",mtp_link->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"mtp_link\"...\n"); - } - - for (i = 0; i < num_parms; i++) { - /* try to match the parameter to what we expect */ - /**********************************************************************/ - if (!strcasecmp(parm->var, "name")) { - strncpy((char *)mtpLink->name, parm->val, MAX_NAME_LEN-1); - SS7_DEBUG("\tFound an \"mtp_link\" named = %s\n", mtpLink->name); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "span")) { - mtpLink->mtp1.span = atoi(parm->val); - SS7_DEBUG("\tFound mtpLink->span = %d\n", mtpLink->mtp1.span); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "chan")) { - mtpLink->mtp1.chan = atoi(parm->val); - SS7_DEBUG("\tFound mtpLink->chan = %d\n", mtpLink->mtp1.chan); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "errorType")) { - if (!strcasecmp(parm->val, "basic")) { - mtpLink->mtp2.errorType = SD_ERR_NRM; - } else if (!strcasecmp(parm->val, "pcr")) { - mtpLink->mtp2.errorType = SD_ERR_CYC; - } else { - SS7_ERROR("\tFound an invalid \"errorType\" = %s\n", parm->var); - return FTDM_FAIL; - } - SS7_DEBUG("\tFound mtpLink->errorType=%s\n", parm->val); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "lssuLength")) { - mtpLink->mtp2.lssuLength = atoi(parm->val); - if ((mtpLink->mtp2.lssuLength != 1) && (mtpLink->mtp2.lssuLength != 2)) { - SS7_ERROR("\tFound an invalid \"lssuLength\" = %d\n", mtpLink->mtp2.lssuLength); - return FTDM_FAIL; - } else { - SS7_DEBUG("\tFound mtpLink->lssuLength=%d\n", mtpLink->mtp2.lssuLength); - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "priority")) { - mtpLink->mtp3.priority = atoi(parm->val); - if ((mtpLink->mtp3.priority == 0) || (mtpLink->mtp3.priority == 1) || - (mtpLink->mtp3.priority == 2) || (mtpLink->mtp3.priority == 3)) { - SS7_DEBUG("\tFound mtpLink->priority = %d\n",mtpLink->mtp3.priority); - } else { - SS7_ERROR("\tFound an invalid \"priority\"=%d\n",mtpLink->mtp3.priority); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "linkType")) { - if (!strcasecmp(parm->val, "itu92")) { - mtpLink->mtp2.linkType = LSD_SW_ITU92; - mtpLink->mtp3.linkType = LSN_SW_ITU; - SS7_DEBUG("\tFound mtpLink->linkType = \"ITU92\"\n"); - } else if (!strcasecmp(parm->val, "itu88")) { - mtpLink->mtp2.linkType = LSD_SW_ITU88; - mtpLink->mtp3.linkType = LSN_SW_ITU; - SS7_DEBUG("\tFound mtpLink->linkType = \"ITU88\"\n"); - } else if (!strcasecmp(parm->val, "ansi96")) { - mtpLink->mtp2.linkType = LSD_SW_ANSI92; - mtpLink->mtp3.linkType = LSN_SW_ANS96; - SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI96\"\n"); - } else if (!strcasecmp(parm->val, "ansi92")) { - mtpLink->mtp2.linkType = LSD_SW_ANSI92; - mtpLink->mtp3.linkType = LSN_SW_ANS; - SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI92\"\n"); - } else if (!strcasecmp(parm->val, "ansi88")) { - mtpLink->mtp2.linkType = LSD_SW_ANSI88; - mtpLink->mtp3.linkType = LSN_SW_ANS; - SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI88\"\n"); - } else if (!strcasecmp(parm->val, "etsi")) { - mtpLink->mtp2.linkType = LSD_SW_ITU92; - mtpLink->mtp3.linkType = LSN_SW_ITU; - SS7_DEBUG("\tFound mtpLink->linkType = \"ETSI\"\n"); - } else { - SS7_ERROR("\tFound an invalid linktype of \"%s\"!\n", parm->val); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "switchType")) { - if (!strcasecmp(parm->val, "itu97")) { - mtpLink->mtp3.switchType = LSI_SW_ITU97; - SS7_DEBUG("\tFound mtpLink->switchType = \"ITU97\"\n"); - } else if (!strcasecmp(parm->val, "itu88")) { - mtpLink->mtp3.switchType = LSI_SW_ITU; - SS7_DEBUG("\tFound mtpLink->switchType = \"ITU88\"\n"); - } else if (!strcasecmp(parm->val, "itu92")) { - mtpLink->mtp3.switchType = LSI_SW_ITU; - SS7_DEBUG("\tFound mtpLink->switchType = \"ITU92\"\n"); - } else if (!strcasecmp(parm->val, "itu00")) { - mtpLink->mtp3.switchType = LSI_SW_ITU2000; - SS7_DEBUG("\tFound mtpLink->switchType = \"ITU00\"\n"); - } else if (!strcasecmp(parm->val, "ETSIV2")) { - mtpLink->mtp3.switchType = LSI_SW_ETSI; - SS7_DEBUG("\tFound mtpLink->switchType = \"ETSIV2\"\n"); - } else if (!strcasecmp(parm->val, "ETSIV3")) { - mtpLink->mtp3.switchType = LSI_SW_ETSIV3; - SS7_DEBUG("\tFound mtpLink->switchType = \"ETSIV3\"\n"); - } else if (!strcasecmp(parm->val, "UK")) { - mtpLink->mtp3.switchType = LSI_SW_UK; - SS7_DEBUG("\tFound mtpLink->switchType = \"UK\"\n"); - } else if (!strcasecmp(parm->val, "RUSSIA")) { - mtpLink->mtp3.switchType = LSI_SW_RUSSIA; - SS7_DEBUG("\tFound mtpLink->switchType = \"RUSSIA\"\n"); - } else if (!strcasecmp(parm->val, "INDIA")) { - mtpLink->mtp3.switchType = LSI_SW_INDIA; - SS7_DEBUG("\tFound mtpLink->switchType = \"INDIA\"\n"); - } else if (!strcasecmp(parm->val, "ansi88")) { - mtpLink->mtp3.switchType = LSI_SW_ANS88; - SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI88\"\n"); - } else if (!strcasecmp(parm->val, "ansi92")) { - mtpLink->mtp3.switchType = LSI_SW_ANS92; - SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI92\"\n"); - } else if (!strcasecmp(parm->val, "ansi95")) { - mtpLink->mtp3.switchType = LSI_SW_ANS95; - SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI95\"\n"); - } else { - SS7_ERROR("\tFound an invalid linktype of \"%s\"!\n", parm->val); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "ssf")) { - if (!strcasecmp(parm->val, "nat")) { - mtpLink->mtp3.ssf = SSF_NAT; - } else if (!strcasecmp(parm->val, "int")) { - mtpLink->mtp3.ssf = SSF_INTL; - } else if (!strcasecmp(parm->val, "spare")) { - mtpLink->mtp3.ssf = SSF_SPARE; - } else if (!strcasecmp(parm->val, "res")) { - mtpLink->mtp3.ssf = SSF_RES; - } else { - SS7_ERROR("\tFound an invalid ssf of \"%s\"!\n", parm->val); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "slc")) { - mtpLink->mtp3.slc = atoi(parm->val); - SS7_DEBUG("\tFound mtpLink->slc = \"%d\"\n",mtpLink->mtp3.slc); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t1")) { - mtpLink->mtp2.t1 = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t1 = \"%d\"\n",mtpLink->mtp2.t1); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t2")) { - mtpLink->mtp2.t2 = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t2 = \"%d\"\n",mtpLink->mtp2.t2); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t3")) { - mtpLink->mtp2.t3 = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t3 = \"%d\"\n",mtpLink->mtp2.t3); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t4n")) { - mtpLink->mtp2.t4n = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t4n = \"%d\"\n",mtpLink->mtp2.t4n); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t4e")) { - mtpLink->mtp2.t4e = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t4e = \"%d\"\n",mtpLink->mtp2.t4e); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t5")) { - mtpLink->mtp2.t5 = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t5 = \"%d\"\n",mtpLink->mtp2.t5); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t6")) { - mtpLink->mtp2.t6 = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t6 = \"%d\"\n",mtpLink->mtp2.t6); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t7")) { - mtpLink->mtp2.t7 = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t7 = \"%d\"\n",mtpLink->mtp2.t7); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t1")) { - mtpLink->mtp3.t1 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t1 = \"%d\"\n",mtpLink->mtp3.t1); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t2")) { - mtpLink->mtp3.t2 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t2 = \"%d\"\n",mtpLink->mtp3.t2); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t3")) { - mtpLink->mtp3.t3 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t3 = \"%d\"\n",mtpLink->mtp3.t3); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t4")) { - mtpLink->mtp3.t4 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t4 = \"%d\"\n",mtpLink->mtp3.t4); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t5")) { - mtpLink->mtp3.t5 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t5 = \"%d\"\n",mtpLink->mtp3.t5); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t7")) { - mtpLink->mtp3.t7 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t7 = \"%d\"\n",mtpLink->mtp3.t7); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t12")) { - mtpLink->mtp3.t12 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t12 = \"%d\"\n",mtpLink->mtp3.t12); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t13")) { - mtpLink->mtp3.t13 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t13 = \"%d\"\n",mtpLink->mtp3.t13); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t14")) { - mtpLink->mtp3.t14 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t14 = \"%d\"\n",mtpLink->mtp3.t14); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t17")) { - mtpLink->mtp3.t17 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t17 = \"%d\"\n",mtpLink->mtp3.t17); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t22")) { - mtpLink->mtp3.t22 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t22 = \"%d\"\n",mtpLink->mtp3.t22); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t23")) { - mtpLink->mtp3.t23 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t23 = \"%d\"\n",mtpLink->mtp3.t23); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t24")) { - mtpLink->mtp3.t24 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t24 = \"%d\"\n",mtpLink->mtp3.t24); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t31")) { - mtpLink->mtp3.t31 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t31 = \"%d\"\n",mtpLink->mtp3.t31); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t32")) { - mtpLink->mtp3.t32 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t32 = \"%d\"\n",mtpLink->mtp3.t32); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t33")) { - mtpLink->mtp3.t33 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t33 = \"%d\"\n",mtpLink->mtp3.t33); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t34")) { - mtpLink->mtp3.t34 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t34 = \"%d\"\n",mtpLink->mtp3.t34); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t35")) { - mtpLink->mtp3.t35 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t35 = \"%d\"\n",mtpLink->mtp3.t35); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t36")) { - mtpLink->mtp3.t36 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t36 = \"%d\"\n",mtpLink->mtp3.t36); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t37")) { - mtpLink->mtp3.t37 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t37 = \"%d\"\n",mtpLink->mtp3.t37); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.tcraft")) { - mtpLink->mtp3.tcraft = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 tcraft = \"%d\"\n",mtpLink->mtp3.tcraft); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.tflc")) { - mtpLink->mtp3.tflc = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 tflc = \"%d\"\n",mtpLink->mtp3.tflc); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.tbnd")) { - mtpLink->mtp3.tbnd = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 tbnd = \"%d\"\n",mtpLink->mtp3.tbnd); - /**********************************************************************/ - } else { - SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); - return FTDM_FAIL; + /* go through all the mtp3 links and fill in the apc */ + i = 1; + while (g_ftdm_sngss7_data.cfg.mtp3Link[i].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp3Link[i].linkSetId == mtpLinkSet.id) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].apc = mtpLinkSet.apc; } - - /* move to the next parameter */ - parm = parm + 1; + + i++; } - + return FTDM_SUCCESS; } @@ -813,6 +1269,7 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) int num_parms = mtp_route->n_parameters; int i; + /* initalize the mtpRoute structure */ memset(&mtpRoute, 0x0, sizeof(mtpRoute)); /* confirm that we are looking at an mtp_link */ @@ -824,119 +1281,120 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) } for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + /* try to match the parameter to what we expect */ - /**********************************************************************/ if (!strcasecmp(parm->var, "name")) { - strncpy((char *)mtpRoute.name, parm->val, MAX_NAME_LEN-1); - SS7_DEBUG("\tFound an \"mtp_route\" named = %s\n", mtpRoute.name); + /**********************************************************************/ + strcpy((char *)mtpRoute.name, parm->val); + SS7_DEBUG("Found an mtpRoute named = %s\n", mtpRoute.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "id")) { + /**********************************************************************/ + mtpRoute.id = atoi(parm->val); + SS7_DEBUG("Found an mtpRoute id = %d\n", mtpRoute.id); /**********************************************************************/ } else if (!strcasecmp(parm->var, "dpc")) { - mtpRoute.dpc = atoi(parm->val); - SS7_DEBUG("\tFound mtpRoute->dpc = %d\n", mtpRoute.dpc); /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp_linkset")) { - - /* find the linkset by it's name */ - int x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) { - /* check if the name matches */ - if (!strcasecmp((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, parm->val)) { - - /* now, harvest the required infomormation from the global structure */ - mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].linkType; - mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].switchType; - mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].ssf; - mtpRoute.linkSetId = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id; - cmbLinkSetId++; - mtpRoute.cmbLinkSetId = cmbLinkSetId; - - /* update the linkset with the new cmbLinkSet value */ - g_ftdm_sngss7_data.cfg.mtpLinkSet[x].numLinks++; - g_ftdm_sngss7_data.cfg.mtpLinkSet[x].links[g_ftdm_sngss7_data.cfg.mtpLinkSet[x].numLinks-1] = mtpRoute.cmbLinkSetId; - break; - } - x++; - } - - /* check why we exited the wile loop ... and react accordingly */ - if (mtpRoute.cmbLinkSetId == 0) { - SS7_ERROR("\tFailed to find the linkset = \"%s\"!\n", parm->val); - return FTDM_FAIL; - } else { - SS7_DEBUG("\tFound mtp3_route->linkset = %s\n", parm->val); - } + mtpRoute.dpc = atoi(parm->val); + SS7_DEBUG("Found an mtpRoute dpc = %d\n", mtpRoute.dpc); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "linksetId")) { + /**********************************************************************/ + mtpRoute.linkSetId = atoi(parm->val); + SS7_DEBUG("Found an mtpRoute linkset = %s\n", parm->val); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isSTP")) { + /**********************************************************************/ if (!strcasecmp(parm->val, "no")) { mtpRoute.isSTP = 0; - SS7_DEBUG("\tFound mtpRoute->isSTP = no\n"); + SS7_DEBUG("Found an mtpRoute isSTP = no\n"); } else if (!strcasecmp(parm->val, "yes")) { mtpRoute.isSTP = 1; - SS7_DEBUG("\tFound mtpRoute->isSTP = yes\n"); + SS7_DEBUG("Found an mtpRoute isSTP = yes\n"); } else { - SS7_ERROR("\tFound an invalid parameter for isSTP \"%s\"!\n", parm->val); + SS7_ERROR("Found an invalid parameter for isSTP %s!\n", parm->val); return FTDM_FAIL; } /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t6")) { + /**********************************************************************/ mtpRoute.t6 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t6 = \"%d\"\n",mtpRoute.t6); + SS7_DEBUG("Found an mtp3 t6 = %d\n",mtpRoute.t6); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t8")) { + /**********************************************************************/ mtpRoute.t8 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t8 = \"%d\"\n",mtpRoute.t8); + SS7_DEBUG("Found an mtp3 t8 = %d\n",mtpRoute.t8); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t10")) { + /**********************************************************************/ mtpRoute.t10 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t10 = \"%d\"\n",mtpRoute.t10); + SS7_DEBUG("Found an mtp3 t10 = %d\n",mtpRoute.t10); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t11")) { + /**********************************************************************/ mtpRoute.t11 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t11 = \"%d\"\n",mtpRoute.t11); + SS7_DEBUG("Found an mtp3 t11 = %d\n",mtpRoute.t11); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t15")) { + /**********************************************************************/ mtpRoute.t15 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t15 = \"%d\"\n",mtpRoute.t15); + SS7_DEBUG("Found an mtp3 t15 = %d\n",mtpRoute.t15); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t16")) { + /**********************************************************************/ mtpRoute.t16 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t16 = \"%d\"\n",mtpRoute.t16); + SS7_DEBUG("Found an mtp3 t16 = %d\n",mtpRoute.t16); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t18")) { + /**********************************************************************/ mtpRoute.t18 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t18 = \"%d\"\n",mtpRoute.t18); + SS7_DEBUG("Found an mtp3 t18 = %d\n",mtpRoute.t18); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t19")) { + /**********************************************************************/ mtpRoute.t19 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t19 = \"%d\"\n",mtpRoute.t19); + SS7_DEBUG("Found an mtp3 t19 = %d\n",mtpRoute.t19); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t21")) { + /**********************************************************************/ mtpRoute.t21 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t21 = \"%d\"\n",mtpRoute.t21); + SS7_DEBUG("Found an mtp3 t21 = %d\n",mtpRoute.t21); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t25")) { + /**********************************************************************/ mtpRoute.t25 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t25 = \"%d\"\n",mtpRoute.t25); + SS7_DEBUG("Found an mtp3 t25 = %d\n",mtpRoute.t25); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t26")) { + /**********************************************************************/ mtpRoute.t26 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t26 = \"%d\"\n",mtpRoute.t26); + SS7_DEBUG("Found an mtp3 t26 = %d\n",mtpRoute.t26); /**********************************************************************/ } else { - SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); + /**********************************************************************/ + SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); return FTDM_FAIL; - + /**********************************************************************/ } /* move to the next parameter */ parm = parm + 1; } - ftmod_ss7_fill_in_nsap(&mtpRoute); + /* pull up the linktype, switchtype, and SSF from the linkset */ + mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLinkSet[mtpRoute.linkSetId].linkType; + mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLinkSet[mtpRoute.linkSetId].switchType; + mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLinkSet[mtpRoute.linkSetId].ssf; + + /* fill in the rest of the values in the mtpRoute struct */ + mtpRoute.nwId = mtpRoute.id; + mtpRoute.cmbLinkSetId = mtpRoute.id; ftmod_ss7_fill_in_mtp3_route(&mtpRoute); - + ftmod_ss7_fill_in_nsap(&mtpRoute); return FTDM_SUCCESS; } @@ -979,10 +1437,9 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) ftdm_conf_parameter_t *parm = isup_interface->parameters; int num_parms = isup_interface->n_parameters; int i; - int linkSetId; - int flag_cld_nadi = 0; - int flag_clg_nadi = 0; + int ret; + /* initalize the isup intf and isap structure */ memset(&sng_isup, 0x0, sizeof(sng_isup)); memset(&sng_isap, 0x0, sizeof(sng_isap)); @@ -996,56 +1453,30 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + /* try to match the parameter to what we expect */ - /**********************************************************************/ if (!strcasecmp(parm->var, "name")) { - strncpy((char *)sng_isup.name, parm->val, MAX_NAME_LEN-1); - SS7_DEBUG("\tFound an \"isup_interface\" named = %s\n", sng_isup.name); + /**********************************************************************/ + strcpy((char *)sng_isup.name, parm->val); + SS7_DEBUG("Found an isup_interface named = %s\n", sng_isup.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "id")) { + /**********************************************************************/ + sng_isup.id = atoi(parm->val); + SS7_DEBUG("Found an isup id = %d\n", sng_isup.id); /**********************************************************************/ } else if (!strcasecmp(parm->var, "spc")) { + /**********************************************************************/ sng_isup.spc = atoi(parm->val); g_ftdm_sngss7_data.cfg.spc = sng_isup.spc; - SS7_DEBUG("\tFound SPC = %d\n", sng_isup.spc); + SS7_DEBUG("Found an isup SPC = %d\n", sng_isup.spc); /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp_route")) { - /* find the route by it's name */ - int x = 1; + } else if (!strcasecmp(parm->var, "mtprouteId")) { + /**********************************************************************/ + sng_isup.mtpRouteId=atoi(parm->val); - while (g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) { - - /* check if the name matches */ - if (!strcasecmp((char *)g_ftdm_sngss7_data.cfg.mtpRoute[x].name, parm->val)) { - /* now, harvest the required information from the global structure */ - sng_isup.mtpRouteId = g_ftdm_sngss7_data.cfg.mtpRoute[x].id; - sng_isup.dpc = g_ftdm_sngss7_data.cfg.mtpRoute[x].dpc; - sng_isup.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType; - sng_isap.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType; - - /* find the NSAP corresponding to this switchType and SSF */ - int z = 1; - while (g_ftdm_sngss7_data.cfg.nsap[z].id != 0) { - if ((g_ftdm_sngss7_data.cfg.nsap[z].linkType == g_ftdm_sngss7_data.cfg.mtpRoute[x].linkType) && - (g_ftdm_sngss7_data.cfg.nsap[z].switchType == g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType) && - (g_ftdm_sngss7_data.cfg.nsap[z].ssf == g_ftdm_sngss7_data.cfg.mtpRoute[x].ssf)) { - sng_isup.nwId = g_ftdm_sngss7_data.cfg.nsap[z].nwId; - /* we have a match so break out of this loop */ - break; - } - /* move on to the next one */ - z++; - } - break; - } - x++; - } /* while (g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) */ - - /* check why we exited the while loop ... and react accordingly */ - if (sng_isup.mtpRouteId == 0) { - SS7_ERROR("\tFailed to find the MTP3 Route = \"%s\"!\n", parm->val); - return FTDM_FAIL; - } else { - SS7_DEBUG("\tFound MTP3 Route = %s\n", parm->val); - } + SS7_DEBUG("Found an isup mptRouteId = %d\n", sng_isup.mtpRouteId); /**********************************************************************/ } else if (!strcasecmp(parm->var, "min_digits")) { sng_isup.min_digits = atoi(parm->val); @@ -1053,300 +1484,544 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) SS7_DEBUG("\tFound min_digits = %d\n", sng_isup.min_digits); /**********************************************************************/ } else if (!strcasecmp(parm->var, "ssf")) { - if (!strcasecmp(parm->val, "nat")) { - sng_isup.ssf = SSF_NAT; - sng_isap.ssf = SSF_NAT; - } else if (!strcasecmp(parm->val, "int")) { - sng_isup.ssf = SSF_INTL; - sng_isap.ssf = SSF_INTL; - } else if (!strcasecmp(parm->val, "spare")) { - sng_isup.ssf = SSF_SPARE; - sng_isap.ssf = SSF_SPARE; - } else if (!strcasecmp(parm->val, "res")) { - sng_isup.ssf = SSF_RES; - sng_isap.ssf = SSF_RES; - } else { - SS7_ERROR("\tFound an invalid ssf of \"%s\"!\n", parm->val); + /**********************************************************************/ + ret = find_ssf_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid isup ssf = %s\n", parm->var); return FTDM_FAIL; + } else { + sng_isup.ssf = sng_ssf_type_map[ret].tril_type; + sng_isap.ssf = sng_ssf_type_map[ret].tril_type; + SS7_DEBUG("Found an isup ssf = %s\n", sng_ssf_type_map[ret].sng_type); } /**********************************************************************/ - } else if (!strcasecmp(parm->var, "license")) { - /**********************************************************************/ - strncpy(g_ftdm_sngss7_data.cfg.license, parm->val, MAX_PATH-1); - strncpy(g_ftdm_sngss7_data.cfg.signature, parm->val, MAX_PATH-1); - strcat(g_ftdm_sngss7_data.cfg.signature, ".sig"); - SS7_DEBUG("\tFound license file = %s\n", g_ftdm_sngss7_data.cfg.license); - SS7_DEBUG("\tFound signature file = %s\n", g_ftdm_sngss7_data.cfg.signature); - /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t1")) { + /**********************************************************************/ sng_isap.t1 = atoi(parm->val); - SS7_DEBUG("\tFound isup t1 = \"%d\"\n",sng_isap.t1); + SS7_DEBUG("Found isup t1 = %d\n",sng_isap.t1); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t2")) { + /**********************************************************************/ sng_isap.t2 = atoi(parm->val); - SS7_DEBUG("\tFound isup t2 = \"%d\"\n",sng_isap.t2); + SS7_DEBUG("Found isup t2 = %d\n",sng_isap.t2); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t4")) { + /**********************************************************************/ sng_isup.t4 = atoi(parm->val); - SS7_DEBUG("\tFound isup t4 = \"%d\"\n",sng_isup.t4); + SS7_DEBUG("Found isup t4 = %d\n",sng_isup.t4); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t5")) { + /**********************************************************************/ sng_isap.t5 = atoi(parm->val); - SS7_DEBUG("\tFound isup t5 = \"%d\"\n",sng_isap.t5); + SS7_DEBUG("Found isup t5 = %d\n",sng_isap.t5); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t6")) { + /**********************************************************************/ sng_isap.t6 = atoi(parm->val); - SS7_DEBUG("\tFound isup t6 = \"%d\"\n",sng_isap.t6); + SS7_DEBUG("Found isup t6 = %d\n",sng_isap.t6); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t7")) { + /**********************************************************************/ sng_isap.t7 = atoi(parm->val); - SS7_DEBUG("\tFound isup t7 = \"%d\"\n",sng_isap.t7); + SS7_DEBUG("Found isup t7 = %d\n",sng_isap.t7); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t8")) { + /**********************************************************************/ sng_isap.t8 = atoi(parm->val); - SS7_DEBUG("\tFound isup t8 = \"%d\"\n",sng_isap.t8); + SS7_DEBUG("Found isup t8 = %d\n",sng_isap.t8); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t9")) { + /**********************************************************************/ sng_isap.t9 = atoi(parm->val); - SS7_DEBUG("\tFound isup t9 = \"%d\"\n",sng_isap.t9); + SS7_DEBUG("Found isup t9 = %d\n",sng_isap.t9); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t10")) { + /**********************************************************************/ sng_isup.t10 = atoi(parm->val); - SS7_DEBUG("\tFound isup t10 = \"%d\"\n",sng_isup.t10); + SS7_DEBUG("Found isup t10 = %d\n",sng_isup.t10); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t11")) { + /**********************************************************************/ sng_isup.t11 = atoi(parm->val); - SS7_DEBUG("\tFound isup t11 = \"%d\"\n",sng_isup.t11); + SS7_DEBUG("Found isup t11 = %d\n",sng_isup.t11); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t18")) { + /**********************************************************************/ sng_isup.t18 = atoi(parm->val); - SS7_DEBUG("\tFound isup t18 = \"%d\"\n",sng_isup.t18); + SS7_DEBUG("Found isup t18 = %d\n",sng_isup.t18); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t19")) { + /**********************************************************************/ sng_isup.t19 = atoi(parm->val); - SS7_DEBUG("\tFound isup t19 = \"%d\"\n",sng_isup.t19); + SS7_DEBUG("Found isup t19 = %d\n",sng_isup.t19); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t20")) { + /**********************************************************************/ sng_isup.t20 = atoi(parm->val); - SS7_DEBUG("\tFound isup t20 = \"%d\"\n",sng_isup.t20); + SS7_DEBUG("Found isup t20 = %d\n",sng_isup.t20); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t21")) { + /**********************************************************************/ sng_isup.t21 = atoi(parm->val); - SS7_DEBUG("\tFound isup t21 = \"%d\"\n",sng_isup.t21); + SS7_DEBUG("Found isup t21 = %d\n",sng_isup.t21); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t22")) { + /**********************************************************************/ sng_isup.t22 = atoi(parm->val); - SS7_DEBUG("\tFound isup t22 = \"%d\"\n",sng_isup.t22); + SS7_DEBUG("Found isup t22 = %d\n",sng_isup.t22); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t23")) { + /**********************************************************************/ sng_isup.t23 = atoi(parm->val); - SS7_DEBUG("\tFound isup t23 = \"%d\"\n",sng_isup.t23); + SS7_DEBUG("Found isup t23 = %d\n",sng_isup.t23); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t24")) { + /**********************************************************************/ sng_isup.t24 = atoi(parm->val); - SS7_DEBUG("\tFound isup t24 = \"%d\"\n",sng_isup.t24); + SS7_DEBUG("Found isup t24 = %d\n",sng_isup.t24); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t25")) { + /**********************************************************************/ sng_isup.t25 = atoi(parm->val); - SS7_DEBUG("\tFound isup t25 = \"%d\"\n",sng_isup.t25); + SS7_DEBUG("Found isup t25 = %d\n",sng_isup.t25); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t26")) { + /**********************************************************************/ sng_isup.t26 = atoi(parm->val); - SS7_DEBUG("\tFound isup t26 = \"%d\"\n",sng_isup.t26); + SS7_DEBUG("Found isup t26 = %d\n",sng_isup.t26); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t28")) { + /**********************************************************************/ sng_isup.t28 = atoi(parm->val); - SS7_DEBUG("\tFound isup t28 = \"%d\"\n",sng_isup.t28); + SS7_DEBUG("Found isup t28 = %d\n",sng_isup.t28); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t29")) { + /**********************************************************************/ sng_isup.t29 = atoi(parm->val); - SS7_DEBUG("\tFound isup t29 = \"%d\"\n",sng_isup.t29); + SS7_DEBUG("Found isup t29 = %d\n",sng_isup.t29); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t30")) { + /**********************************************************************/ sng_isup.t30 = atoi(parm->val); - SS7_DEBUG("\tFound isup t30 = \"%d\"\n",sng_isup.t30); + SS7_DEBUG("Found isup t30 = %d\n",sng_isup.t30); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t31")) { + /**********************************************************************/ sng_isap.t31 = atoi(parm->val); - SS7_DEBUG("\tFound isup t31 = \"%d\"\n",sng_isap.t31); + SS7_DEBUG("Found isup t31 = %d\n",sng_isap.t31); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t32")) { + /**********************************************************************/ sng_isup.t32 = atoi(parm->val); - SS7_DEBUG("\tFound isup t32 = \"%d\"\n",sng_isup.t32); + SS7_DEBUG("Found isup t32 = %d\n",sng_isup.t32); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t33")) { + /**********************************************************************/ sng_isap.t33 = atoi(parm->val); - SS7_DEBUG("\tFound isup t33 = \"%d\"\n",sng_isap.t33); + SS7_DEBUG("Found isup t33 = %d\n",sng_isap.t33); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t34")) { - sng_isap.t34 = atoi(parm->val); - SS7_DEBUG("\tFound isup t34 = \"%d\"\n",sng_isap.t34); /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t35")) { - sng_isup.t35 = atoi(parm->val); - SS7_DEBUG("\tFound isup t35 = \"%d\"\n",sng_isup.t35); + sng_isap.t34 = atoi(parm->val); + SS7_DEBUG("Found isup t34 = %d\n",sng_isap.t34); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t36")) { + /**********************************************************************/ sng_isap.t36 = atoi(parm->val); - SS7_DEBUG("\tFound isup t36 = \"%d\"\n",sng_isap.t36); + SS7_DEBUG("Found isup t36 = %d\n",sng_isap.t36); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t37")) { + /**********************************************************************/ sng_isup.t37 = atoi(parm->val); - SS7_DEBUG("\tFound isup t37 = \"%d\"\n",sng_isup.t37); + SS7_DEBUG("Found isup t37 = %d\n",sng_isup.t37); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t38")) { + /**********************************************************************/ sng_isup.t38 = atoi(parm->val); - SS7_DEBUG("\tFound isup t38 = \"%d\"\n",sng_isup.t38); + SS7_DEBUG("Found isup t38 = %d\n",sng_isup.t38); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t39")) { + /**********************************************************************/ sng_isup.t39 = atoi(parm->val); - SS7_DEBUG("\tFound isup t39 = \"%d\"\n",sng_isup.t39); + SS7_DEBUG("Found isup t39 = %d\n",sng_isup.t39); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tccr")) { + /**********************************************************************/ sng_isap.tccr = atoi(parm->val); - SS7_DEBUG("\tFound isup tccr = \"%d\"\n",sng_isap.tccr); + SS7_DEBUG("Found isup tccr = %d\n",sng_isap.tccr); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tccrt")) { + /**********************************************************************/ sng_isap.tccrt = atoi(parm->val); - SS7_DEBUG("\tFound isup tccrt = \"%d\"\n",sng_isap.tccrt); + SS7_DEBUG("Found isup tccrt = %d\n",sng_isap.tccrt); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tex")) { + /**********************************************************************/ sng_isap.tex = atoi(parm->val); - SS7_DEBUG("\tFound isup tex = \"%d\"\n",sng_isap.tex); + SS7_DEBUG("Found isup tex = %d\n",sng_isap.tex); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tect")) { + /**********************************************************************/ sng_isap.tect = atoi(parm->val); - SS7_DEBUG("\tFound isup tect = \"%d\"\n",sng_isap.tect); + SS7_DEBUG("Found isup tect = %d\n",sng_isap.tect); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tcrm")) { + /**********************************************************************/ sng_isap.tcrm = atoi(parm->val); - SS7_DEBUG("\tFound isup tcrm = \"%d\"\n",sng_isap.tcrm); + SS7_DEBUG("Found isup tcrm = %d\n",sng_isap.tcrm); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tcra")) { + /**********************************************************************/ sng_isap.tcra = atoi(parm->val); - SS7_DEBUG("\tFound isup tcra = \"%d\"\n",sng_isap.tcra); + SS7_DEBUG("Found isup tcra = %d\n",sng_isap.tcra); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tfgr")) { + /**********************************************************************/ sng_isup.tfgr = atoi(parm->val); - SS7_DEBUG("\tFound isup tfgr = \"%d\"\n",sng_isup.tfgr); + SS7_DEBUG("Found isup tfgr = %d\n",sng_isup.tfgr); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.trelrsp")) { + /**********************************************************************/ sng_isap.trelrsp = atoi(parm->val); - SS7_DEBUG("\tFound isup trelrsp = \"%d\"\n",sng_isap.trelrsp); + SS7_DEBUG("Found isup trelrsp = %d\n",sng_isap.trelrsp); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tfnlrelrsp")) { + /**********************************************************************/ sng_isap.tfnlrelrsp = atoi(parm->val); - SS7_DEBUG("\tFound isup tfnlrelrsp = \"%d\"\n",sng_isap.tfnlrelrsp); + SS7_DEBUG("Found isup tfnlrelrsp = %d\n",sng_isap.tfnlrelrsp); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tfnlrelrsp")) { + /**********************************************************************/ sng_isap.tfnlrelrsp = atoi(parm->val); - SS7_DEBUG("\tFound isup tfnlrelrsp = \"%d\"\n",sng_isap.tfnlrelrsp); + SS7_DEBUG("Found isup tfnlrelrsp = %d\n",sng_isap.tfnlrelrsp); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tpause")) { + /**********************************************************************/ sng_isup.tpause = atoi(parm->val); - SS7_DEBUG("\tFound isup tpause = \"%d\"\n",sng_isup.tpause); + SS7_DEBUG("Found isup tpause = %d\n",sng_isup.tpause); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tstaenq")) { + /**********************************************************************/ sng_isup.tstaenq = atoi(parm->val); - SS7_DEBUG("\tFound isup tstaenq = \"%d\"\n",sng_isup.tstaenq); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "clg_nadi")) { - /**********************************************************************/ - /* throw the flag so that we know we got this optional parameter */ - flag_clg_nadi = 1; - sng_isup.clg_nadi = atoi(parm->val); - SS7_DEBUG("\tFound default CLG_NADI value = %d\n", sng_isup.clg_nadi); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "cld_nadi")) { - /**********************************************************************/ - /* throw the flag so that we know we got this optional parameter */ - flag_cld_nadi = 1; - sng_isup.cld_nadi = atoi(parm->val); - SS7_DEBUG("\tFound default CLD_NADI value = %d\n", sng_isup.cld_nadi); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "obci_bita")) { - /**********************************************************************/ - if (*parm->val == '1') { - sngss7_set_options(&sng_isup, SNGSS7_ACM_OBCI_BITA); - SS7_DEBUG("\tFound Optional Backwards Indicator: Bit A (early media) enable option\n"); - } else if (*parm->val == '0') { - sngss7_clear_options(&sng_isup, SNGSS7_ACM_OBCI_BITA); - SS7_DEBUG("\tFound Optional Backwards Indicator: Bit A (early media) disable option\n"); - } else { - SS7_DEBUG("\tInvalid value for \"obci_bita\" option\n"); - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "lpa_on_cot")) { - /**********************************************************************/ - if (*parm->val == '1') { - sngss7_set_options(&sng_isup, SNGSS7_LPA_FOR_COT); - SS7_DEBUG("\tFound Tx LPA on COT enable option\n"); - } else if (*parm->val == '0') { - sngss7_clear_options(&sng_isup, SNGSS7_LPA_FOR_COT); - SS7_DEBUG("\tFound Tx LPA on COT disable option\n"); - } else { - SS7_DEBUG("\tInvalid value for \"lpa_on_cot\" option\n"); - } + SS7_DEBUG("Found isup tstaenq = %d\n",sng_isup.tstaenq); /**********************************************************************/ } else { - SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); + /**********************************************************************/ + SS7_ERROR("Found an invalid parameter %s!\n", parm->val); return FTDM_FAIL; - + /**********************************************************************/ } /* move to the next parameter */ parm = parm + 1; - } + /**************************************************************************/ + } /* for (i = 0; i < num_parms; i++) */ - /* check if the user filled in a nadi value by looking at flag */ - if (!flag_cld_nadi) { - /* default the nadi value to national */ - sng_isup.cld_nadi = 0x03; - } - - if (!flag_clg_nadi) { - /* default the nadi value to national */ - sng_isup.clg_nadi = 0x03; - } - - /* check if the user requested min_digits value */ - if (sng_isup.min_digits == 0) { - /* default to 7 */ - sng_isup.min_digits = 7; - } - + /* default the interface to paused state */ + sngss7_set_flag(&sng_isup, SNGSS7_PAUSED); /* trickle down the SPC to all sub entities */ + int linkSetId; + linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].linkSetId; i = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[i].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.linkSetId == linkSetId) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.spc = g_ftdm_sngss7_data.cfg.spc; + 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++; } + /* pull values from the lower levels */ + sng_isup.dpc = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].dpc; + sng_isup.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].switchType; + sng_isup.nwId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].nwId; + + sng_isap.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].switchType; + ftmod_ss7_fill_in_isap(&sng_isap); sng_isup.isap = sng_isap.id; ftmod_ss7_fill_in_isup_interface(&sng_isup); + /* setup the self mtp3 route */ + i = sng_isup.mtpRouteId; + + if(ftmod_ss7_fill_in_self_route(sng_isup.spc, + g_ftdm_sngss7_data.cfg.mtpRoute[i].linkType, + g_ftdm_sngss7_data.cfg.mtpRoute[i].switchType, + g_ftdm_sngss7_data.cfg.mtpRoute[i].ssf)) { + + SS7_ERROR("Failed to fill in self route structure!\n"); + return FTDM_FAIL; + + } + return FTDM_SUCCESS; } /******************************************************************************/ -static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink) +static int ftmod_ss7_parse_cc_spans(ftdm_conf_node_t *cc_spans) +{ + ftdm_conf_node_t *cc_span = NULL; + + /* confirm that we are looking at cc_spans */ + if (strcasecmp(cc_spans->name, "cc_spans")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"cc_spans\"!\n",cc_spans->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"cc_spans\"...\n"); + } + + /* extract the cc_spans */ + cc_span = cc_spans->child; + + while (cc_span != NULL) { + /* parse the found cc_span */ + if (ftmod_ss7_parse_cc_span(cc_span)) { + SS7_ERROR("Failed to parse \"cc_span\"\n"); + return FTDM_FAIL; + } + + /* go to the next cc_span */ + cc_span = cc_span->next; + } + + return FTDM_SUCCESS; + +} + +/******************************************************************************/ +static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span) +{ + sng_ccSpan_t sng_ccSpan; + ftdm_conf_parameter_t *parm = cc_span->parameters; + int num_parms = cc_span->n_parameters; + int flag_clg_nadi = 0; + int flag_cld_nadi = 0; + int i; + int ret; + + /* initalize the ccSpan structure */ + memset(&sng_ccSpan, 0x0, sizeof(sng_ccSpan)); + + /* confirm that we are looking at an mtp_link */ + if (strcasecmp(cc_span->name, "cc_span")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"cc_span\"!\n",cc_span->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"cc_span\"...\n"); + } + + + for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + + /* try to match the parameter to what we expect */ + if (!strcasecmp(parm->var, "name")) { + /**********************************************************************/ + strcpy((char *)sng_ccSpan.name, parm->val); + SS7_DEBUG("Found an ccSpan named = %s\n", sng_ccSpan.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "id")) { + /**********************************************************************/ + sng_ccSpan.id = atoi(parm->val); + SS7_DEBUG("Found an ccSpan id = %d\n", sng_ccSpan.id); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "procid")) { + /**********************************************************************/ + sng_ccSpan.procId = atoi(parm->val); + SS7_DEBUG("Found an ccSpan procId = %d\n", sng_ccSpan.procId); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "ch_map")) { + /**********************************************************************/ + strcpy(sng_ccSpan.ch_map, parm->val); + SS7_DEBUG("Found channel map %s\n", sng_ccSpan.ch_map); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "typeCntrl")) { + /**********************************************************************/ + ret = find_cic_cntrl_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid ccSpan typeCntrl = %s\n", parm->var); + return FTDM_FAIL; + } else { + sng_ccSpan.typeCntrl = sng_cic_cntrl_type_map[ret].tril_type; + SS7_DEBUG("Found an ccSpan typeCntrl = %s\n", sng_cic_cntrl_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "ssf")) { + /**********************************************************************/ + ret = find_ssf_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid ccSpan ssf = %s\n", parm->var); + return FTDM_FAIL; + } else { + sng_ccSpan.ssf = sng_ssf_type_map[ret].tril_type; + SS7_DEBUG("Found an ccSpan ssf = %s\n", sng_ssf_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "switchType")) { + /**********************************************************************/ + ret = find_switch_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid ccSpan switchType = %s\n", parm->var); + return FTDM_FAIL; + } else { + sng_ccSpan.switchType = sng_switch_type_map[ret].tril_isup_type; + SS7_DEBUG("Found an ccSpan switchType = %s\n", sng_switch_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "cicbase")) { + /**********************************************************************/ + sng_ccSpan.cicbase = atoi(parm->val); + SS7_DEBUG("Found a cicbase = %d\n", sng_ccSpan.cicbase); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup_interface")) { + /**********************************************************************/ + sng_ccSpan.isupInf = atoi(parm->val); + SS7_DEBUG("Found an isup_interface = %d\n",sng_ccSpan.isupInf); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "min_digits")) { + /**********************************************************************/ + sng_ccSpan.min_digits = atoi(parm->val); + SS7_DEBUG("Found a min_digits = %d\n",sng_ccSpan.min_digits); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "clg_nadi")) { + /**********************************************************************/ + /* throw the flag so that we know we got this optional parameter */ + flag_clg_nadi = 1; + sng_ccSpan.clg_nadi = atoi(parm->val); + SS7_DEBUG("Found default CLG_NADI parm->value = %d\n", sng_ccSpan.clg_nadi); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "cld_nadi")) { + /**********************************************************************/ + /* throw the flag so that we know we got this optional parameter */ + flag_cld_nadi = 1; + sng_ccSpan.cld_nadi = atoi(parm->val); + SS7_DEBUG("Found default CLD_NADI parm->value = %d\n", sng_ccSpan.cld_nadi); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "obci_bita")) { + /**********************************************************************/ + if (*parm->val == '1') { + sngss7_set_options(&sng_ccSpan, SNGSS7_ACM_OBCI_BITA); + SS7_DEBUG("Found Optional Backwards Indicator: Bit A (early media) enable option\n"); + } else if (*parm->val == '0') { + sngss7_clear_options(&sng_ccSpan, SNGSS7_ACM_OBCI_BITA); + SS7_DEBUG("Found Optional Backwards Indicator: Bit A (early media) disable option\n"); + } else { + SS7_DEBUG("Invalid parm->value for obci_bita option\n"); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "lpa_on_cot")) { + /**********************************************************************/ + if (*parm->val == '1') { + sngss7_set_options(&sng_ccSpan, SNGSS7_LPA_FOR_COT); + SS7_DEBUG("Found Tx LPA on COT enable option\n"); + } else if (*parm->val == '0') { + sngss7_clear_options(&sng_ccSpan, SNGSS7_LPA_FOR_COT); + SS7_DEBUG("Found Tx LPA on COT disable option\n"); + } else { + SS7_DEBUG("Invalid parm->value for lpa_on_cot option\n"); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t3")) { + /**********************************************************************/ + sng_ccSpan.t3 = atoi(parm->val); + SS7_DEBUG("Found isup t3 = %d\n", sng_ccSpan.t3); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t12")) { + /**********************************************************************/ + sng_ccSpan.t12 = atoi(parm->val); + SS7_DEBUG("Found isup t12 = %d\n", sng_ccSpan.t12); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t13")) { + /**********************************************************************/ + sng_ccSpan.t13 = atoi(parm->val); + SS7_DEBUG("Found isup t13 = %d\n", sng_ccSpan.t13); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t14")) { + /**********************************************************************/ + sng_ccSpan.t14 = atoi(parm->val); + SS7_DEBUG("Found isup t14 = %d\n", sng_ccSpan.t14); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t15")) { + /**********************************************************************/ + sng_ccSpan.t15 = atoi(parm->val); + SS7_DEBUG("Found isup t15 = %d\n", sng_ccSpan.t15); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t16")) { + /**********************************************************************/ + sng_ccSpan.t16 = atoi(parm->val); + SS7_DEBUG("Found isup t16 = %d\n", sng_ccSpan.t16); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t17")) { + /**********************************************************************/ + sng_ccSpan.t17 = atoi(parm->val); + SS7_DEBUG("Found isup t17 = %d\n", sng_ccSpan.t17); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t35")) { + /**********************************************************************/ + sng_ccSpan.t35 = atoi(parm->val); + SS7_DEBUG("Found isup t35 = %d\n",sng_ccSpan.t35); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.tval")) { + /**********************************************************************/ + sng_ccSpan.tval = atoi(parm->val); + SS7_DEBUG("Found isup tval = %d\n", sng_ccSpan.tval); + /**********************************************************************/ + } else { + /**********************************************************************/ + SS7_ERROR("Found an invalid parameter %s!\n", parm->var); + return FTDM_FAIL; + /**********************************************************************/ + } + + /* move to the next parameter */ + parm = parm + 1; + /**************************************************************************/ + } /* for (i = 0; i < num_parms; i++) */ + + /* check if the user filled in a nadi value by looking at flag */ + if (!flag_cld_nadi) { + /* default the nadi value to national */ + sng_ccSpan.cld_nadi = 0x03; + } + + if (!flag_clg_nadi) { + /* default the nadi value to national */ + sng_ccSpan.clg_nadi = 0x03; + } + + /* add this span to our global listing */ + ftmod_ss7_fill_in_ccSpan(&sng_ccSpan); + + /* make sure the isup interface structure has something in it */ + if (g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf].id == 0) { + /* fill in the id, so that we know it exists */ + g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf].id = sng_ccSpan.isupInf; + + /* default the status to PAUSED */ + sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf], SNGSS7_PAUSED); + } + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_fill_in_relay_channel(sng_relay_t *relay_channel) { int i; - /* go through all the existing links and see if we find a match */ + /* go through all the existing channels and see if we find a match */ i = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[i].id != 0) { - if ((g_ftdm_sngss7_data.cfg.mtpLink[i].mtp1.span == mtpLink->mtp1.span) && - (g_ftdm_sngss7_data.cfg.mtpLink[i].mtp1.chan == mtpLink->mtp1.chan)) { + while (g_ftdm_sngss7_data.cfg.relay[i].id != 0) { + if ((g_ftdm_sngss7_data.cfg.relay[i].type == relay_channel->type) && + (g_ftdm_sngss7_data.cfg.relay[i].port == relay_channel->port) && + (g_ftdm_sngss7_data.cfg.relay[i].procId == relay_channel->procId) && + (!strcasecmp(g_ftdm_sngss7_data.cfg.relay[i].hostname, relay_channel->hostname))) { /* we have a match so break out of this loop */ break; @@ -1355,178 +2030,272 @@ static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink) i++; } - /* if the id value is 0 that means we didn't find the link */ - if (g_ftdm_sngss7_data.cfg.mtpLink[i].id == 0) { - mtpLink->id = i; - SS7_DEBUG("found new mtpLink on span=%d, chan=%d, id = %d\n", - mtpLink->mtp1.span, - mtpLink->mtp1.chan, - mtpLink->id); + /* if the id value is 0 that means we didn't find the relay channel */ + if (g_ftdm_sngss7_data.cfg.relay[i].id == 0) { + relay_channel->id = i; + SS7_DEBUG("found new relay channel on type:%d, hostname:%s, port:%d, procId:%d, id = %d\n", + relay_channel->type, + relay_channel->hostname, + relay_channel->port, + relay_channel->procId, + relay_channel->id); + sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY); } else { - mtpLink->id = i; - SS7_DEBUG("found existing mtpLink on span=%d, chan=%d, id = %d\n", - mtpLink->mtp1.span, - mtpLink->mtp1.chan, - mtpLink->id); + relay_channel->id = i; + SS7_DEBUG("found existing relay channel on type:%d, hostname:%s, port:%d, procId:%d, id = %d\n", + relay_channel->type, + relay_channel->hostname, + relay_channel->port, + relay_channel->procId, + relay_channel->id); } - /* fill in the information */ - strncpy((char *)g_ftdm_sngss7_data.cfg.mtpLink[i].name, (char *)mtpLink->name, MAX_NAME_LEN-1); + g_ftdm_sngss7_data.cfg.relay[i].id = relay_channel->id; + g_ftdm_sngss7_data.cfg.relay[i].type = relay_channel->type; + g_ftdm_sngss7_data.cfg.relay[i].port = relay_channel->port; + g_ftdm_sngss7_data.cfg.relay[i].procId = relay_channel->procId; + strcpy(g_ftdm_sngss7_data.cfg.relay[i].hostname, relay_channel->hostname); + strcpy(g_ftdm_sngss7_data.cfg.relay[i].name, relay_channel->name); - g_ftdm_sngss7_data.cfg.mtpLink[i].id = mtpLink->id; - - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp1.span = mtpLink->mtp1.span; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp1.chan = mtpLink->mtp1.chan; - - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.linkType = mtpLink->mtp2.linkType; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.errorType = mtpLink->mtp2.errorType; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.lssuLength = mtpLink->mtp2.lssuLength; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.mtp1Id = mtpLink->id; - - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.priority = mtpLink->mtp3.priority; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.linkType = mtpLink->mtp3.linkType; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.switchType = mtpLink->mtp3.switchType; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.apc = mtpLink->mtp3.apc; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.spc = g_ftdm_sngss7_data.cfg.spc; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.ssf = mtpLink->mtp3.ssf; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.slc = mtpLink->mtp3.slc; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.linkSetId = mtpLink->mtp3.linkSetId; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.mtp2Id = mtpLink->id; - - if ( mtpLink->mtp2.t1 != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t1 = mtpLink->mtp2.t1; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t1 = 500; - } - if ( mtpLink->mtp2.t2 != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t2 = mtpLink->mtp2.t2; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t2 = 250; - } - if ( mtpLink->mtp2.t3 != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t3 = mtpLink->mtp2.t3; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t3 = 20; - } - if ( mtpLink->mtp2.t4n != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t4n = mtpLink->mtp2.t4n; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t4n = 80; - } - if ( mtpLink->mtp2.t4e != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t4e = mtpLink->mtp2.t4e; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t4e = 5; - } - if ( mtpLink->mtp2.t5 != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t5 = mtpLink->mtp2.t5; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t5 = 1; - } - if ( mtpLink->mtp2.t6 != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t6 = mtpLink->mtp2.t6; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t6 = 60; - } - if ( mtpLink->mtp2.t7 != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t7 = mtpLink->mtp2.t7; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t7 = 40; + /* if this is THE listen channel grab the procId and use it */ + if (relay_channel->type == LRY_CT_TCP_LISTEN) { + g_ftdm_sngss7_data.cfg.procId = relay_channel->procId; } - if (mtpLink->mtp3.t1 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t1 = mtpLink->mtp3.t1; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t1 = 8; - } - if (mtpLink->mtp3.t2 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t2 = mtpLink->mtp3.t2; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t2 = 14; - } - if (mtpLink->mtp3.t3 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t3 = mtpLink->mtp3.t3; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t3 = 8; - } - if (mtpLink->mtp3.t4 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t4 = mtpLink->mtp3.t4; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t4 = 8; - } - if (mtpLink->mtp3.t5 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t5 = mtpLink->mtp3.t5; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t5 = 8; - } - if (mtpLink->mtp3.t7 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t7 = mtpLink->mtp3.t7; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t7 = 15; - } - if (mtpLink->mtp3.t12 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t12 = mtpLink->mtp3.t12; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t12 = 15; - } - if (mtpLink->mtp3.t13 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t13 = mtpLink->mtp3.t13; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t13 = 15; - } - if (mtpLink->mtp3.t14 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t14 = mtpLink->mtp3.t14; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t14 = 30; - } - if (mtpLink->mtp3.t17 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t17 = mtpLink->mtp3.t17; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t17 = 15; - } - if (mtpLink->mtp3.t22 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t22 = mtpLink->mtp3.t22; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t22 = 1800; - } - if (mtpLink->mtp3.t23 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t23 = mtpLink->mtp3.t23; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t23 = 1800; - } - if (mtpLink->mtp3.t24 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t24 = mtpLink->mtp3.t24; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t24 = 5; - } - if (mtpLink->mtp3.t31 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t31 = mtpLink->mtp3.t31; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t31 = 50; - } - if (mtpLink->mtp3.t32 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t32 = mtpLink->mtp3.t32; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t32 = 120; - } - if (mtpLink->mtp3.t33 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t33 = mtpLink->mtp3.t33; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t33 = 3000; - } - if (mtpLink->mtp3.t34 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t34 = mtpLink->mtp3.t34; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t34 = 600; - } - if (mtpLink->mtp3.tflc != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.tflc = mtpLink->mtp3.tflc; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.tflc = 300; - } - return (mtpLink->id); + return FTDM_SUCCESS; } +/******************************************************************************/ +static int ftmod_ss7_fill_in_mtp1_link(sng_mtp1_link_t *mtp1Link) +{ + int i = mtp1Link->id; + + /* check if this id value has been used already */ + if (g_ftdm_sngss7_data.cfg.mtp1Link[i].id == 0) { + SS7_DEBUG("Found new MTP1 Link: id=%d, name=%s\n", mtp1Link->id, mtp1Link->name); + sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP1); + } else { + SS7_DEBUG("Found an existing MTP1 Link: id=%d, name=%s (old name=%s)\n", + mtp1Link->id, + mtp1Link->name, + g_ftdm_sngss7_data.cfg.mtp1Link[i].name); + } + + /* copy over the values */ + strcpy((char *)g_ftdm_sngss7_data.cfg.mtp1Link[i].name, (char *)mtp1Link->name); + + g_ftdm_sngss7_data.cfg.mtp1Link[i].id = mtp1Link->id; + g_ftdm_sngss7_data.cfg.mtp1Link[i].span = mtp1Link->span; + g_ftdm_sngss7_data.cfg.mtp1Link[i].chan = mtp1Link->chan; + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_fill_in_mtp2_link(sng_mtp2_link_t *mtp2Link) +{ + int i = mtp2Link->id; + + /* check if this id value has been used already */ + if (g_ftdm_sngss7_data.cfg.mtp2Link[i].id == 0) { + SS7_DEBUG("Found new MTP2 Link: id=%d, name=%s\n", mtp2Link->id, mtp2Link->name); + sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2); + } else { + SS7_DEBUG("Found an existing MTP2 Link: id=%d, name=%s (old name=%s)\n", + mtp2Link->id, + mtp2Link->name, + g_ftdm_sngss7_data.cfg.mtp2Link[i].name); + } + + /* copy over the values */ + strcpy((char *)g_ftdm_sngss7_data.cfg.mtp2Link[i].name, (char *)mtp2Link->name); + + g_ftdm_sngss7_data.cfg.mtp2Link[i].id = mtp2Link->id; + g_ftdm_sngss7_data.cfg.mtp2Link[i].lssuLength = mtp2Link->lssuLength; + g_ftdm_sngss7_data.cfg.mtp2Link[i].errorType = mtp2Link->errorType; + g_ftdm_sngss7_data.cfg.mtp2Link[i].linkType = mtp2Link->linkType; + g_ftdm_sngss7_data.cfg.mtp2Link[i].mtp1Id = mtp2Link->mtp1Id; + g_ftdm_sngss7_data.cfg.mtp2Link[i].mtp1ProcId = mtp2Link->mtp1ProcId; + + if ( mtp2Link->t1 != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t1 = mtp2Link->t1; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t1 = 500; + } + + if ( mtp2Link->t2 != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t2 = mtp2Link->t2; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t2 = 250; + } + + if ( mtp2Link->t3 != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t3 = mtp2Link->t3; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t3 = 20; + } + + if ( mtp2Link->t4n != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t4n = mtp2Link->t4n; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t4n = 80; + } + + if ( mtp2Link->t4e != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t4e = mtp2Link->t4e; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t4e = 5; + } + + if ( mtp2Link->t5 != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t5 = mtp2Link->t5; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t5 = 1; + } + + if ( mtp2Link->t6 != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t6 = mtp2Link->t6; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t6 = 60; + } + + if ( mtp2Link->t7 != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t7 = mtp2Link->t7; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t7 = 40; + } + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_fill_in_mtp3_link(sng_mtp3_link_t *mtp3Link) +{ + int i = mtp3Link->id; + + /* check if this id value has been used already */ + if (g_ftdm_sngss7_data.cfg.mtp3Link[i].id == 0) { + SS7_DEBUG("Found new MTP3 Link: id=%d, name=%s\n", mtp3Link->id, mtp3Link->name); + sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3); + } else { + SS7_DEBUG("Found an existing MTP3 Link: id=%d, name=%s (old name=%s)\n", + mtp3Link->id, + mtp3Link->name, + g_ftdm_sngss7_data.cfg.mtp3Link[i].name); + } + + /* copy over the values */ + strcpy((char *)g_ftdm_sngss7_data.cfg.mtp3Link[i].name, (char *)mtp3Link->name); + + g_ftdm_sngss7_data.cfg.mtp3Link[i].id = mtp3Link->id; + g_ftdm_sngss7_data.cfg.mtp3Link[i].priority = mtp3Link->priority; + g_ftdm_sngss7_data.cfg.mtp3Link[i].linkType = mtp3Link->linkType; + g_ftdm_sngss7_data.cfg.mtp3Link[i].switchType = mtp3Link->switchType; + g_ftdm_sngss7_data.cfg.mtp3Link[i].apc = mtp3Link->apc; + g_ftdm_sngss7_data.cfg.mtp3Link[i].spc = mtp3Link->spc; /* unknown at this time */ + g_ftdm_sngss7_data.cfg.mtp3Link[i].ssf = mtp3Link->ssf; + g_ftdm_sngss7_data.cfg.mtp3Link[i].slc = mtp3Link->slc; + g_ftdm_sngss7_data.cfg.mtp3Link[i].linkSetId = mtp3Link->linkSetId; + g_ftdm_sngss7_data.cfg.mtp3Link[i].mtp2Id = mtp3Link->mtp2Id; + g_ftdm_sngss7_data.cfg.mtp3Link[i].mtp2ProcId = mtp3Link->mtp2ProcId; + + if (mtp3Link->t1 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t1 = mtp3Link->t1; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t1 = 8; + } + if (mtp3Link->t2 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t2 = mtp3Link->t2; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t2 = 14; + } + if (mtp3Link->t3 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t3 = mtp3Link->t3; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t3 = 8; + } + if (mtp3Link->t4 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t4 = mtp3Link->t4; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t4 = 8; + } + if (mtp3Link->t5 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t5 = mtp3Link->t5; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t5 = 8; + } + if (mtp3Link->t7 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t7 = mtp3Link->t7; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t7 = 15; + } + if (mtp3Link->t12 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t12 = mtp3Link->t12; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t12 = 15; + } + if (mtp3Link->t13 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t13 = mtp3Link->t13; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t13 = 15; + } + if (mtp3Link->t14 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t14 = mtp3Link->t14; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t14 = 30; + } + if (mtp3Link->t17 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t17 = mtp3Link->t17; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t17 = 15; + } + if (mtp3Link->t22 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t22 = mtp3Link->t22; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t22 = 1800; + } + if (mtp3Link->t23 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t23 = mtp3Link->t23; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t23 = 1800; + } + if (mtp3Link->t24 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t24 = mtp3Link->t24; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t24 = 5; + } + if (mtp3Link->t31 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t31 = mtp3Link->t31; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t31 = 50; + } + if (mtp3Link->t32 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t32 = mtp3Link->t32; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t32 = 120; + } + if (mtp3Link->t33 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t33 = mtp3Link->t33; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t33 = 3000; + } + if (mtp3Link->t34 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t34 = mtp3Link->t34; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t34 = 600; + } + if (mtp3Link->tbnd != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].tbnd = mtp3Link->tbnd; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].tbnd = 30000; + } + if (mtp3Link->tflc != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].tflc = mtp3Link->tflc; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].tflc = 300; + } + return FTDM_SUCCESS; +} /******************************************************************************/ static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet) @@ -1537,9 +2306,6 @@ static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet) g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id = mtpLinkSet->id; g_ftdm_sngss7_data.cfg.mtpLinkSet[i].apc = mtpLinkSet->apc; - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].linkType = mtpLinkSet->linkType; - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].switchType = mtpLinkSet->switchType; - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].ssf = mtpLinkSet->ssf; /* these values are filled in as we find routes and start allocating cmbLinkSetIds */ g_ftdm_sngss7_data.cfg.mtpLinkSet[i].minActive = mtpLinkSet->minActive; @@ -1550,28 +2316,25 @@ 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; - - /* go through all the existing routes and see if we find a match */ - i = 1; - while (g_ftdm_sngss7_data.cfg.mtpRoute[i].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpRoute[i].name, mtp3_route->name)) { - /* we have a match so break out of this loop */ - break; - } - /* move on to the next one */ - i++; - } + int i = mtp3_route->id; + /* check if this id value has been used already */ if (g_ftdm_sngss7_data.cfg.mtpRoute[i].id == 0) { - mtp3_route->id = i; - SS7_DEBUG("found new mtp3_route, id is = %d\n", mtp3_route->id); + SS7_DEBUG("Found new MTP3 Link: id=%d, name=%s\n", mtp3_route->id, mtp3_route->name); } else { - mtp3_route->id = i; - SS7_DEBUG("found existing mtp3_route, id is = %d\n", mtp3_route->id); + SS7_DEBUG("Found an existing MTP3 Link: id=%d, name=%s (old name=%s)\n", + mtp3_route->id, + mtp3_route->name, + g_ftdm_sngss7_data.cfg.mtpRoute[i].name); } - strncpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, (char *)mtp3_route->name, MAX_NAME_LEN-1); + /* fill in the cmbLinkSet in the linkset structure */ + int tmp = g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3_route->linkSetId].numLinks; + + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3_route->linkSetId].links[tmp] = mtp3_route->cmbLinkSetId; + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3_route->linkSetId].numLinks++; + + strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, (char *)mtp3_route->name); g_ftdm_sngss7_data.cfg.mtpRoute[i].id = mtp3_route->id; g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc = mtp3_route->dpc; @@ -1662,11 +2425,9 @@ static int ftmod_ss7_fill_in_nsap(sng_route_t *mtp3_route) if (g_ftdm_sngss7_data.cfg.nsap[i].id == 0) { g_ftdm_sngss7_data.cfg.nsap[i].id = i; - mtp3_route->nwId = i; SS7_DEBUG("found new mtp3_isup interface, id is = %d\n", g_ftdm_sngss7_data.cfg.nsap[i].id); } else { g_ftdm_sngss7_data.cfg.nsap[i].id = i; - mtp3_route->nwId = i; SS7_DEBUG("found existing mtp3_isup interface, id is = %d\n", g_ftdm_sngss7_data.cfg.nsap[i].id); } @@ -1683,26 +2444,17 @@ static int ftmod_ss7_fill_in_nsap(sng_route_t *mtp3_route) /******************************************************************************/ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup) { - int i; - - /* go through all the existing interfaces and see if we find a match */ - i = 1; - while (g_ftdm_sngss7_data.cfg.isupIntf[i].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.isupIntf[i].name, sng_isup->name)) { - - /* we have a match so break out of this loop */ - break; - } - /* move on to the next one */ - i++; - } + int i = sng_isup->id; + /* check if this id value has been used already */ if (g_ftdm_sngss7_data.cfg.isupIntf[i].id == 0) { - sng_isup->id = i; - SS7_DEBUG("found new isup interface, id is = %d\n", sng_isup->id); + SS7_DEBUG("Found new ISUP Interface: id=%d, name=%s\n", sng_isup->id, sng_isup->name); + sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP); } else { - sng_isup->id = i; - SS7_DEBUG("found existing isup interface, id is = %d\n", sng_isup->id); + SS7_DEBUG("Found an existing ISUP Interface: id=%d, name=%s (old name=%s)\n", + sng_isup->id, + sng_isup->name, + g_ftdm_sngss7_data.cfg.isupIntf[i].name); } strncpy((char *)g_ftdm_sngss7_data.cfg.isupIntf[i].name, (char *)sng_isup->name, MAX_NAME_LEN-1); @@ -1715,9 +2467,6 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup) g_ftdm_sngss7_data.cfg.isupIntf[i].switchType = sng_isup->switchType; g_ftdm_sngss7_data.cfg.isupIntf[i].ssf = sng_isup->ssf; g_ftdm_sngss7_data.cfg.isupIntf[i].isap = sng_isup->isap; - g_ftdm_sngss7_data.cfg.isupIntf[i].cld_nadi = sng_isup->cld_nadi; - g_ftdm_sngss7_data.cfg.isupIntf[i].clg_nadi = sng_isup->clg_nadi; - g_ftdm_sngss7_data.cfg.isupIntf[i].min_digits = sng_isup->min_digits; g_ftdm_sngss7_data.cfg.isupIntf[i].options = sng_isup->options; if (sng_isup->t4 != 0) { g_ftdm_sngss7_data.cfg.isupIntf[i].t4 = sng_isup->t4; @@ -1799,11 +2548,6 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup) } else { g_ftdm_sngss7_data.cfg.isupIntf[i].t32 = 30; } - if (sng_isup->t35 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t35 = sng_isup->t35; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t35 = 170; - } if (sng_isup->t37 != 0) { g_ftdm_sngss7_data.cfg.isupIntf[i].t37 = sng_isup->t37; } else { @@ -1857,10 +2601,10 @@ static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap) if (g_ftdm_sngss7_data.cfg.isap[i].id == 0) { sng_isap->id = i; - SS7_DEBUG("found new isup to cc interface, id is = %d\n", g_ftdm_sngss7_data.cfg.isap[i].id); + SS7_DEBUG("found new isup to cc interface, id is = %d\n", sng_isap->id); } else { sng_isap->id = i; - SS7_DEBUG("found existing isup to cc interface, id is = %d\n", g_ftdm_sngss7_data.cfg.isap[i].id); + SS7_DEBUG("found existing isup to cc interface, id is = %d\n", sng_isap->id); } g_ftdm_sngss7_data.cfg.isap[i].id = sng_isap->id; @@ -2013,226 +2757,213 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i } /******************************************************************************/ -static int ftmod_ss7_fill_in_circuits(sng_isupCkt_t *isupCkt) +static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan) { - sngss7_chan_data_t *ss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; sng_timeslot_t timeslot; - int count; - int i; + sngss7_chan_data_t *ss7_info = NULL; int x; + int count = 1; - count = 1; + while (ccSpan->ch_map[0] != '\0') { + /**************************************************************************/ - while (isupCkt->ch_map[0] != '\0') { - - /* pull out the next timeslot */ - if (ftmod_ss7_next_timeslot(isupCkt->ch_map, ×lot)) { + /* pull out the next timeslot */ + if (ftmod_ss7_next_timeslot(ccSpan->ch_map, ×lot)) { SS7_ERROR("Failed to parse the channel map!\n"); return FTDM_FAIL; } - if ((timeslot.siglink) || (timeslot.gap)) { - /* try to find the channel in the circuits structure*/ - x = 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if ((g_ftdm_sngss7_data.cfg.isupCkt[x].chan == count) && - (g_ftdm_sngss7_data.cfg.isupCkt[x].span == isupCkt->span->channels[1]->physical_span_id)) { + /* find the spot in master array for this circuit */ + x = (ccSpan->procId * 1000) + count; - SS7_DEVEL_DEBUG("Circuit for span=%d, chan=%d is already exists...id=%d\n", - isupCkt->span->channels[1]->physical_span_id, - count, - x); + /* 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); + } - /* we have a match so this circuit already exists in the structure */ - break; - } - /* move to the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ + /* prepare the global info sturcture */ + ss7_info = ftdm_calloc(1, sizeof(sngss7_chan_data_t)); + ss7_info->ftdmchan = NULL; + ss7_info->circuit = &g_ftdm_sngss7_data.cfg.isupCkt[x]; - /* check why we exited the while loop */ - if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) { - SS7_DEVEL_DEBUG("Circuit for span=%d, chan=%d is new...id=%d\n", - isupCkt->span->channels[1]->physical_span_id, - count, - x); + g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info; - /* prepare the global info sturcture */ - ss7_info = ftdm_calloc(1, sizeof(sngss7_chan_data_t)); - ss7_info->ftdmchan = NULL; - ss7_info->circuit = &g_ftdm_sngss7_data.cfg.isupCkt[x]; + /* fill in the rest of the global structure */ + g_ftdm_sngss7_data.cfg.isupCkt[x].procId = ccSpan->procId; + g_ftdm_sngss7_data.cfg.isupCkt[x].id = x; + g_ftdm_sngss7_data.cfg.isupCkt[x].ccSpanId = ccSpan->id; + g_ftdm_sngss7_data.cfg.isupCkt[x].span = 0; + g_ftdm_sngss7_data.cfg.isupCkt[x].chan = count; - /* circuit is new so fill in the needed information */ - g_ftdm_sngss7_data.cfg.isupCkt[x].id = x; - g_ftdm_sngss7_data.cfg.isupCkt[x].span = isupCkt->span->channels[1]->physical_span_id; - g_ftdm_sngss7_data.cfg.isupCkt[x].chan = count; - if (timeslot.siglink) { - g_ftdm_sngss7_data.cfg.isupCkt[x].type = SIG; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].type = HOLE; - } + if (timeslot.siglink) { + g_ftdm_sngss7_data.cfg.isupCkt[x].type = SIG; + } else if (timeslot.gap) { + g_ftdm_sngss7_data.cfg.isupCkt[x].type = HOLE; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].type = VOICE; + + /* throw the flag to indicate that we need to start call control */ + sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC); + } - if (timeslot.channel) { - g_ftdm_sngss7_data.cfg.isupCkt[x].cic = isupCkt->cicbase; - isupCkt->cicbase++; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].cic = 0; - } - g_ftdm_sngss7_data.cfg.isupCkt[x].infId = isupCkt->isupInf; - g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = isupCkt->typeCntrl; - g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = g_ftdm_sngss7_data.cfg.isupIntf[isupCkt->isupInf].ssf; - g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info; + if (timeslot.channel) { + g_ftdm_sngss7_data.cfg.isupCkt[x].cic = ccSpan->cicbase; + ccSpan->cicbase++; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].cic = 0; + } - } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) */ + g_ftdm_sngss7_data.cfg.isupCkt[x].infId = ccSpan->isupInf; + g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = ccSpan->typeCntrl; + g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = ccSpan->ssf; + g_ftdm_sngss7_data.cfg.isupCkt[x].cld_nadi = ccSpan->cld_nadi; + g_ftdm_sngss7_data.cfg.isupCkt[x].clg_nadi = ccSpan->clg_nadi; + g_ftdm_sngss7_data.cfg.isupCkt[x].options = ccSpan->options; + g_ftdm_sngss7_data.cfg.isupCkt[x].switchType = ccSpan->switchType; + g_ftdm_sngss7_data.cfg.isupCkt[x].min_digits = ccSpan->min_digits; - /* increment the span channel count */ - count++; + if (ccSpan->t3 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = ccSpan->t3; + } + if (ccSpan->t12 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = 300; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = ccSpan->t12; + } + if (ccSpan->t13 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = 3000; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = ccSpan->t13; + } + if (ccSpan->t14 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = 300; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = ccSpan->t14; + } + if (ccSpan->t15 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = 3000; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = ccSpan->t15; + } + if (ccSpan->t16 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = 300; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = ccSpan->t16; + } + if (ccSpan->t17 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = 3000; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = ccSpan->t17; + } + if (ccSpan->t35 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = 170; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = ccSpan->t35; + } + if (ccSpan->tval == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].tval = ccSpan->tval; + } - } else { /* if ((timeslot.siglink) || (timeslot.gap)) */ - /* find the ftdm the channel structure for this channel*/ - i = 1; - while (isupCkt->span->channels[i] != NULL) { - if (isupCkt->span->channels[i]->physical_chan_id == timeslot.channel) { - break; - } - i++; - } /* while (span->channels[i] != NULL) */ + SS7_INFO("Added procId=%d, spanId = %d, chan = %d, cic = %d, ISUP cirId = %d\n", + g_ftdm_sngss7_data.cfg.isupCkt[x].procId, + g_ftdm_sngss7_data.cfg.isupCkt[x].ccSpanId, + g_ftdm_sngss7_data.cfg.isupCkt[x].chan, + g_ftdm_sngss7_data.cfg.isupCkt[x].cic, + g_ftdm_sngss7_data.cfg.isupCkt[x].id); - if (isupCkt->span->channels[i] == NULL) { - /* we weren't able to find the channel in the ftdm channels */ - SS7_ERROR("Unable to find the requested channel %d in the FreeTDM channels!\n", timeslot.channel); - return FTDM_FAIL; - } else { - ftdmchan = isupCkt->span->channels[i]; + /* increment the span channel count */ + count++; + + /**************************************************************************/ + } /* while (ccSpan->ch_map[0] != '\0') */ + + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_fill_in_circuits(sng_span_t *sngSpan) +{ + ftdm_channel_t *ftdmchan = NULL; + ftdm_span_t *ftdmspan = sngSpan->span; + sng_isup_ckt_t *isupCkt = NULL; + sngss7_chan_data_t *ss7_info = NULL; + int flag; + int i; + int x; + + /* go through all the channels on ftdm span */ + for (i = 1; i < (ftdmspan->chan_count+1); i++) { + /**************************************************************************/ + + /* extract the ftdmchan pointer */ + ftdmchan = ftdmspan->channels[i]; + + /* find the equivalent channel in the global structure */ + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; + flag = 0; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + /**********************************************************************/ + /* pull out the circuit to make it easier to work with */ + isupCkt = &g_ftdm_sngss7_data.cfg.isupCkt[x]; + + /* if the ccSpanId's match fill in the span value...this is for sigs + * because they will never have a channel that matches since they + * have a ftdmchan at this time */ + if (sngSpan->ccSpanId == isupCkt->ccSpanId) { + isupCkt->span = ftdmchan->physical_span_id; } - /* try to find a match for the physical span and chan */ - x = 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if ((g_ftdm_sngss7_data.cfg.isupCkt[x].chan == ftdmchan->physical_chan_id) && - (g_ftdm_sngss7_data.cfg.isupCkt[x].span == ftdmchan->physical_span_id)) { + /* check if the ccSpanId matches and the physical channel # match */ + if ((sngSpan->ccSpanId == isupCkt->ccSpanId) && + (ftdmchan->physical_chan_id == isupCkt->chan)) { - /* we have a match so this circuit already exists in the structure */ - break; - } - /* move to the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ + /* we've found the channel in the ckt structure...raise the flag */ + flag = 1; - /* check why we exited the while loop */ - if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) { - SS7_DEVEL_DEBUG("Circuit for span=%d, chan=%d is new...id=%d\n", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id, - x); + /* now get out of the loop */ + break; + } - /* prepare the global info sturcture */ - ss7_info = ftdm_calloc(1, sizeof(sngss7_chan_data_t)); - ss7_info->ftdmchan = ftdmchan; - ss7_info->circuit = &g_ftdm_sngss7_data.cfg.isupCkt[x]; - ftdmchan->call_data = ss7_info; + /* move to the next ckt */ + x++; - /* prepare the timer structures */ - ss7_info->t35.sched = ((sngss7_span_data_t *)isupCkt->span->signal_data)->sched; - ss7_info->t35.counter = 1; - ss7_info->t35.beat = g_ftdm_sngss7_data.cfg.isupIntf[isupCkt->isupInf].t35*100; /* beat is in ms, t35 is in 100ms */ - ss7_info->t35.callback = handle_isup_t35; - ss7_info->t35.sngss7_info = ss7_info; + /* check if we are outside of the range of possible indexes */ + if (x == ((g_ftdm_sngss7_data.cfg.procId + 1) * 1000)) { + break; + } + /**********************************************************************/ + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ - /* circuit is new so fill in the needed information */ - g_ftdm_sngss7_data.cfg.isupCkt[x].id = x; - g_ftdm_sngss7_data.cfg.isupCkt[x].span = ftdmchan->physical_span_id; - g_ftdm_sngss7_data.cfg.isupCkt[x].chan = ftdmchan->physical_chan_id; - g_ftdm_sngss7_data.cfg.isupCkt[x].type = VOICE; - g_ftdm_sngss7_data.cfg.isupCkt[x].cic = isupCkt->cicbase; - g_ftdm_sngss7_data.cfg.isupCkt[x].infId = isupCkt->isupInf; - g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = isupCkt->typeCntrl; - if (isupCkt->t3 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = isupCkt->t3; - } - if (isupCkt->t12 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = 300; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = isupCkt->t12; - } - if (isupCkt->t13 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = 3000; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = isupCkt->t13; - } - if (isupCkt->t14 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = 300; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = isupCkt->t14; - } - if (isupCkt->t15 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = 3000; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = isupCkt->t15; - } - if (isupCkt->t16 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = 300; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = isupCkt->t16; - } - if (isupCkt->t17 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = 3000; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = isupCkt->t17; - } - if (isupCkt->tval == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].tval = isupCkt->tval; - } - g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info; - g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = g_ftdm_sngss7_data.cfg.isupIntf[isupCkt->isupInf].ssf; - - /* increment the cicbase */ - isupCkt->cicbase++; - } else { /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) */ - SS7_DEBUG("Circuit for span=%d, chan=%d is new...id=%d\n", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id, - x); - - /* for now make sure ss7_info is set to null */ - ss7_info = NULL; - - /* KONRAD FIX ME -> confirm that it is the same circuit */ - } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) */ - - /* increment the span channel count */ - count++; - } /* if ((timeslot.siglink) || (timeslot.gap)) */ - - if (ss7_info == NULL) { - SS7_ERROR("KONRAD -> circuit was not configured !\n"); + /* check we found the ckt or not */ + if (!flag) { + SS7_ERROR_CHAN(ftdmchan, "Failed to find this channel in the global ckts!%s\n",""); return FTDM_FAIL; } - if (ss7_info->ftdmchan == NULL) { - SS7_INFO("Added span = %d, chan = %d, cic = %d, FTDM chan = %d, ISUP cirId = %d\n", - g_ftdm_sngss7_data.cfg.isupCkt[x].span, - g_ftdm_sngss7_data.cfg.isupCkt[x].chan, - g_ftdm_sngss7_data.cfg.isupCkt[x].cic, - 0, - g_ftdm_sngss7_data.cfg.isupCkt[x].id); - } else { - SS7_INFO("Added span = %d, chan = %d, cic = %d, FTDM chan = %d, ISUP cirId = %d\n", - g_ftdm_sngss7_data.cfg.isupCkt[x].span, - g_ftdm_sngss7_data.cfg.isupCkt[x].chan, - g_ftdm_sngss7_data.cfg.isupCkt[x].cic, - ss7_info->ftdmchan->chan_id, - g_ftdm_sngss7_data.cfg.isupCkt[x].id); - } + /* fill in the rest of the global sngss7_chan_data_t structure */ + ss7_info = (sngss7_chan_data_t *)isupCkt->obj; + ss7_info->ftdmchan = ftdmchan; - } /* while (ch_map[0] != '\0') */ + /* attach the sngss7_chan_data_t to the freetdm channel structure */ + ftdmchan->call_data = ss7_info; - return 0; + /* prepare the timer structures */ + ss7_info->t35.sched = ((sngss7_span_data_t *)(ftdmspan->signal_data))->sched; + ss7_info->t35.counter = 1; + ss7_info->t35.beat = (isupCkt->t35) * 100; /* beat is in ms, t35 is in 100ms */ + ss7_info->t35.callback = handle_isup_t35; + ss7_info->t35.sngss7_info = ss7_info; + + + /**************************************************************************/ + } /* for (i == 1; i < ftdmspan->chan_count; i++) */ + + return FTDM_SUCCESS; } /******************************************************************************/ From a382990d9f23096d04812cea6d66f6c3f3994e89 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Fri, 21 Jan 2011 12:04:33 -0500 Subject: [PATCH 092/245] chlog: freetdm: ss7 - bug fix: a route now supports multiple linksets --- libs/freetdm/mod_freetdm/mod_freetdm.c | 2 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 51 +++++++++++++++---- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index d972cd7406..92cf9e54b9 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2462,7 +2462,7 @@ static ftdm_conf_node_t *get_ss7_config_node(switch_xml_t cfg, const char *confn } /* add mtp routes */ - if (add_config_list_nodes(isup, rootnode, "mtp_routes", "mtp_route", NULL, NULL)) { + if (add_config_list_nodes(isup, rootnode, "mtp_routes", "mtp_route", "linksets", "linkset")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp_routes for sng_isup config %s\n", confname); ftdm_conf_node_destroy(rootnode); return NULL; 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 277951c5d1..93f2678d08 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 @@ -1269,6 +1269,10 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) int num_parms = mtp_route->n_parameters; int i; + ftdm_conf_node_t *linkset; + int ls_id; + int numLinks; + /* initalize the mtpRoute structure */ memset(&mtpRoute, 0x0, sizeof(mtpRoute)); @@ -1299,11 +1303,6 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) mtpRoute.dpc = atoi(parm->val); SS7_DEBUG("Found an mtpRoute dpc = %d\n", mtpRoute.dpc); /**********************************************************************/ - } else if (!strcasecmp(parm->var, "linksetId")) { - /**********************************************************************/ - mtpRoute.linkSetId = atoi(parm->val); - SS7_DEBUG("Found an mtpRoute linkset = %s\n", parm->val); - /**********************************************************************/ } else if (!strcasecmp(parm->var, "isSTP")) { /**********************************************************************/ if (!strcasecmp(parm->val, "no")) { @@ -1383,15 +1382,47 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) parm = parm + 1; } - /* pull up the linktype, switchtype, and SSF from the linkset */ - mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLinkSet[mtpRoute.linkSetId].linkType; - mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLinkSet[mtpRoute.linkSetId].switchType; - mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLinkSet[mtpRoute.linkSetId].ssf; - /* fill in the rest of the values in the mtpRoute struct */ mtpRoute.nwId = mtpRoute.id; mtpRoute.cmbLinkSetId = mtpRoute.id; + /* parse in the list of linksets this route is reachable by */ + linkset = mtp_route->child->child; + + while (linkset != NULL) { + /**************************************************************************/ + /* extract the linkset Id */ + ls_id = 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); + } else { + SS7_ERROR("Found mtpRoute linkset id = %d that is invalid\n",ls_id); + 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; + + /* extract the number of cmbLinkSetId aleady on this linkset */ + numLinks = g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].numLinks; + + /* add this routes cmbLinkSetId to the list */ + g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].links[numLinks] = mtpRoute.cmbLinkSetId; + + /* increment the number of cmbLinkSets on this linkset */ + g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].numLinks++; + +move_along: + /* move to the next linkset element */ + linkset = linkset->next; + + /**************************************************************************/ + } /* while (linkset != null) */ + + ftmod_ss7_fill_in_mtp3_route(&mtpRoute); ftmod_ss7_fill_in_nsap(&mtpRoute); From 1932b3fe3bc8de85098eaf9b810da9d3b027d865 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Sat, 29 Jan 2011 19:34:39 -0500 Subject: [PATCH 093/245] chlog: freetdm: ss7 - update for new licensing, will not work with old licenses contact Sangoma (techdesk@sangoma.com) to obtain a new license --- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c | 3 +-- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c | 4 ++-- 2 files changed, 3 insertions(+), 4 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 42b95a1863..15fc1ef5db 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 @@ -80,8 +80,7 @@ int ft_to_sngss7_cfg_all(void) /* start of by checking if the license and sig file are valid */ if (sng_validate_license(g_ftdm_sngss7_data.cfg.license, - g_ftdm_sngss7_data.cfg.signature, - g_ftdm_sngss7_data.cfg.spc)) { + g_ftdm_sngss7_data.cfg.signature)) { SS7_CRITICAL("License verification failed..ending!\n"); return 1; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c index 1dfcab4555..f4143fc864 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c @@ -79,8 +79,8 @@ void handle_sng_log(uint8_t level, char *fmt,...) ftdm_log(FTDM_LOG_INFO, "sng_ss7->%s", data); break; /**************************************************************************/ - case SNG_LOGLEVEL_STATS: - ftdm_log(FTDM_LOG_INFO, "sng_ss7->%s", data); + case SNG_LOGLEVEL_NOTICE: + ftdm_log(FTDM_LOG_NOTICE, "sng_ss7->%s", data); break; /**************************************************************************/ case SNG_LOGLEVEL_ERROR: From 7c3ee98d3375dcab851ed8f4eb4b3d6a991295b1 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Sat, 29 Jan 2011 19:57:12 -0500 Subject: [PATCH 094/245] freetdm: ss7 - bug fix: fix for bug introduced by merge of RELAY work --- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c | 8 +++----- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 5 ----- 2 files changed, 3 insertions(+), 10 deletions(-) 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 c971179f1a..adee000abb 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 @@ -495,8 +495,6 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /**************************************************************************/ case FTDM_CHANNEL_STATE_COLLECT: /* IAM received but wating on digits */ - isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); break; @@ -516,8 +514,8 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /*now go to the RING state */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING); - } else if (i >= isup_intf->min_digits) { - SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, isup_intf->min_digits); + } else if (i >= sngss7_info->circuit->min_digits) { + SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, sngss7_info->circuit->min_digits); /*now go to the RING state */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING); @@ -527,7 +525,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) { SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n", i, - isup_intf->min_digits, + sngss7_info->circuit->min_digits, ftdmchan->caller_data.dnis.digits); /* start ISUP t35 */ 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 93f2678d08..d2fa973393 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 @@ -1509,11 +1509,6 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) SS7_DEBUG("Found an isup mptRouteId = %d\n", sng_isup.mtpRouteId); /**********************************************************************/ - } else if (!strcasecmp(parm->var, "min_digits")) { - sng_isup.min_digits = atoi(parm->val); - - SS7_DEBUG("\tFound min_digits = %d\n", sng_isup.min_digits); - /**********************************************************************/ } else if (!strcasecmp(parm->var, "ssf")) { /**********************************************************************/ ret = find_ssf_type_in_map(parm->val); From c8f5c66c3520ecda8f8dbc07dc01f1d4035058e4 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Mon, 31 Jan 2011 15:41:58 +0100 Subject: [PATCH 095/245] 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 096/245] 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 c339d6f2e1e8111da4150974ca324d3c3b9393c0 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 31 Jan 2011 15:50:51 -0500 Subject: [PATCH 097/245] test --- libs/freetdm/src/ftdm_io.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 529a30f120..3ac9f4cb92 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -37,6 +37,10 @@ * */ +#ifdef MOYTEST +crap +#endif + #define _GNU_SOURCE #include "private/ftdm_core.h" #include From 766f2d61651f161b074fad2f987b4f10532a9a7a Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 31 Jan 2011 18:24:08 +0000 Subject: [PATCH 098/245] 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 099/245] 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 be370d45ebf5bc7fc329ef0b1abd48c2e38c8e9b Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 31 Jan 2011 15:55:50 -0500 Subject: [PATCH 100/245] test --- libs/freetdm/src/ftdm_io.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 529a30f120..0f92f59053 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -37,6 +37,9 @@ * */ +#ifdef MOYTEST +crap +#endif #define _GNU_SOURCE #include "private/ftdm_core.h" #include From b6afdadc82a3d9c95ff61bad4a7f869d220cd0f9 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 31 Jan 2011 15:58:07 -0500 Subject: [PATCH 101/245] no test --- libs/freetdm/src/ftdm_io.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 3ac9f4cb92..529a30f120 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -37,10 +37,6 @@ * */ -#ifdef MOYTEST -crap -#endif - #define _GNU_SOURCE #include "private/ftdm_core.h" #include From 9470e70057c549598d6d5e768d6cb08a2ba82104 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 31 Jan 2011 17:58:15 -0600 Subject: [PATCH 102/245] 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 103/245] 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 104/245] 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 105/245] 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 106/245] 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 107/245] 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 108/245] 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 109/245] 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 110/245] 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 111/245] 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 112/245] 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 113/245] 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 114/245] 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 115/245] 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 116/245] 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 117/245] 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 118/245] 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 119/245] 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 120/245] 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 121/245] 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 122/245] 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 123/245] 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 124/245] 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 125/245] 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 126/245] 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 127/245] 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 128/245] 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 129/245] 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 130/245] 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 131/245] 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 132/245] 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 133/245] 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 134/245] 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 135/245] 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 136/245] 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 137/245] 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 138/245] 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 142/245] 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 143/245] 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 144/245] 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 145/245] 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 146/245] 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 147/245] 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 148/245] 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 149/245] 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 150/245] 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 151/245] 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 152/245] 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 153/245] 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 154/245] 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 155/245] 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 156/245] 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 157/245] 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 158/245] 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 159/245] 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 160/245] 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); From 428ef9666734805fa7f97f8291c06252a4f1b798 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Mon, 7 Feb 2011 17:29:26 -0500 Subject: [PATCH 161/245] freetdm: allow reception of FACILITY msg in any channel state when transparent facility is enabled --- .../ftmod_sangoma_isdn_stack_hndl.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) 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 578677a39f..bcc7d938b7 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 @@ -801,6 +801,23 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing FACILITY IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); + if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) { + /* If Facility decoding is disabled, we do not care about current call state, just pass event up to user */ + ftdm_sigmsg_t sigev; + if (facEvnt->facElmt.facStr.pres) { + get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len-2); + } + memset(&sigev, 0, sizeof(sigev)); + sigev.chan_id = ftdmchan->chan_id; + sigev.span_id = ftdmchan->span_id; + sigev.channel = ftdmchan; + + sigev.event_id = FTDM_SIGEVENT_FACILITY; + ftdm_span_send_signal(ftdmchan->span, &sigev); + ISDN_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_GET_CALLERID: /* Update the caller ID Name */ From a93623618b83fb08f2a0a728800f431856b29f92 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 7 Feb 2011 16:33:36 -0600 Subject: [PATCH 162/245] 3 regresions from this now, rolling it back --- src/mod/applications/mod_voicemail/mod_voicemail.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index bea82142b6..80b011e189 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1277,13 +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, myid, domain_name, myfolder); - - + 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;", + myid, domain_name, myfolder); vm_execute_sql_callback(profile, profile->mutex, sql, message_count_callback, &cbt); From 0e841a5f14810514ee60562481c405d7fb560e72 Mon Sep 17 00:00:00 2001 From: Mike Jerris Date: Tue, 8 Feb 2011 10:36:12 -0600 Subject: [PATCH 163/245] FS-3040/FS-1742: use 1 sql query for message count in a way that is portable and doesn't segfault --- .../mod_voicemail/mod_voicemail.c | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 80b011e189..894e49a511 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1011,6 +1011,11 @@ typedef struct msg_cnt_callback msg_cnt_callback_t; static int message_count_callback(void *pArg, int argc, char **argv, char **columnNames) { msg_cnt_callback_t *cbt = (msg_cnt_callback_t *) pArg; + + if (argc < 3 || zstr(argv[0]) || zstr(argv[1]) || zstr(argv[2])) { + return -1; + } + if (atoi(argv[0]) == 1) { /* UnRead */ if (!strcasecmp(argv[1], "A_URGENT")) { /* Urgent */ cbt->total_new_urgent_messages = atoi(argv[2]); @@ -1263,7 +1268,7 @@ static void message_count(vm_profile_t *profile, const char *id_in, const char * { char msg_count[80] = ""; msg_cnt_callback_t cbt = { 0 }; - char sql[256]; + char *sql; char *myid = NULL; @@ -1277,11 +1282,20 @@ 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;", - myid, domain_name, myfolder); + sql = switch_mprintf( + "select 1, read_flags, count(read_epoch) from voicemail_msgs where " + "username='%q' and domain='%q' and in_folder='%q' and read_epoch=0 " + "group by read_flags " + "union " + "select 0, read_flags, count(read_epoch) from voicemail_msgs where " + "username='%q' and domain='%q' and in_folder='%q' 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); + free(sql); *total_new_messages = cbt.total_new_messages + cbt.total_new_urgent_messages; *total_new_urgent_messages = cbt.total_new_urgent_messages; From df4a18dcba1ad6a3ac20f67982642e8fe0e35471 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 8 Feb 2011 11:52:40 -0500 Subject: [PATCH 164/245] Fixes to support QSIG over T1 --- .../ftmod_sangoma_isdn_cfg.c | 2 + .../ftmod_sangoma_isdn_stack_cfg.c | 38 +++++++++++-------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index bd5b13bfec..9fe28190e1 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -84,6 +84,8 @@ static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span signal_data->switchtype = SNGISDN_SWITCH_4ESS; } else if (!strcasecmp(switch_name, "dms100")) { signal_data->switchtype = SNGISDN_SWITCH_DMS100; + } else if (!strcasecmp(switch_name, "qsig")) { + signal_data->switchtype = SNGISDN_SWITCH_QSIG; } else { ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported switchtype %s for trunktype:%s\n", span->name, switch_name, ftdm_trunk_type2str(span->trunk_type)); return FTDM_FAIL; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c index a52a624dd0..1bd2753e81 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c @@ -667,25 +667,33 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span) cfg.t.cfg.s.inDLSAP.maxBSrvCnt = 2; cfg.t.cfg.s.inDLSAP.maxDSrvCnt = 2; #endif /* ISDN_SRV */ - - if (signal_data->signalling == SNGISDN_SIGNALING_NET) { - cfg.t.cfg.s.inDLSAP.ackOpt = TRUE; - cfg.t.cfg.s.inDLSAP.intType = NETWORK; - cfg.t.cfg.s.inDLSAP.clrGlr = FALSE; /* in case of glare, do not clear local call */ - cfg.t.cfg.s.inDLSAP.statEnqOpt = TRUE; - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN || - signal_data->switchtype == SNGISDN_SWITCH_INSNET) { - cfg.t.cfg.s.inDLSAP.rstOpt = FALSE; - } else { - cfg.t.cfg.s.inDLSAP.rstOpt = TRUE; - } - } else { - cfg.t.cfg.s.inDLSAP.ackOpt = FALSE; - cfg.t.cfg.s.inDLSAP.intType = USER; + if (signal_data->switchtype == SNGISDN_SWITCH_QSIG) { + cfg.t.cfg.s.inDLSAP.ackOpt = TRUE; + cfg.t.cfg.s.inDLSAP.intType = SYM_USER; cfg.t.cfg.s.inDLSAP.clrGlr = TRUE; /* in case of glare, clear local call */ cfg.t.cfg.s.inDLSAP.statEnqOpt = FALSE; cfg.t.cfg.s.inDLSAP.rstOpt = FALSE; + } else { + if (signal_data->signalling == SNGISDN_SIGNALING_NET) { + cfg.t.cfg.s.inDLSAP.ackOpt = TRUE; + cfg.t.cfg.s.inDLSAP.intType = NETWORK; + cfg.t.cfg.s.inDLSAP.clrGlr = FALSE; /* in case of glare, do not clear local call */ + cfg.t.cfg.s.inDLSAP.statEnqOpt = TRUE; + + if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN || + signal_data->switchtype == SNGISDN_SWITCH_INSNET) { + cfg.t.cfg.s.inDLSAP.rstOpt = FALSE; + } else { + cfg.t.cfg.s.inDLSAP.rstOpt = TRUE; + } + } else { + cfg.t.cfg.s.inDLSAP.ackOpt = FALSE; + cfg.t.cfg.s.inDLSAP.intType = USER; + cfg.t.cfg.s.inDLSAP.clrGlr = TRUE; /* in case of glare, clear local call */ + cfg.t.cfg.s.inDLSAP.statEnqOpt = FALSE; + cfg.t.cfg.s.inDLSAP.rstOpt = FALSE; + } } /* Override the restart options if user selected that option */ From 93501b288b34a7d4f5287f7bc2b498a2321d73c5 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 8 Feb 2011 11:52:40 -0500 Subject: [PATCH 165/245] Fixes to support QSIG over T1 --- .../ftmod_sangoma_isdn_cfg.c | 2 + .../ftmod_sangoma_isdn_stack_cfg.c | 38 +++++++++++-------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index bd5b13bfec..9fe28190e1 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -84,6 +84,8 @@ static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span signal_data->switchtype = SNGISDN_SWITCH_4ESS; } else if (!strcasecmp(switch_name, "dms100")) { signal_data->switchtype = SNGISDN_SWITCH_DMS100; + } else if (!strcasecmp(switch_name, "qsig")) { + signal_data->switchtype = SNGISDN_SWITCH_QSIG; } else { ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported switchtype %s for trunktype:%s\n", span->name, switch_name, ftdm_trunk_type2str(span->trunk_type)); return FTDM_FAIL; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c index a52a624dd0..1bd2753e81 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c @@ -667,25 +667,33 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span) cfg.t.cfg.s.inDLSAP.maxBSrvCnt = 2; cfg.t.cfg.s.inDLSAP.maxDSrvCnt = 2; #endif /* ISDN_SRV */ - - if (signal_data->signalling == SNGISDN_SIGNALING_NET) { - cfg.t.cfg.s.inDLSAP.ackOpt = TRUE; - cfg.t.cfg.s.inDLSAP.intType = NETWORK; - cfg.t.cfg.s.inDLSAP.clrGlr = FALSE; /* in case of glare, do not clear local call */ - cfg.t.cfg.s.inDLSAP.statEnqOpt = TRUE; - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN || - signal_data->switchtype == SNGISDN_SWITCH_INSNET) { - cfg.t.cfg.s.inDLSAP.rstOpt = FALSE; - } else { - cfg.t.cfg.s.inDLSAP.rstOpt = TRUE; - } - } else { - cfg.t.cfg.s.inDLSAP.ackOpt = FALSE; - cfg.t.cfg.s.inDLSAP.intType = USER; + if (signal_data->switchtype == SNGISDN_SWITCH_QSIG) { + cfg.t.cfg.s.inDLSAP.ackOpt = TRUE; + cfg.t.cfg.s.inDLSAP.intType = SYM_USER; cfg.t.cfg.s.inDLSAP.clrGlr = TRUE; /* in case of glare, clear local call */ cfg.t.cfg.s.inDLSAP.statEnqOpt = FALSE; cfg.t.cfg.s.inDLSAP.rstOpt = FALSE; + } else { + if (signal_data->signalling == SNGISDN_SIGNALING_NET) { + cfg.t.cfg.s.inDLSAP.ackOpt = TRUE; + cfg.t.cfg.s.inDLSAP.intType = NETWORK; + cfg.t.cfg.s.inDLSAP.clrGlr = FALSE; /* in case of glare, do not clear local call */ + cfg.t.cfg.s.inDLSAP.statEnqOpt = TRUE; + + if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN || + signal_data->switchtype == SNGISDN_SWITCH_INSNET) { + cfg.t.cfg.s.inDLSAP.rstOpt = FALSE; + } else { + cfg.t.cfg.s.inDLSAP.rstOpt = TRUE; + } + } else { + cfg.t.cfg.s.inDLSAP.ackOpt = FALSE; + cfg.t.cfg.s.inDLSAP.intType = USER; + cfg.t.cfg.s.inDLSAP.clrGlr = TRUE; /* in case of glare, clear local call */ + cfg.t.cfg.s.inDLSAP.statEnqOpt = FALSE; + cfg.t.cfg.s.inDLSAP.rstOpt = FALSE; + } } /* Override the restart options if user selected that option */ From 330d741853f4f7c548b61dbcb717266a2bf24107 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 8 Feb 2011 11:23:59 -0600 Subject: [PATCH 166/245] reset signal_bond variable back to its original value on failed dial in att_xfer --- src/mod/applications/mod_dptools/mod_dptools.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index f7bf86b4c7..9a1258a5b6 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -1864,6 +1864,7 @@ SWITCH_STANDARD_APP(att_xfer_function) if (switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL) != SWITCH_STATUS_SUCCESS || !peer_session) { + switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond); goto end; } @@ -1878,6 +1879,7 @@ SWITCH_STANDARD_APP(att_xfer_function) if (zstr(bond) && switch_channel_down(peer_channel)) { switch_core_session_rwunlock(peer_session); + switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond); goto end; } From 2401fec54b48d8dfb1ec5a2f33a092dac076c0f3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 8 Feb 2011 13:01:42 -0600 Subject: [PATCH 167/245] minor regression from 4ae8282e6c6df0e296113e9b4b4a1383e1af8ad7 (sofia_contact with no args from cli caused seg) --- src/mod/endpoints/mod_sofia/mod_sofia.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index c6832030b4..2a2ec63221 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -3458,7 +3458,7 @@ SWITCH_STANDARD_API(sofia_contact_function) { char *data; char *user = NULL; - char *domain = NULL; + char *domain = NULL, *dup_domain = NULL; char *concat = NULL; char *profile_name = NULL; char *p; @@ -3501,7 +3501,8 @@ SWITCH_STANDARD_API(sofia_contact_function) } if (zstr(domain)) { - domain = switch_core_get_variable_pdup("domain", switch_core_session_get_pool(session)); + dup_domain = switch_core_get_variable_dup("domain"); + domain = dup_domain; } if (!user) goto end; @@ -3567,6 +3568,7 @@ SWITCH_STANDARD_API(sofia_contact_function) switch_safe_free(mystream.data); switch_safe_free(data); + switch_safe_free(dup_domain); return SWITCH_STATUS_SUCCESS; } From 2adfc50af7958eea12c15e023bcf80b18a4c73f9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 9 Feb 2011 09:32:17 -0600 Subject: [PATCH 168/245] take out default it seems to suck on 32 bit --- conf/autoload_configs/switch.conf.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/autoload_configs/switch.conf.xml b/conf/autoload_configs/switch.conf.xml index 32cb76f08a..44893b931a 100644 --- a/conf/autoload_configs/switch.conf.xml +++ b/conf/autoload_configs/switch.conf.xml @@ -25,7 +25,7 @@ - + - + From c81bf01fc977fd1a12b521cf29abb5b466f1fda2 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 14 Feb 2011 14:44:38 -0500 Subject: [PATCH 192/245] freetdm: ftmod_r2 - set MF dump directory default to logdir --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index d86fb43195..83705d9af8 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -725,9 +725,10 @@ static void dump_mf(openr2_chan_t *r2chan) if (r2data->mf_dump_size) { char *logname = R2CALL(ftdmchan)->logname; - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO output in prefix %s\n", logname); - snprintf(dfile, sizeof(dfile), logname ? "%s.s%dc%d.input.alaw" : "%s/s%dc%d.input.alaw", - logname ? logname : r2data->logdir, ftdmchan->span_id, ftdmchan->chan_id); + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO output in prefix %s\n", !ftdm_strlen_zero(logname) + ? logname : r2data->logdir); + snprintf(dfile, sizeof(dfile), !ftdm_strlen_zero(logname) ? "%s.s%dc%d.input.alaw" : "%s/s%dc%d.input.alaw", + !ftdm_strlen_zero(logname) ? logname : r2data->logdir, ftdmchan->span_id, ftdmchan->chan_id); f = fopen(dfile, "wb"); if (f) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO input in file %s\n", dfile); @@ -737,8 +738,8 @@ static void dump_mf(openr2_chan_t *r2chan) ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Could not dump IO input in file %s, error: %s", dfile, strerror(errno)); } - snprintf(dfile, sizeof(dfile), logname ? "%s.s%dc%d.output.alaw" : "%s/s%dc%d.output.alaw", - logname ? logname : r2data->logdir, ftdmchan->span_id, ftdmchan->chan_id); + snprintf(dfile, sizeof(dfile), !ftdm_strlen_zero(logname) ? "%s.s%dc%d.output.alaw" : "%s/s%dc%d.output.alaw", + !ftdm_strlen_zero(logname) ? logname : r2data->logdir, ftdmchan->span_id, ftdmchan->chan_id); f = fopen(dfile, "wb"); if (f) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO output in file %s\n", dfile); From 17d521128014853b24f983307fc28317f11e950b Mon Sep 17 00:00:00 2001 From: Mike Jerris Date: Mon, 14 Feb 2011 13:52:35 -0600 Subject: [PATCH 193/245] add make targets for mod_com_g729 mod_com_g729-activate mod_com_g729-install mod_com_g729-clean mod_com_g729-uninstall --- .gitignore | 69 +++++++++++++------------ build/getg729.sh.in | 34 ++++++++++++ build/modules.conf.in | 1 + configure.in | 6 +++ src/mod/Makefile.am | 5 +- src/mod/codecs/mod_com_g729/Makefile.am | 39 ++++++++++++++ 6 files changed, 120 insertions(+), 34 deletions(-) create mode 100755 build/getg729.sh.in create mode 100644 src/mod/codecs/mod_com_g729/Makefile.am diff --git a/.gitignore b/.gitignore index c53d07d8a9..2480b83823 100644 --- a/.gitignore +++ b/.gitignore @@ -46,45 +46,47 @@ core.* !/w32/Console/FreeSwitchConsole.vcproj.user !/w32/Setup/inno_setup/vcredist_x64.exe !/w32/Setup/inno_setup/vcredist_x86.exe -/.version -/AUTHORS -/COPYING -/ChangeLog -/Makefile -/Makefile.in -/NEWS -/README -/TAGS +.version +AUTHORS +COPYING +ChangeLog +Makefile +Makefile.in +NEWS +README +TAGS aclocal.m4 autom4te.cache -/build/Makefile -/build/Makefile.in -/build/config/compile -/build/config/config.guess -/build/config/depcomp -/build/config/install-sh -/build/config/ltmain.sh -/build/config/missing -/build/freeswitch.pc -/build/getlib.sh -/build/getsounds.sh -/build/modmake.rules +build/Makefile +build/Makefile.in +build/config/compile +build/config/config.guess +build/config/depcomp +build/config/install-sh +build/config/ltmain.sh +build/config/missing +build/freeswitch.pc +build/getlib.sh +build/getsounds.sh +build/modmake.rules +build/getg729.sh config.cache config.log config.status -/configure +configure configure.lineno -/freeswitch -/fs_cli -/fs_encode -/fs_ivrd -/libtool -/modules.conf -/quiet_libtool -/tone2wav -/scripts/fsxs -/scripts/gentls_cert -/a.out.dSYM +freeswitch +fs_cli +fs_encode +fs_ivrd +libtool +noreg +modules.conf +quiet_libtool +tone2wav +scripts/fsxs +scripts/gentls_cert +a.out.dSYM src/mod/applications/mod_easyroute/Makefile src/mod/applications/mod_lcr/Makefile src/mod/applications/mod_nibblebill/Makefile @@ -102,6 +104,7 @@ src/mod/say/mod_say_th/Makefile src/mod/say/mod_say_zh/Makefile libs/curl/lib/ca-bundle.h libs/g729/ +libs/fsg729-*-installer src/mod/codecs/mod_com_g729/ src/mod/languages/mod_lua/mod_lua_wrap.cpp.orig src/mod/languages/mod_perl/mod_perl_wrap.cpp.orig diff --git a/build/getg729.sh.in b/build/getg729.sh.in new file mode 100755 index 0000000000..c8a7227425 --- /dev/null +++ b/build/getg729.sh.in @@ -0,0 +1,34 @@ +#!/bin/sh + +TAR=@TAR@ +ZCAT=@ZCAT@ +WGET=@WGET@ +CURL=@CURL@ + +if [ -f "$WGET" ] ; then + DOWNLOAD_CMD=$WGET +else + if [ -f "$CURL" ] ; then + DOWNLOAD_CMD="$CURL -O" + fi +fi + +base=http://files.freeswitch.org/g729/ +tarfile=$1 +url=`echo $tarfile | grep "://"` + +if [ ! -z $url ] ; then + base=$tarfile/ + tarfile=$2 +fi + +if [ ! -f $tarfile ] ; then + $DOWNLOAD_CMD $base$tarfile + if [ ! -f $tarfile ] ; then + echo cannot find $tarfile + exit 1 + fi +fi + +exit 0 + diff --git a/build/modules.conf.in b/build/modules.conf.in index 8d3dfaa85a..63a0ab491e 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -42,6 +42,7 @@ codecs/mod_amr #codecs/mod_silk #codecs/mod_codec2 codecs/mod_g729 +#codecs/mod_com_g729 codecs/mod_h26x codecs/mod_bv codecs/mod_ilbc diff --git a/configure.in b/configure.in index d91cf11419..a0c9418751 100644 --- a/configure.in +++ b/configure.in @@ -730,6 +730,8 @@ AC_PATH_PROGS(WGET, wget) AC_PATH_PROGS(CURL, curl) GETLIB="cd $switch_srcdir/libs && ${SHELL} $switch_builddir/build/getlib.sh" AC_SUBST(GETLIB) +GETG729="cd $switch_srcdir/libs && ${SHELL} $switch_builddir/build/getg729.sh" +AC_SUBST(GETG729) GETSOUNDS="${SHELL} $switch_builddir/build/getsounds.sh" AC_SUBST(GETSOUNDS) @@ -916,6 +918,7 @@ AC_CONFIG_FILES([Makefile src/mod/applications/mod_osp/Makefile src/mod/applications/mod_stress/Makefile src/mod/applications/mod_hash/Makefile + src/mod/codecs/mod_com_g729/Makefile src/mod/endpoints/mod_portaudio/Makefile src/mod/endpoints/mod_skinny/Makefile src/mod/endpoints/mod_skypopen/Makefile @@ -930,6 +933,7 @@ AC_CONFIG_FILES([Makefile src/include/switch_am_config.h build/getsounds.sh build/getlib.sh + build/getg729.sh build/freeswitch.pc build/modmake.rules libs/xmlrpc-c/include/xmlrpc-c/config.h @@ -1023,6 +1027,7 @@ AC_OUTPUT ## ## Registering for ClueCon ## +if ! test -f noreg ; then echo "" echo "" echo $ECHO_N "Registering you for ClueCon http://www.cluecon.com $ECHO_C" 1>&6 @@ -1040,6 +1045,7 @@ sleep 1 AC_MSG_RESULT([ See you in August. ;-)]) sleep 2 echo "" +fi ## ## Configuration summary diff --git a/src/mod/Makefile.am b/src/mod/Makefile.am index e655cf7f05..5af782d12d 100644 --- a/src/mod/Makefile.am +++ b/src/mod/Makefile.am @@ -21,7 +21,7 @@ $(OUR_MODULES) $(OUR_CLEAN_MODULES) $(OUR_INSTALL_MODULES) $(OUR_UNINSTALL_MODUL fi ; \ fi ; \ if test -z "$$target" ; then target="all" ; fi ; \ - if ! test -f $$moddir/$$modname.c && ! test -f $$moddir/$$modname.cpp ; \ + if ! test -f $$moddir/$$modname.c && ! test -f $$moddir/$$modname.cpp && test $$modname != "mod_com_g729" ; \ then echo ; echo "WARNING $$modname is not a valid FreeSWITCH module dir, skipping it..." ; else \ echo ;\ echo making $$target $$modname ;\ @@ -35,6 +35,9 @@ $(OUR_MODULES) $(OUR_CLEAN_MODULES) $(OUR_INSTALL_MODULES) $(OUR_UNINSTALL_MODUL fi; \ test -z "$$fail" ; +mod_com_g729-activate: + cd $(switch_builddir)/src/mod/codecs/mod_com_g729 && $(MAKE) $(AM_MAKEFLAGS) activate + .DEFAULT: @if test -z "`echo $@ | grep all`"; then $(MAKE) $(AM_MAKEFLAGS) $@-all ; else echo Unknown target `echo $@ | sed -e 's|-all||'`; exit 1; fi diff --git a/src/mod/codecs/mod_com_g729/Makefile.am b/src/mod/codecs/mod_com_g729/Makefile.am new file mode 100644 index 0000000000..7b631386d3 --- /dev/null +++ b/src/mod/codecs/mod_com_g729/Makefile.am @@ -0,0 +1,39 @@ +include $(top_srcdir)/build/modmake.rulesam + +MODNAME=mod_com_g729 +VERSION=193 + +if ISLINUX + +G729INSTALLER = $(top_srcdir)/libs/fsg729-$(VERSION)-installer +LICSERVER=/usr/sbin/freeswitch_licence_server +VALIDATOR=$(bindir)/validator +MOD=$(moddir)/mod_com_g729.so +BUILT_SOURCES = $(G729INSTALLER) + +install: $(LICSERVER) $(VALIDATOR) $(MOD) + +$(LICSERVER) $(VALIDATOR) $(MOD): $(G729INSTALLER) + $(SHELL) $(G729INSTALLER) $(bindir) $(moddir) nobanner + $(ECHO) + $(ECHO) + $(ECHO) Now you can activate your license by running $(MAKE) mod_com_g729-activate + $(ECHO) + $(ECHO) + +$(G729INSTALLER): + rm -f $(top_srcdir)/libs/fsg729-*-installer* + $(GETG729) fsg729-$(VERSION)-installer + chmod 755 $(G729INSTALLER) + +clean: + rm -f $(top_srcdir)/libs/fsg729-*-installer* + rm -rf /tmp/fsg729 + +activate: $(LICSERVER) $(VALIDATOR) $(MOD) + $(VALIDATOR) + +uninstall: clean + rm -f $(LICSERVER) $(VALIDATOR) $(MOD) + +endif From d8add09a352cdfca64fa94688285ce6c96e6f6dc Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 14 Feb 2011 15:05:39 -0500 Subject: [PATCH 194/245] freetdm: ftmod_r2 - Disable MF dump on call accepted core - Do not start DTMF debugging until media is available --- libs/freetdm/src/ftdm_io.c | 4 ---- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 17 ++++++----------- libs/freetdm/src/include/private/ftdm_core.h | 3 +++ 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 906fbfed89..3ef22780f3 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -5536,10 +5536,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t } ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED); ftdm_call_set_call_id(sigmsg->channel, &sigmsg->channel->caller_data); - if (sigmsg->channel->dtmfdbg.requested) { - ftdm_channel_command(sigmsg->channel, FTDM_COMMAND_ENABLE_DEBUG_DTMF, NULL); - } - /* when cleaning up the public API I added this because mod_freetdm.c on_fxs_signal was * doing it during SIGEVENT_START, but now that flags are private they can't, wonder if * is needed at all? diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 83705d9af8..4265c9b8fa 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -676,12 +676,6 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Call offered with ANI = %s, DNIS = %s, Category = %d, ANI restricted = %s\n", ani, dnis, category, ani_restricted ? "Yes" : "No"); - /* nothing went wrong during call setup, MF has ended, we can and must disable the MF dump */ - if (r2data->mf_dump_size) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL); - } - /* check if this is a collect call and if we should accept it */ if (!r2data->allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Rejecting collect call\n"); @@ -770,6 +764,12 @@ static void ftdm_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t m R2CALL(ftdmchan)->accepted = 1; + /* nothing went wrong during call setup, MF has ended, we can and must disable the MF dump */ + if (r2data->mf_dump_size) { + ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL); + } + if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) { if (R2CALL(ftdmchan)->answer_pending) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Answer was pending, answering now.\n"); @@ -778,11 +778,6 @@ static void ftdm_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t m return; } } else { - /* nothing went wrong during call setup, MF has ended, we can and must disable the MF dump */ - if (r2data->mf_dump_size) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL); - } ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } } diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index ba16c7cb7f..7b26d655c5 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -688,6 +688,9 @@ FT_DECLARE(void) ftdm_set_echocancel_call_end(ftdm_channel_t *chan); if (!ftdm_test_flag((fchan), FTDM_CHANNEL_MEDIA)) { \ ftdm_set_flag((fchan), FTDM_CHANNEL_MEDIA); \ ftdm_set_echocancel_call_begin((fchan)); \ + if ((fchan)->dtmfdbg.requested) { \ + ftdm_channel_command((fchan), FTDM_COMMAND_ENABLE_DEBUG_DTMF, NULL); \ + } \ } \ } while (0); From 0bce777a4a06701798e426b13b8b7e0153836077 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 14 Feb 2011 14:07:37 -0600 Subject: [PATCH 195/245] fix regression in rtp stack trying to avoid broken clients who send the wrong payload type, we were eating the stun packets in jingle calls --- src/switch_rtp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 200f4f0dfa..faa79e35a2 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2808,7 +2808,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ goto end; } - if (bytes && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) && + if (bytes && rtp_session->recv_msg.header.version == 2 && + !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) && rtp_session->recv_msg.header.pt != 13 && rtp_session->recv_msg.header.pt != rtp_session->recv_te && (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) && From 642882727f015be345501f6f7c727ef23ec70c9f Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 14 Feb 2011 15:14:44 -0500 Subject: [PATCH 196/245] freetdm: added CLI completion for core commands --- libs/freetdm/mod_freetdm/mod_freetdm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index c0fdaa6ecc..3cb7dce9c1 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -4269,7 +4269,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load) switch_console_set_complete("add ftdm gains"); switch_console_set_complete("add ftdm dtmf on"); switch_console_set_complete("add ftdm dtmf off"); - + switch_console_set_complete("add ftdm core state"); + switch_console_set_complete("add ftdm core flag"); + switch_console_set_complete("add ftdm core calls"); SWITCH_ADD_APP(app_interface, "disable_ec", "Disable Echo Canceller", "Disable Echo Canceller", disable_ec_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "disable_dtmf", "Disable DTMF Detection", "Disable DTMF Detection", disable_dtmf_function, "", SAF_NONE); From c9ee4fab736d1d0db6638468598bab11b1648c87 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 14 Feb 2011 17:32:30 -0500 Subject: [PATCH 197/245] freetdm: remove deprecated channel variables code --- libs/freetdm/mod_freetdm/mod_freetdm.c | 14 +-- libs/freetdm/src/ftdm_io.c | 117 +----------------- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 36 +++--- libs/freetdm/src/include/freetdm.h | 39 ------ libs/freetdm/src/include/private/ftdm_core.h | 19 ++- 5 files changed, 41 insertions(+), 184 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 78874de059..b42a13b278 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1552,6 +1552,8 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chanid); switch_channel_set_variable_printf(channel, "freetdm_bearer_capability", "%d", channel_caller_data->bearer_capability); switch_channel_set_variable_printf(channel, "freetdm_bearer_layer1", "%d", channel_caller_data->bearer_layer1); + switch_channel_set_variable_printf(channel, "freetdm_screening_ind", ftdm_screening2str(channel_caller_data->screen)); + switch_channel_set_variable_printf(channel, "freetdm_presentation_ind", ftdm_presentation2str(channel_caller_data->pres)); if (globals.sip_headers) { switch_channel_set_variable(channel, "sip_h_X-FreeTDM-SpanName", ftdm_channel_get_span_name(sigmsg->channel)); @@ -1580,21 +1582,13 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session if (channel_caller_data->raw_data_len) { switch_channel_set_variable_printf(channel, "freetdm_custom_call_data", "%s", channel_caller_data->raw_data); } - /* Add any channel variable to the dial plan */ - iter = ftdm_channel_get_var_iterator(sigmsg->channel, NULL); - for (curr = iter ; curr; curr = ftdm_iterator_next(curr)) { - ftdm_channel_get_current_var(curr, &var_name, &var_value); - snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name); - switch_channel_set_variable_printf(channel, name, "%s", var_value); - } - /* Add any call variable to the dial plan */ iter = ftdm_call_get_var_iterator(channel_caller_data, iter); for (curr = iter ; curr; curr = ftdm_iterator_next(curr)) { ftdm_call_get_current_var(curr, &var_name, &var_value); snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name); switch_channel_set_variable_printf(channel, name, "%s", var_value); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s=%s\n", name, var_value); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s = %s\n", name, var_value); } ftdm_iterator_free(iter); @@ -2149,8 +2143,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) switch(sigmsg->event_id) { case FTDM_SIGEVENT_START: { - ftdm_call_add_var(caller_data, "screening_ind", ftdm_screening2str(caller_data->screen)); - ftdm_call_add_var(caller_data, "presentation_ind", ftdm_presentation2str(caller_data->pres)); return ftdm_channel_from_event(sigmsg, &session); } break; diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index bd4e896dad..59615b4c75 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -65,7 +65,6 @@ ftdm_time_t time_current_throttle_log = 0; static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter); static ftdm_status_t ftdm_call_set_call_id(ftdm_channel_t *fchan, ftdm_caller_data_t *caller_data); static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data); -static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan); static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan); static int time_is_init = 0; @@ -2633,7 +2632,6 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdm_buffer_destroy(&ftdmchan->pre_buffer); ftdmchan->pre_buffer_size = 0; ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex); - ftdm_channel_clear_vars(ftdmchan); if (ftdmchan->hangup_timer) { ftdm_sched_cancel_timer(globals.timingsched, ftdmchan->hangup_timer); } @@ -4033,20 +4031,13 @@ done: } FT_DECLARE(void) ftdm_call_clear_data(ftdm_caller_data_t *caller_data) -{ - ftdm_call_clear_vars(caller_data); - memset(&caller_data->raw_data, 0, sizeof(caller_data->raw_data)); - caller_data->raw_data_len = 0; - return; -} - -FT_DECLARE(ftdm_status_t) ftdm_call_clear_vars(ftdm_caller_data_t *caller_data) { if (caller_data->variables) { hashtable_destroy(caller_data->variables); } caller_data->variables = NULL; - return FTDM_SUCCESS; + memset(&caller_data->raw_data, 0, sizeof(caller_data->raw_data)); + caller_data->raw_data_len = 0; } FT_DECLARE(ftdm_status_t) ftdm_call_remove_var(ftdm_caller_data_t *caller_data, const char *var_name) @@ -4058,7 +4049,6 @@ FT_DECLARE(ftdm_status_t) ftdm_call_remove_var(ftdm_caller_data_t *caller_data, return FTDM_SUCCESS; } - FT_DECLARE(ftdm_status_t) ftdm_call_add_var(ftdm_caller_data_t *caller_data, const char *var_name, const char *value) { char *t_name = 0, *t_val = 0; @@ -4125,72 +4115,6 @@ FT_DECLARE(ftdm_status_t) ftdm_call_get_current_var(ftdm_iterator_t *iter, const return FTDM_SUCCESS; } - -static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan) -{ - ftdm_channel_lock(ftdmchan); - - if (ftdmchan->variable_hash) { - hashtable_destroy(ftdmchan->variable_hash); - } - ftdmchan->variable_hash = NULL; - - ftdm_channel_unlock(ftdmchan); - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_add_var(ftdm_channel_t *ftdmchan, const char *var_name, const char *value) -{ - char *t_name = 0, *t_val = 0; - - ftdm_status_t status = FTDM_FAIL; - - if (!var_name || !value) { - return FTDM_FAIL; - } - - ftdm_channel_lock(ftdmchan); - - if (!ftdmchan->variable_hash) { - /* initialize on first use */ - ftdmchan->variable_hash = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - if (!ftdmchan->variable_hash) { - goto done; - } - } - - t_name = ftdm_strdup(var_name); - t_val = ftdm_strdup(value); - - hashtable_insert(ftdmchan->variable_hash, t_name, t_val, HASHTABLE_FLAG_FREE_KEY | HASHTABLE_FLAG_FREE_VALUE); - - status = FTDM_SUCCESS; - -done: - ftdm_channel_unlock(ftdmchan); - - return status; -} - - -FT_DECLARE(const char *) ftdm_channel_get_var(ftdm_channel_t *ftdmchan, const char *var_name) -{ - const char *var = NULL; - - ftdm_channel_lock(ftdmchan); - - if (!ftdmchan->variable_hash || !var_name) { - goto done; - } - - var = (const char *)hashtable_search(ftdmchan->variable_hash, (void *)var_name); - -done: - ftdm_channel_unlock(ftdmchan); - - return var; -} - static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter) { int allocated = 0; @@ -4215,25 +4139,6 @@ static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t return iter; } -FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan, ftdm_iterator_t *iter) -{ - ftdm_hash_iterator_t *hashiter = NULL; - ftdm_channel_lock(ftdmchan); - hashiter = ftdmchan->variable_hash == NULL ? NULL : hashtable_first(ftdmchan->variable_hash); - ftdm_channel_unlock(ftdmchan); - - - if (hashiter == NULL) { - return NULL; - } - - if (!(iter = get_iterator(FTDM_ITERATOR_VARS, iter))) { - return NULL; - } - iter->pvt.hashiter = hashiter; - return iter; -} - FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *span, ftdm_iterator_t *iter) { if (!(iter = get_iterator(FTDM_ITERATOR_CHANS, iter))) { @@ -4244,24 +4149,6 @@ FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *spa return iter; } -FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val) -{ - const void *key = NULL; - void *val = NULL; - - *var_name = NULL; - *var_val = NULL; - - ftdm_assert_return(iter && (iter->type == FTDM_ITERATOR_VARS) && iter->pvt.hashiter, FTDM_FAIL, "Cannot get variable from invalid iterator!\n"); - - hashtable_this(iter->pvt.hashiter, &key, NULL, &val); - - *var_name = key; - *var_val = val; - - return FTDM_SUCCESS; -} - FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter) { ftdm_assert_return(iter && iter->type, NULL, "Invalid iterator\n"); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c index 06b0b2183e..918b284de1 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c @@ -299,7 +299,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) ftdmchan->caller_data.dnis.digits, iam.cdPtyNum.natAddrInd.val); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -379,7 +379,7 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) ADDRCMPLT); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ACM\n", sngss7_info->circuit->cic); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -403,7 +403,7 @@ void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan) 5); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ANM\n", sngss7_info->circuit->cic); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -438,7 +438,7 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan) SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx REL cause=%d \n", sngss7_info->circuit->cic, ftdmchan->caller_data.hangup_cause ); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -461,7 +461,7 @@ void ft_to_sngss7_rlc (ftdm_channel_t * ftdmchan) &rlc); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RLC\n", sngss7_info->circuit->cic); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -482,7 +482,7 @@ void ft_to_sngss7_rsc (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC\n", sngss7_info->circuit->cic); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -503,7 +503,7 @@ void ft_to_sngss7_rsca (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC-RLC\n", sngss7_info->circuit->cic); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -524,7 +524,7 @@ void ft_to_sngss7_blo (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLO\n", sngss7_info->circuit->cic); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -545,7 +545,7 @@ void ft_to_sngss7_bla (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLA\n", sngss7_info->circuit->cic); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -567,7 +567,7 @@ ft_to_sngss7_ubl (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBL\n", sngss7_info->circuit->cic); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -588,7 +588,7 @@ void ft_to_sngss7_uba (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBA\n", sngss7_info->circuit->cic); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -609,7 +609,7 @@ void ft_to_sngss7_lpa (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx LPA\n", sngss7_info->circuit->cic); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -654,7 +654,7 @@ void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan) sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->rx_grs.range)); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -688,7 +688,7 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan) sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->tx_grs.range)); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -737,7 +737,7 @@ void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan) /* clean out the saved data */ memset(&sngss7_span->rx_cgb, 0x0, sizeof(sngss7_group_data_t)); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -787,7 +787,7 @@ void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan) /* clean out the saved data */ memset(&sngss7_span->rx_cgu, 0x0, sizeof(sngss7_group_data_t)); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -838,7 +838,7 @@ void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan) /* clean out the saved data */ memset(&sngss7_span->tx_cgb, 0x0, sizeof(sngss7_group_data_t)); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -889,7 +889,7 @@ void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan) /* clean out the saved data */ memset(&sngss7_span->tx_cgu, 0x0, sizeof(sngss7_group_data_t)); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 588dc311b6..bb4b08b1a6 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -1368,34 +1368,12 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data */ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t datasize, ftdm_size_t *datalen); -/*! \brief Add a custom variable to the channel - * \note This variables may be used by signaling modules to override signaling parameters - * \todo Document which signaling variables are available - * */ -FT_DECLARE(ftdm_status_t) ftdm_channel_add_var(ftdm_channel_t *ftdmchan, const char *var_name, const char *value); - -/*! \brief Get a custom variable from the channel. - * \note The variable pointer returned is only valid while the channel is open and it'll be destroyed when the channel is closed. */ -FT_DECLARE(const char *) ftdm_channel_get_var(ftdm_channel_t *ftdmchan, const char *var_name); - -/*! \brief Get an iterator to iterate over the channel variables - * \param ftdmchan The channel structure containing the variables - * \param iter Optional iterator. You can reuse an old iterator (not previously freed) to avoid the extra allocation of a new iterator. - * \note The iterator pointer returned is only valid while the channel is open and it'll be destroyed when the channel is closed. - * This iterator is completely non-thread safe, if you are adding variables or removing variables while iterating - * results are unpredictable - */ -FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan, ftdm_iterator_t *iter); - /*! \brief Get iterator current value (depends on the iterator type) * \note Channel iterators return a pointer to ftdm_channel_t * Variable iterators return a pointer to the variable name (not the variable value) */ FT_DECLARE(void *) ftdm_iterator_current(ftdm_iterator_t *iter); -/*! \brief Get variable name and value for the current iterator position */ -FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val); - /*! \brief Advance iterator */ FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter); @@ -1426,23 +1404,6 @@ FT_DECLARE(ftdm_iterator_t *) ftdm_call_get_var_iterator(const ftdm_caller_data_ /*! \brief Get variable name and value for the current iterator position */ FT_DECLARE(ftdm_status_t) ftdm_call_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val); -/*! \brief Clear all variables attached to the call - * \note Variables are cleared at the end of each call back, so it is not necessary for the user to call this function. - * \todo Document which signaling variables are available - * */ -FT_DECLARE(ftdm_status_t) ftdm_call_clear_vars(ftdm_caller_data_t *caller_data); - -/*! \brief Remove a variable attached to the call - * \note Removes a variable that was attached to the call. - * \todo Document which call variables are available - * */ -FT_DECLARE(ftdm_status_t) ftdm_call_remove_var(ftdm_caller_data_t *caller_data, const char *var_name); - -/*! \brief Clears all the temporary data attached to this call - * \note Clears caller_data->variables and caller_data->raw_data. - * */ -FT_DECLARE(void) ftdm_call_clear_data(ftdm_caller_data_t *caller_data); - /*! \brief Get the span pointer associated to the channel */ FT_DECLARE(ftdm_span_t *) ftdm_channel_get_span(const ftdm_channel_t *ftdmchan); diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index ba16c7cb7f..07717a4ea2 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -451,7 +451,6 @@ struct ftdm_channel { struct ftdm_caller_data caller_data; struct ftdm_span *span; struct ftdm_io_interface *fio; - ftdm_hash_t *variable_hash; unsigned char rx_cas_bits; uint32_t pre_buffer_size; uint8_t rxgain_table[FTDM_GAINS_TABLE_SIZE]; @@ -629,6 +628,24 @@ FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan); FT_DECLARE(void) ftdm_set_echocancel_call_begin(ftdm_channel_t *chan); FT_DECLARE(void) ftdm_set_echocancel_call_end(ftdm_channel_t *chan); +/*! \brief Clear all variables attached to the call + * \note Variables are cleared at the end of each call back, so it is not necessary for the user to call this function. + * \todo Document which signaling variables are available + * */ +FT_DECLARE(ftdm_status_t) ftdm_call_clear_vars(ftdm_caller_data_t *caller_data); + +/*! \brief Remove a variable attached to the call + * \note Removes a variable that was attached to the call. + * \todo Document which call variables are available + * */ +FT_DECLARE(ftdm_status_t) ftdm_call_remove_var(ftdm_caller_data_t *caller_data, const char *var_name); + +/*! \brief Clears all the temporary data attached to this call + * \note Clears caller_data->variables and caller_data->raw_data. + * */ +FT_DECLARE(void) ftdm_call_clear_data(ftdm_caller_data_t *caller_data); + + /*! \brief Assert condition */ From cd1982ceb7c7a7df598adea002cea51d040a3f62 Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Mon, 14 Feb 2011 22:43:45 -0500 Subject: [PATCH 198/245] mod_callcenter: IMPORTANT UPDATE, DTMF during moh created an loop to reactivate MOH but got canceled right away because of pending DTMF in the queue never been cleaned. Could cause masive disk write of debug, and can cause problem to the rest of FS stability. This patch also include basic fundation for DTMF capture support for member waiting. --- .../mod_callcenter/mod_callcenter.c | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index 61305bbbb5..a06520f987 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -2080,6 +2080,32 @@ void *SWITCH_THREAD_FUNC cc_member_thread_run(switch_thread_t *thread, void *obj return NULL; } +struct moh_dtmf_helper { + const char *queue_name; + char dtmf; +}; + +static switch_status_t moh_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) { + struct moh_dtmf_helper *h = (struct moh_dtmf_helper *) buf; + + switch (itype) { + case SWITCH_INPUT_TYPE_DTMF: + { + /* Just laywork for people who want to get some DTMF actions */ + switch_dtmf_t *dtmf = (switch_dtmf_t *) input; + if (strchr("#", dtmf->digit)) { + h->dtmf = dtmf->digit; + return SWITCH_STATUS_BREAK; + } + } + break; + default: + break; + } + + return SWITCH_STATUS_SUCCESS; +} + #define CC_DESC "callcenter" #define CC_USAGE "queue_name" @@ -2226,8 +2252,6 @@ SWITCH_STANDARD_APP(callcenter_function) switch_thread_create(&thread, thd_attr, cc_member_thread_run, h, h->pool); /* Playback MOH */ - /* TODO Add DTMF callback support */ - /* TODO add MOH infitite loop */ if (cc_moh_override) { cur_moh = switch_core_session_strdup(member_session, cc_moh_override); } else { @@ -2237,6 +2261,12 @@ SWITCH_STANDARD_APP(callcenter_function) while (switch_channel_ready(member_channel)) { switch_input_args_t args = { 0 }; + struct moh_dtmf_helper ht; + + ht.dtmf = '\0'; + args.input_callback = moh_on_dtmf; + args.buf = (void *) &ht; + args.buflen = sizeof(h); /* An agent was found, time to exit and let the bridge do it job */ if ((agent_uuid = switch_channel_get_variable(member_channel, "cc_agent_uuid"))) { @@ -2260,6 +2290,8 @@ SWITCH_STANDARD_APP(callcenter_function) switch_ivr_collect_digits_callback(session, &args, 0, 0); } + switch_yield(1000); + } /* Stop Member Thread */ From 2e399b0baf871b82e8b1bd553fce16b54abe6d7b Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Mon, 14 Feb 2011 22:46:35 -0500 Subject: [PATCH 199/245] mod_callcenter: force loopback_bowout=false on originate. This will need to be reworked, but should fix basic issues call to an agent using loopback --- src/mod/applications/mod_callcenter/mod_callcenter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index a06520f987..9d9feed0aa 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -1384,6 +1384,8 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_agent", "%s", h->agent_name); switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_agent_type", "%s", h->agent_type); switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "ignore_early_media", "true"); + /* Force loopback to remain live, if not, the loop will detect the actual channel to gone */ + switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "loopback_bowout", "false"); t_agent_called = switch_epoch_time_now(NULL); dialstr = switch_mprintf("%s", h->originate_string); From 500e9acd254e1e2b50d07aec2fe1241fe3e18aba Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Tue, 15 Feb 2011 01:49:41 -0500 Subject: [PATCH 200/245] switch_core: Add capability to specify core-db-name in switch.conf.xml to have sqlite in a different location. This is important for everyone with relatively 'high' sip registration since the addition of sip registration to the core require sqlite db to be moved to a faster location (Ramdisk for example). Useful for everyone who moved their sqlite db for sofia to ramdisk because of performance issue. --- conf/autoload_configs/switch.conf.xml | 2 ++ src/include/private/switch_core_pvt.h | 1 + src/switch_core.c | 3 +++ src/switch_core_sqldb.c | 6 +++++- 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/conf/autoload_configs/switch.conf.xml b/conf/autoload_configs/switch.conf.xml index 44893b931a..95c43331e4 100644 --- a/conf/autoload_configs/switch.conf.xml +++ b/conf/autoload_configs/switch.conf.xml @@ -94,6 +94,8 @@ + + diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 05cd24d230..f8c6a794b9 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -236,6 +236,7 @@ struct switch_runtime { char *odbc_dsn; char *odbc_user; char *odbc_pass; + char *dbname; uint32_t debug_level; uint32_t runlevel; uint32_t tipping_point; diff --git a/src/switch_core.c b/src/switch_core.c index 0eb51ccab3..66731b61c8 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1298,6 +1298,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc runtime.default_dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION; runtime.min_dtmf_duration = SWITCH_MIN_DTMF_DURATION; runtime.odbc_dbtype = DBTYPE_DEFAULT; + runtime.dbname = NULL; /* INIT APR and Create the pool context */ if (apr_initialize() != SWITCH_STATUS_SUCCESS) { @@ -1641,6 +1642,8 @@ static void switch_load_core_config(const char *file) switch_rtp_set_start_port((switch_port_t) atoi(val)); } else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)) { switch_rtp_set_end_port((switch_port_t) atoi(val)); + } else if (!strcasecmp(var, "core-db-name") && !zstr(val)) { + runtime.dbname = switch_core_strdup(runtime.memory_pool, val); } else if (!strcasecmp(var, "core-db-dsn") && !zstr(val)) { if (switch_odbc_available()) { runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val); diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index f54bd650fe..120b2565cf 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -74,7 +74,11 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); } else { - options.core_db_options.db_path = SWITCH_CORE_DB; + if (runtime.dbname) { + options.core_db_options.db_path = runtime.dbname; + } else { + options.core_db_options.db_path = SWITCH_CORE_DB; + } r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); } From 1096e6732c6073228f78d7ab24be29780713f64c Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Tue, 15 Feb 2011 02:24:43 -0500 Subject: [PATCH 201/245] switch_core_sqldb: Index column name wrong on table registrations. (This wont create the index for people who already have the table) --- src/switch_core_sqldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 120b2565cf..f135e9586d 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1639,7 +1639,7 @@ static char create_registrations_sql[] = " network_proto VARCHAR(256),\n" " hostname VARCHAR(256)\n" ");\n" - "create index regindex1 on registrations (user,realm,hostname);\n"; + "create index regindex1 on registrations (reg_user,realm,hostname);\n"; SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, const char *realm, const char *token, const char *url, uint32_t expires, From 017842c87fb8f7c93e486e00076ffdfd684d41fb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 15 Feb 2011 09:45:14 -0600 Subject: [PATCH 202/245] FS-3056 --- src/mod/applications/mod_commands/mod_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 030cb8e867..517134d2e1 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -780,7 +780,7 @@ SWITCH_STANDARD_API(user_data_function) if ((domain = strchr(user, '@'))) { *domain++ = '\0'; } else { - if ((dup_domain = switch_core_get_variable("domain"))) { + if ((dup_domain = switch_core_get_variable_dup("domain"))) { domain = dup_domain; } else { domain = "cluecon.com"; From 11cc6f95cddb45f261af348e03007e78de88b2ae Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Tue, 15 Feb 2011 11:58:16 -0500 Subject: [PATCH 203/245] freetdm: ss7 - update to configuration file to mirror ISDN configuration --- libs/freetdm/mod_freetdm/mod_freetdm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 7f18b1f2d4..4dc6cfcfd2 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2690,7 +2690,7 @@ static switch_status_t load_config(void) ftdm_conf_parameter_t spanparameters[30]; char *id = (char *) switch_xml_attr(myspan, "id"); char *name = (char *) switch_xml_attr(myspan, "name"); - char *configname = (char *) switch_xml_attr(myspan, "config"); + char *configname = (char *) switch_xml_attr(myspan, "cfgprofile"); ftdm_span_t *span = NULL; uint32_t span_id = 0; unsigned paramindex = 0; From a411cea7b21c2b1094848c11ff9213b9b7d2b3b6 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 15 Feb 2011 16:34:09 -0500 Subject: [PATCH 204/245] freetdm: ftmod_r2 - check fclose return value when dumping IO --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 4265c9b8fa..540d7cb6e9 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -714,6 +714,7 @@ static void dump_mf(openr2_chan_t *r2chan) { char dfile[512]; FILE *f = NULL; + int rc = 0; ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; if (r2data->mf_dump_size) { @@ -727,7 +728,10 @@ static void dump_mf(openr2_chan_t *r2chan) if (f) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO input in file %s\n", dfile); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_INPUT, f); - fclose(f); + rc = fclose(f); + if (rc) { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failure closing IO input file %s: %s\n", dfile, strerror(errno)); + } } else { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Could not dump IO input in file %s, error: %s", dfile, strerror(errno)); } @@ -738,7 +742,10 @@ static void dump_mf(openr2_chan_t *r2chan) if (f) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO output in file %s\n", dfile); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_OUTPUT, f); - fclose(f); + rc = fclose(f); + if (rc) { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failure closing IO output file %s: %s\n", dfile, strerror(errno)); + } } else { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Could not dump IO output in file %s, error: %s", dfile, strerror(errno)); } From c565501f555a507fa2c56eccedccdbba7a366d6d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 15 Feb 2011 16:09:48 -0600 Subject: [PATCH 205/245] tell rtp stack about what remote payload type to expect when the receiving end follows the stupid SHOULD as WONT and sends a different dynamic payload number than the one in the offer --- src/include/switch_rtp.h | 2 + src/mod/endpoints/mod_sofia/mod_sofia.h | 2 + src/mod/endpoints/mod_sofia/sofia_glue.c | 71 ++++++++++++++++++++++-- src/switch_rtp.c | 12 ++-- 4 files changed, 78 insertions(+), 9 deletions(-) diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 27dacc7c18..2870bba3af 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -437,6 +437,8 @@ SWITCH_DECLARE(void) switch_rtp_set_private(switch_rtp_t *rtp_session, void *pri */ SWITCH_DECLARE(void) switch_rtp_set_telephony_event(switch_rtp_t *rtp_session, switch_payload_t te); SWITCH_DECLARE(void) switch_rtp_set_telephony_recv_event(switch_rtp_t *rtp_session, switch_payload_t te); +SWITCH_DECLARE(void) switch_rtp_set_recv_pt(switch_rtp_t *rtp_session, switch_payload_t pt); + /*! \brief Set the payload type for comfort noise \param rtp_session the RTP session to modify diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 12148c0f1b..da92746319 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -587,6 +587,8 @@ struct private_object { sofia_private_t *sofia_private; uint8_t flags[TFLAG_MAX]; switch_payload_t agreed_pt; + switch_payload_t audio_recv_pt; + switch_payload_t video_recv_pt; switch_core_session_t *session; switch_channel_t *channel; switch_frame_t read_frame; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index a0b7fca2ff..b2185a2f15 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -3234,6 +3234,11 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f switch_rtp_set_telephony_recv_event(tech_pvt->rtp_session, tech_pvt->recv_te); } + if (tech_pvt->audio_recv_pt != tech_pvt->agreed_pt) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_CRIT, "Set audio receive payload to %u\n", tech_pvt->audio_recv_pt); + switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->audio_recv_pt); + } + if (sofia_test_pflag(tech_pvt->profile, PFLAG_SUPPRESS_CNG) || ((val = switch_channel_get_variable(tech_pvt->channel, "supress_cng")) && switch_true(val)) || ((val = switch_channel_get_variable(tech_pvt->channel, "suppress_cng")) && switch_true(val))) { @@ -3307,7 +3312,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port"))) { remote_rtcp_port = (switch_port_t)atoi(rport); } - + if (switch_rtp_set_remote_address (tech_pvt->video_rtp_session, tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { @@ -3412,6 +3417,13 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f switch_rtp_set_ssrc(tech_pvt->video_rtp_session, ssrc_ul); } + + if (tech_pvt->video_recv_pt != tech_pvt->video_agreed_pt) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, + "Set video receive payload to %u\n", tech_pvt->video_recv_pt); + switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->video_recv_pt); + } + switch_channel_set_variable_printf(tech_pvt->channel, "sip_use_video_pt", "%d", tech_pvt->video_agreed_pt); tech_pvt->video_ssrc = switch_rtp_get_ssrc(tech_pvt->rtp_session); switch_channel_set_variable_printf(tech_pvt->channel, "rtp_use_video_ssrc", "%u", tech_pvt->ssrc); @@ -4038,6 +4050,24 @@ switch_t38_options_t *sofia_glue_extract_t38_options(switch_core_session_t *sess } +switch_status_t sofia_glue_get_offered_pt(private_object_t *tech_pvt, const switch_codec_implementation_t *mimp, switch_payload_t *pt) +{ + int i = 0; + + for (i = 0; i < tech_pvt->num_codecs; i++) { + const switch_codec_implementation_t *imp = tech_pvt->codecs[i]; + + if (!strcasecmp(imp->iananame, mimp->iananame)) { + *pt = tech_pvt->ianacodes[i]; + + return SWITCH_STATUS_SUCCESS; + } + } + + return SWITCH_STATUS_FALSE; +} + + uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_sdp) { uint8_t match = 0; @@ -4554,9 +4584,17 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_sdp_audio_port); switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip); switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); - + tech_pvt->audio_recv_pt = map->rm_pt; + + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { + sofia_glue_get_offered_pt(tech_pvt, mimp, &tech_pvt->audio_recv_pt); + } + + switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->audio_recv_pt); + switch_channel_set_variable(tech_pvt->channel, "sip_audio_recv_pt", tmp); + } - + if (match) { if (sofia_glue_tech_set_codec(tech_pvt, 1) == SWITCH_STATUS_SUCCESS) { got_audio = 1; @@ -4583,7 +4621,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s } } - + if (!match && greedy && mine < tech_pvt->num_codecs) { mine++; skip = 0; @@ -4665,6 +4703,16 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->video_agreed_pt); switch_channel_set_variable(tech_pvt->channel, "sip_video_pt", tmp); sofia_glue_check_video_codecs(tech_pvt); + + tech_pvt->video_recv_pt = map->rm_pt; + + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { + sofia_glue_get_offered_pt(tech_pvt, mimp, &tech_pvt->video_recv_pt); + } + + switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->video_recv_pt); + switch_channel_set_variable(tech_pvt->channel, "sip_video_recv_pt", tmp); + break; } else { vmatch = 0; @@ -5164,7 +5212,7 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName if ((tmp = switch_channel_get_variable(channel, "sip_use_pt"))) { tech_pvt->pt = tech_pvt->agreed_pt = (switch_payload_t)atoi(tmp); } - + sofia_glue_tech_set_codec(tech_pvt, 1); tech_pvt->adv_sdp_audio_ip = tech_pvt->extrtpip = (char *) ip; @@ -5219,6 +5267,19 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName switch_xml_free(xml); return 0; } + + if (switch_rtp_ready(tech_pvt->rtp_session)) { + if ((tmp = switch_channel_get_variable(channel, "sip_audio_recv_pt"))) { + switch_rtp_set_recv_pt(tech_pvt->rtp_session, atoi(tmp)); + } + } + + if (switch_rtp_ready(tech_pvt->video_rtp_session)) { + if ((tmp = switch_channel_get_variable(channel, "sip_video_recv_pt"))) { + switch_rtp_set_recv_pt(tech_pvt->rtp_session, atoi(tmp)); + } + } + } if (switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index faa79e35a2..ffc41a73c6 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1578,7 +1578,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session rtp_session->recv_msg.header.cc = 0; rtp_session->payload = payload; - + rtp_session->rpayload = payload; rtp_session->rtcp_send_msg.header.version = 2; rtp_session->rtcp_send_msg.header.p = 0; @@ -1773,6 +1773,12 @@ SWITCH_DECLARE(void) switch_rtp_set_telephony_recv_event(switch_rtp_t *rtp_sessi } } +SWITCH_DECLARE(void) switch_rtp_set_recv_pt(switch_rtp_t *rtp_session, switch_payload_t pt) +{ + rtp_session->rpayload = pt; +} + + SWITCH_DECLARE(void) switch_rtp_set_cng_pt(switch_rtp_t *rtp_session, switch_payload_t pt) { rtp_session->cng_pt = pt; @@ -2813,7 +2819,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ rtp_session->recv_msg.header.pt != 13 && rtp_session->recv_msg.header.pt != rtp_session->recv_te && (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) && - rtp_session->recv_msg.header.pt != rtp_session->payload) { + rtp_session->recv_msg.header.pt != rtp_session->rpayload) { /* drop frames of incorrect payload number and return CNG frame instead */ return_cng_frame(); } @@ -3131,8 +3137,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ rtp_session->recv_msg.header.pt = 97; } - rtp_session->rpayload = (switch_payload_t) rtp_session->recv_msg.header.pt; - break; do_continue: From b7fd81de33a28c95cb935cc57429081b6c5a5f41 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 15 Feb 2011 16:30:57 -0600 Subject: [PATCH 206/245] rip off the fs_ args on message like we do in SEND_MESSAGE --- src/mod/endpoints/mod_sofia/sofia_presence.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 2313cb7a1a..3755894cb8 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -80,6 +80,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co char *ffrom = NULL; nua_handle_t *msg_nh; char *contact = NULL; + char *p; char *dup = NULL; switch_status_t status = SWITCH_STATUS_FALSE; const char *ct = "text/html"; @@ -239,8 +240,12 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co status = SWITCH_STATUS_SUCCESS; - /* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */ + if ((p = strstr(contact, ";fs_"))) { + *p = '\0'; + } + /* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */ + msg_nh = nua_handle(profile->nua, NULL, TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), From 4f93ea25ece53df029e6dc6c913ad7c190df22d5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 15 Feb 2011 17:43:13 -0600 Subject: [PATCH 207/245] allow uuid bridge on unaswered channels as long as there is media available on at least one --- src/switch_ivr_bridge.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 6f84de3893..f130625a75 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1398,8 +1398,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu return SWITCH_STATUS_FALSE; } - if (!switch_channel_test_flag(originator_channel, CF_ANSWERED)) { - if (switch_channel_test_flag(originatee_channel, CF_ANSWERED)) { + //if (!switch_channel_test_flag(originator_channel, CF_ANSWERED)) { + if (!switch_channel_media_ready(originator_channel)) { + if (switch_channel_media_ready(originatee_channel)) { + //if (switch_channel_test_flag(originatee_channel, CF_ANSWERED)) { swap_session = originator_session; originator_session = originatee_session; originatee_session = swap_session; From 713b82d52f0432044d210ef6050418e285abf213 Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Tue, 15 Feb 2011 16:20:50 -0800 Subject: [PATCH 208/245] Update ChangeLog through Feb 1 --- docs/ChangeLog | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/docs/ChangeLog b/docs/ChangeLog index 41f94d78ab..356cbdc852 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -35,6 +35,7 @@ freeswitch (1.0.7) config: Disallow global-intercept and group-intercept can intercept an outbound call in default dialplan (r:890871ba/FS-2777) config: fix single domain assumption in default config to be more portable *cough* bkw *cough* (r:f987903e) config: Bump Doxygen.conf version to 1.0.6... belatedly (r:cfeae1ba) + config: docs for acl (r:57b410eb) core: Add RTCP support (FSRTP-14) core: handle some errors on missing db handle conditions core: add ... and shutdown as a fail-safe when no modules are loaded @@ -164,6 +165,24 @@ freeswitch (1.0.7) core: drop rtp frame that was already replaced with a cng frame (r:34a0ca50) core: fix partial match counting as exact match in dmachine (r:5eb951aa) core: try to adjust the timer to be ok with the horrible 10000 microsecond kernel resolution on amazon ec3 but that doesn't mean it's not horribly wrong to run the kernel that slow (r:903b2901) + core: make exact matches return sooner in dmachine (r:e897646e) + core: don't let inherit_codec work when we have ep_codec_string set and the B-leg codec is not in that list since it will lead to failure (r:f79f9766) + core: set maximum query run time to 30 seconds at least on drivers that support SQL_ATTR_QUERY_TIMEOUT (r:5bb525e1) + core: dd switch_cache_db_affected_rows() to switch_core_sqldb (and switch_odbc) and expose it through Lua dbh:affected_rows() (r:d79cf484/FS-2962) + core: add bind meta on A-D and refactor (r:27869d7a) + core: add temp_hold_music var that is only valid until you transfer the call and finishing touches on bind meta to A-D (r:b262f44c) + core: add function to help set session read codec to slinear (r:1a08df9b) + core: add rtp_bug IGNORE_DTMF_DURATION to speed up dtmf detection of RFC2833 on strange carriers (r:b3fc001e) + core: Fix crash when re-connecting to non-working database server (r:29daaa07/FS-2960) + core: treat EINTR returns as a BREAK (now mapped to SWITCH_STATUS_INTR), we appriciate the interrupted syscalls but we would like to continue working properly (r:316963c5) + core: eat rtp frames with the wrong payload type number (r:fe1711fd) + core: up assert vaule on header loop detection to 1 meeeeelyonne for hmmhesegs (r:d9c56345) + core: Fix race condition in originate where USER_BUSY is reported as a no answer (r:cc06fdb5/FS-2992) + core: Allow check ip change to be optional (r:1cf79386/FS-2917) + core: handle 2833 in do_flush instead of dropping valid dtmf (r:3fa3e11c/FS-3002) + core: add record_restart_time_limit_on_dtmf var (r:7a1dcb69) + core: fix unreachable condition with a null args to make any key stop playback/record etc without dequing and remove hard-coded flush digits in play_and_get_digits be sure to flush it yourself before using (r:976859bb) + core: Fix a lock on reloadxml when stderr write is blocked. Also remove an error parsing print since reason generated were wrong and duplicate. (r:2d6161e8) embedded languages: Provide core level support for conditional Set Global Variable (r:c017c24b/FSCORE-612) embedded languages: add insertFile front end to switch_ivr_insert_file and reswig (r:c4e350ab) lang: Improve French phrase files (FSCONFIG-23) @@ -188,11 +207,14 @@ freeswitch (1.0.7) libesl: Make last_event pointer last longer (r:a15f51d5/ESL-37) libesl: use a packet buffer for ESL (r:2081bf97) libesl: Noevent/Noevents disparity (r:d29d83d7/ESL-53) + libesl: FS-2957 esl lib on windows fails to build (r:5254df04/FS-2957) + libesl: Small fix on ESL that cause event_id to be set wrong on headers that had value failure. (r:eb88304a) libfreetdm: implemented freetdm config nodes and ss7 initial configuration libfreetdm: fix codec for CAS signaling (r:b76e7f18) libfreetdm: freetdm: ss7- added support for incoming group blocks, started adding support for ansi (r:c219a73c) libg7221: A bunch of tweaks to the G.722.1 codec (r:5d548570) libgnutls: link to libgcrypt as well, please report any platforms this breaks, but it should be portable (r:c569fb0f/FS-1248) + libjs: non-portable comment syntax in .s files libopenzap: Add CLI tracing libs: Merged OpenZAP and FreeTDM into the FreeSWITCH tree. libs: Add support for TLS on Windows using openssl (r:1abe3b93/MODSOFIA-92) @@ -207,6 +229,7 @@ freeswitch (1.0.7) libspandsp: Fix Windows build after libspandsp update (r:d70cc852/FSBUILD-293) libspandsp: Fix for T.30 processing of operator interrupts, to improve compatibility with some machines, which seem to send them when no operator is around. (r:84ee0ae6) libspandsp: spandsp t38 fax receiving error in win XP - regression from f029f7ef (r:761cec8f/FS-2766) + libspandsp: Added missing error codes when an ECM FAX is abandoned with the T30_ERR message (r:ec57dc7a) mod_avmd: Initial check in - Advanced Voicemail Detect (r:10c6a30a) (by Eric Des Courtis) mod_avmd: Add to windows build (r:df4bd935) mod_avmd: Fix mem leak (r:cd951384/FS-2839) @@ -229,8 +252,12 @@ freeswitch (1.0.7) mod_callcenter: Fix bad return type so it compile on archlinux, thx bougyman (r:3a475986) mod_callcenter: Make callcenter_config agent get return the value of the item requested. Also added queue param max-wait-time-with-no-agent-time-reached: If the max-wai-time-with-no-agent is already reached for the queue, then new caller can wait for x amount of second before it kicked out of the queue rather than get rejected automatically. (r:81a03869) mod_callcenter: Add new event socket agent-offering. Plus some documentation and better handling of bad agent type -- FS-2869 (r:80174cf3/FS-2869) + mod_callcenter: Add error response for queue load and queue reload (FS-2988) (r:49a5effc/FS-2988) mod_cdr_sqlite: initial commit (r:f625fe3b) mod_cdr_sqlite: config file for mod_cdr_sqlite (r:25bc8fe3) + mod_cdr_sqlite: Drop transaction BEGIN/END around INSERT. We're only executing one command, and autocommit will automatically rollback if the INSERT fails. Sync state_handlers with mod_cdr_csv. Minor libpq fixups. (r:0f95b870) + mod_celt: Bump celt to 0.10.0 (r:231fbe5e) + mod_celt: update code in mod_celt to match API of 0.10.0 (r:6e4c30ea) mod_cidlookup: null xml is bad (r:095815f8) mod_cid_lookup: honor skipcitystate when using whitepages (r:a66654de/FSMOD-53) mod_commands: make break uuid_break and add cascade flag @@ -252,6 +279,7 @@ freeswitch (1.0.7) mod_commands: Dramatic jitterbuffer changes (r:d5470961) mod_commands: add uuid_buglist to fetch the current media-bugs attached to a given session uuid (r:f6eab64c) mod_commands: add recovery_refresh app and api and use it in mod_conference to send a message to the channel telling it to sync its recovery snapshot (r:650393fb) + mod_commands: add moh by default to uuid_broadcast when only broadcasting to A leg use aleg arg to disable this (r:d164a797) mod_conference: Fix reporting of volume up/down (MODAPP-419) mod_conference: add last talking time per member to conference xml list mod_conference: add terminate-on-silence conference param @@ -265,6 +293,10 @@ freeswitch (1.0.7) mod_conference: Add a chan var conference_enter_sound to override conference enter-sound param on the profile (r:651acc62) mod_conference: Add an unique id to the conference obj so that we can track conferences. (r:479f3de2) mod_conference: Fix corrupted audio when playing "you are now (un)muted..." (r:10257c7d/FS-2768) + mod_conference: clear last_transferred conference when you exit the conference app (r:fb017a52) + mod_conference: Add energy level to conference_add_event_member_data (r:8d6d52e0) + mod_conference: if more digits than the length of the correct pin the remaining digits are accounted for next retry (r:b88cd345/FS-3000) + mod_conference: Fix unexpected behavior with endconf and auto-outcalls and pre_answer (r:6f58e6aa/FS-2771) mod_curl: use method=post when post requested (r:c6a4ddd0/FSMOD-69) mod_db: fix stack corruption (MODAPP-407) mod_dialplan_xml: Add in the INFO log the caller id number when processing a request (Currenly only show the caller name) (r:e1df5e13) @@ -282,12 +314,16 @@ freeswitch (1.0.7) mod_dptools: refactor export code and add new bridge_export app which is like export but exports across when one channel bridges another (r:4aa9a838) mod_dptools: add bind_digit_action application (r:9537197b) mod_dptools: emit event when user presses DTMFs (r:37298f56) + mod_dptools: Log error when there's no IVR menus configured when you call 'ivr' DP app (r:30034891) + mod_easyroute: Fix possible segfaults and memory leak during unload, and add new setting odbc-retries (r:7fbc47f8/FS-2973) mod_erlang_event: Make XML fetch reply ACKs distinguishable, update freeswitch.erl (r:9d44ed04) mod_erlang_event: Add 3 new commands; session_event, session_noevents, session_nixevent (r:698fa045) mod_erlang_event: generate long node names the same as erlang does (r:9ad509c2) mod_erlang_event: Improve some logging to include UUIDs (r:c0d51b83) mod_erlang_event: Support for reading erlang cookie from a file (r:094ffe37) mod_erlang_event: Rewrite XML fetch conditional wait to be more sane (Reported by James Aimonetti) (r:6941c6eb/FS-2775) + mod_erlang_event: Don't urlencode events (and destroy an event after use) (r:4eccdfef) + mod_erlang_event Add proper locking for the list of XML bindings (r:9fe440b2) mod_event_socket: fix up other users of switch_event_xmlize() to use SWITCH_EVENT_NONE (r:d6eb7562) mod_event_socket: Fix small mem leaks (r:e4f90584/MODEVENT-68) mod_event_socket: Add "-ERR" to api cmd response when failure occurs (r:58759052/FS-2827) @@ -301,6 +337,8 @@ freeswitch (1.0.7) mod_fifo: add outbound_ring_timeout param to mod_fifo (r:3885eea7) mod_fifo: add default_lag to fifo (r:dd4fb5be) mod_fifo: Fix crash when using fifo_destroy_after_use (r:ee562c82/FS-2879) + mod_fifo: don't seg in edge case error conditions (r:9ee13b72) + mod_fifo: set tracking data before enabling hooks (r:34267869) mod_freetdm: Fix for TON and NPI not passed through to channel variables on incoming calls mod_freetdm: add pvt data to freetdm channels fix fxs features (r:9d456900) mod_freetdm: export and import boost custom data (r:edb2d582) @@ -334,6 +372,7 @@ freeswitch (1.0.7) mod_freetdm: created cmake files for freetdm (r:fc55997b) mod_freetdm: ss7 - added support to control mtp2, mtp3, and isup timers via freetdm.conf.xml (r:4455d581) mod_freetdm: made ftmod_r2 use FTDM_SPAN_USE_SIGNALS_QUEUE and properly send FTDM_SIGEVENT_SIGSTATUS_CHANGED (r:af5f0a4a) + mod_fsk: add mod_fsk (r:fcc912a9) mod_gsmopen: copy from branch mod_gsmopen: fix FS-2793, compilation stops (r:355c0dbb/FS-2793) mod_gsmopen: retry serial initialization if failed, zeroing audio buffers, slower retry on soundcard busy (EAGAIN) (r:c7aefe93) @@ -351,6 +390,7 @@ freeswitch (1.0.7) mod_hash: use 5 seconds connection timeouts for remote connections (r:7431fbe9) mod_hash: use esl_recv_timed with a 5000ms timeout when doing api commands (r:27d8378f) mod_hash: limit_remote_thread sending invalid handle to esl_connect_timeout causing core (r:6cdd3e2a/MODAPP-446) + mod_hash: avoid scheduler caling a function on null hash during shutdown (r:8458adeb) mod_h323: initial t.38 support. remake logical channel opening. add missing param name in example config. (r:8c58074c) mod_h323: some t.38 and lockinng improvements. replace ptrace with switch_log_printf. (r:5efe5c88) mod_h323: add missing conf prameter (r:0b353d7a) @@ -379,6 +419,8 @@ freeswitch (1.0.7) mod_lua: Made 2nd arg to freeswitch.Dbh:query (cb func) optional (r:87db11af) mod_lua: Added SAF_ROUTING_EXEC flag to lua app, so it can be run inline (r:7d5ca1c0) mod_lua: spelling error in -ERR return code encounterd -> encountered (r:86e7cdc5/FS-2949) + mod_lua: Make dbh:connected accessible from Lua - thanks Grmt (r:09e6fd3f) + mod_lua: Added optional core: prefix to first arg passed to freeswitch.Dbh for giving direct access to sqlite db (r:a0181479) mod_managed: Added wrapper for switch_event_bind for .net (r:a5f07a80/MODLANG-165) mod_managed: add additional support (r:5be58aac) mod_managed: add mono 2.8 patch file see FS-2774 (r:6a948bd9/FS-2774) @@ -442,6 +484,7 @@ freeswitch (1.0.7) mod_snapshot: fix bad codepaths in mod_snapshot (r:844ac220) mod_sndfile: Add support for .alaw and .ulaw to mod_sndfile (r:facf09b8/MODFORM-41) mod_sndfile: return break in mod_sndfile when seek returns failure (r:564dc7e4) + mod_snmp: initial checkin of mod_snmp (r:6e2b1bd3) mod_sofia: Send SIP MESSAGE to unregistered users by prefixing sip: to user@domain mod_sofia: fix callee being updated with callee information mod_sofia: set appearance-index in update statement for SLA @@ -548,6 +591,20 @@ freeswitch (1.0.7) mod_sofia: improve fail2ban logging (r:f4d52d4c/FS-2943) mod_sofia: refactor sofia_contact to try the profile_name first then the domain to resolve the profile then fall back to querying every profile to reduce confusion with multi-homers (d'oh) also special profile name * will force a search-all situation (r:81608da0) mod_sofia: support allowing pidf-ful presence clients to share the same account and 'appear offline' without influencing each other =/ also refactor the contact generation string based on nat into a helper function (r:97a68c50) + mod_sofia: gateway not identified when extension-in-contact is set (r:7b289941/FS-502) + mod_sofia: Fix erroneous error log on SQL statement (r:2c595a6c/FS-2961) + mod_sofia: Fix routing behavior of inbound calls from gateways that only match gateway based on the gw request uri param (r:0132cd3f) + mod_sofia: don't say we are not for polycom phones (safe rport) when its not really nat (r:9462f53c) + mod_sofia: Set route header as a var on channel like Diversion header (r:d41e6498) + mod_sofia: fix seg related to ptime mismatch + CNG + PLC (if you ever get purple ptime mismatch warnings you want this patch) (r:54de293b) + mod_sofia: be more iOS friendly when using TCP or TLS because the phone never sleeps thus drains the battery (r:159ae989) + mod_sofia: add send-presence-on-register (true|false|first-only) param to sofia and api command sofia global debug [presence|sla|none] + mod_sofia: disable media timeout when encountering a recvonly stream (r:029d68ce) + mod_sofia: fix sofia flush_inbound_reg to work when @domain is given (r:68bf642c) + mod_sofia: fix session timer failure when freeswitch is generating the sdp and there are enough dynamic codecs enabled to conflict with the 2833 pt (4 by default) (r:018a3800) + mod_sofia: Places ;fs_path= within the contact string <...> when using NDLB-connectile-dysfunction-2.0, instead of just appending to the end of the contact string. (r:afc02747/FS-2989) + mod_sofia: Fix handling SUBSCRIBE to "park+" fifo, the NOTIFY data was not being generated from mod_fifo data. (r:3dd9d5c0/FS-3007) + mod_sofia: fsctl pause improvements (r:008e527c/FS-3012) mod_spandsp: initial checkin of mod_fax/mod_voipcodecs merge into mod_spandsp (r:fa9a59a8) mod_spandsp: rework of new mod_spandsp to have functions broken up into different c files (r:65400642) mod_spandsp: improve duplicate digit detection and add 'min_dup_digit_spacing_ms' channel variable for use with the dtmf detector (r:eab4f246/FSMOD-45) @@ -559,6 +616,7 @@ freeswitch (1.0.7) mod_spandsp: deadlock in mod_spandsp (mod_spandsp_fax.c) (r:b02c69bb/FS-1690) mod_spandsp: T.38 reINVITE glare condition causes FAX processing to stop. (r:04aa7ef9/FS-1682) mod_spandsp: improve nat handling when using stun or host as ext-rtp-ip (r:03e74c51/FS-526) + mod_spandsp: Fire event when fax is finished; indicates result of fax attempt (r:314a2a1e/FS-3004) mod_spidermonkey: allow vars to be set containing vars from languages (r:5cd072a3) mod_spidermonkey: fix seg in js hangup (r:7d554c11) mod_spidermonkey: Fix mod_spidermonkey build on FreeBSD, (Undefined symbol PR_LocalTimeParameters). (r:3edb8419) @@ -579,10 +637,14 @@ freeswitch (1.0.7) mod_voicemail: add quotes to vm_cc command generated internally to escape spaces in the caller id name (r:5f012813) mod_voicemail: Play caller id of callee prior to playing a vmail (r:e7b97907/FS-2719) mod_voicemail: FS-1776 Add support for per user operator exten override param vm-operator-extension (r:df5b3498/FS-1776) + mod_voicemail: Set email address from within directory (r:83ce26b2/FS-2972) + mod_voicemail: add events for record/change greeting and record name (r:54421f59) + mod_voicemail: let vmain-key and operator-key be set empty (r:de49305a) mod_xml_cdr: add force_process_cdr var to process b leg cdr on a case by case basis when b leg cdr is disabled (XML-17) mod_xml_cdr: add leg param to query string (XML-24) mod_xml_cdr: fix locked sessions (XML-26) mod_xml_cdr: fix minor memory leaks and config bug (r:19253d83/MODEVENT-62) + mod_xml_cdr: Fix prefix-a-leg not respected for url submission (r:ea9021a2/FS-2998) mod_xml_rpc: Fix crash if unauthorized XML RPC is attempted (r:9835395c/FS-184) scripts: added honeypot.pl and blacklist.pl which add extra SIP security options (r:b6a81ba7) scripts: do simple verification to make sure we are getting IP addresses from VoIP abuse blacklist (r:b0049160) From 722b2ce16807e77228f7698275a177af9901ad61 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 15 Feb 2011 19:01:31 -0600 Subject: [PATCH 209/245] FS-3041 --- conf/autoload_configs/modules.conf.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/autoload_configs/modules.conf.xml b/conf/autoload_configs/modules.conf.xml index 8b4a4e7ea4..0e485b24e3 100644 --- a/conf/autoload_configs/modules.conf.xml +++ b/conf/autoload_configs/modules.conf.xml @@ -52,6 +52,7 @@ + From 5f2857b8b8e2d426f9b442e5afb9a26997635330 Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 16 Feb 2011 08:36:40 -0600 Subject: [PATCH 210/245] use the correct URI on endpoints behind nat --- src/mod/endpoints/mod_sofia/sofia_presence.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 3755894cb8..df472f2f56 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -190,16 +190,8 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co dup_dest = strdup(dst->contact); - if (switch_stristr("fs_path", dst->contact)) { - const char *s; - - if ((s = switch_stristr("fs_path=", dst->contact))) { - s += 8; - } - if (s) { - remote_host = strdup(s); - switch_url_decode(remote_host); - } + if (dst->route_uri) { + remote_host = strdup(dst->route_uri); if (!zstr(remote_host)) { switch_split_user_domain(remote_host, NULL, &remote_ip); } From de707ab7f158a56e09ebab1ef835ad7fe6686c3b Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 16 Feb 2011 08:45:17 -0600 Subject: [PATCH 211/245] comment out --- src/mod/endpoints/mod_sofia/sofia_presence.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index df472f2f56..a8d3b84b0a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -232,9 +232,11 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co status = SWITCH_STATUS_SUCCESS; + /* if ((p = strstr(contact, ";fs_"))) { *p = '\0'; } + */ /* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */ From 0d8e945bd1588650051dca407e6e3e3ff90698e9 Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 16 Feb 2011 08:57:43 -0600 Subject: [PATCH 212/245] doh --- src/mod/endpoints/mod_sofia/sofia_presence.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index a8d3b84b0a..89eb1ae948 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -80,7 +80,6 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co char *ffrom = NULL; nua_handle_t *msg_nh; char *contact = NULL; - char *p; char *dup = NULL; switch_status_t status = SWITCH_STATUS_FALSE; const char *ct = "text/html"; From d4068d9755fb65d4a2f21b983cc882fbc7c8b0b1 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 16 Feb 2011 11:06:26 -0500 Subject: [PATCH 213/245] freetdm: Removed ftmod_sangoma_boost --- libs/freetdm/Makefile.am | 21 - libs/freetdm/configure.ac | 3 +- .../ftmod_sangoma_boost/BOOST.limitations | 20 - .../ftmod/ftmod_sangoma_boost/boost-tasks.txt | 146 - .../ftmod_sangoma_boost/ftdm_sangoma_boost.h | 75 - .../ftmod_sangoma_boost.2008.vcproj | 373 --- .../ftmod_sangoma_boost.2010.vcxproj | 206 -- .../ftmod_sangoma_boost.2010.vcxproj.filters | 35 - .../ftmod_sangoma_boost/ftmod_sangoma_boost.c | 2730 ----------------- .../sangoma_boost_client.c | 589 ---- .../sangoma_boost_client.h | 164 - .../sangoma_boost_interface.h | 254 -- .../src/ftmod/ftmod_sangoma_boost/sigboost.h | 221 -- 13 files changed, 1 insertion(+), 4836 deletions(-) delete mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_boost/BOOST.limitations delete mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_boost/boost-tasks.txt delete mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h delete mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2008.vcproj delete mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj delete mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj.filters delete mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c delete mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.c delete mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.h delete mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_interface.h delete mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_boost/sigboost.h diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am index b3353f32de..a26035b2ef 100644 --- a/libs/freetdm/Makefile.am +++ b/libs/freetdm/Makefile.am @@ -39,7 +39,6 @@ libdir = @libdir@ library_includedir = $(prefix)/include INCS = -I$(FT_SRCDIR)/$(SRC)/include -I$(FT_SRCDIR)/$(SRC)/include/private -INCS += -I$(FT_SRCDIR)/$(SRC)/ftmod/ftmod_sangoma_boost if HAVE_SNG_SS7 INCS += -I/usr/include/sng_ss7 @@ -109,7 +108,6 @@ core-install: install-libLTLIBRARIES # tools & test programs # noinst_PROGRAMS = testtones detect_tones detect_dtmf testpri testr2 testanalog testapp testcid -noinst_PROGRAMS += testsangomaboost testapp_SOURCES = $(SRC)/testapp.c testapp_LDADD = libfreetdm.la @@ -143,17 +141,6 @@ testr2_SOURCES = $(SRC)/testr2.c testr2_LDADD = libfreetdm.la testr2_CFLAGS = $(AM_CFLAGS) $(FTDM_CFLAGS) -if HAVE_SCTP -noinst_PROGRAMS += testboost -testboost_SOURCES = $(SRC)/testboost.c -testboost_LDADD = libfreetdm.la -testboost_CFLAGS = $(AM_CFLAGS) $(FTDM_CFLAGS) -endif - -testsangomaboost_SOURCES = $(SRC)/testsangomaboost.c -testsangomaboost_LDADD = libfreetdm.la -testsangomaboost_CFLAGS = $(AM_CFLAGS) $(FTDM_CFLAGS) - testanalog_SOURCES = $(SRC)/testanalog.c testanalog_LDADD = libfreetdm.la testanalog_CFLAGS = $(AM_CFLAGS) $(FTDM_CFLAGS) @@ -201,14 +188,6 @@ ftmod_isdn_la_LDFLAGS = -shared -module -avoid-version $(LIBISDN_LDFLAGS) $(PCA ftmod_isdn_la_LIBADD = libfreetdm.la $(LIBISDN_LIBS) $(PCAP_LIBS) endif -if HAVE_SCTP -mod_LTLIBRARIES += ftmod_sangoma_boost.la -ftmod_sangoma_boost_la_SOURCES = $(SRC)/ftmod/ftmod_sangoma_boost/sangoma_boost_client.c $(SRC)/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c -ftmod_sangoma_boost_la_CFLAGS = $(AM_CFLAGS) $(FTDM_CFLAGS) -ftmod_sangoma_boost_la_LDFLAGS = -shared -module -avoid-version -ftmod_sangoma_boost_la_LIBADD = libfreetdm.la -endif - if HAVE_LIBPRI mod_LTLIBRARIES += ftmod_libpri.la ftmod_libpri_la_SOURCES = $(SRC)/ftmod/ftmod_libpri/ftmod_libpri.c $(SRC)/ftmod/ftmod_libpri/lpwrap_pri.c diff --git a/libs/freetdm/configure.ac b/libs/freetdm/configure.ac index 1f4fc9c6ac..38f849b9e6 100644 --- a/libs/freetdm/configure.ac +++ b/libs/freetdm/configure.ac @@ -121,8 +121,7 @@ AC_CHECK_LIB([dl], [dlopen]) AC_CHECK_LIB([pthread], [pthread_create]) AC_CHECK_LIB([m], [cos]) -AC_CHECK_HEADERS([netinet/sctp.h netdb.h sys/select.h]) -AM_CONDITIONAL([HAVE_SCTP],[test "${ac_cv_header_netinet_sctp_h}" = "yes"]) +AC_CHECK_HEADERS([netdb.h sys/select.h]) AC_CHECK_FUNC([gethostbyname_r], [], [AC_CHECK_LIB([nsl], [gethostbyname_r])] diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/BOOST.limitations b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/BOOST.limitations deleted file mode 100644 index 663b7d376a..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/BOOST.limitations +++ /dev/null @@ -1,20 +0,0 @@ -== Boost sigmod current limitations == -- we don't support having openzap spans with physical channels - belonging to other physical spans. this is due to netborder sangoma abstraction, therefore - any openzap span using sigboost must have only channels belonging to the corresponding - physical span. - - This is the reason we added group functionality in openzap core, furthermore, previous groups in openzap - were only possible through adding of b-channels to a single span, but this forces the user to create groups - of channels only whithin the same type of trunk among other things. - -- all spans must be configured and then started, cannot configure, start, configure start etc - this is due to netborder telesoft abstraction. that requires configuring everything and - then starting everything at once. - -- sangoma_prid and sangoma_brid on Windows had to be compiled hacking make/Makefile.platform to comment all VC runtime checks, - otherwise when running in debug mode exceptions are thrown due to loss of data ie short to char conversions. - -== TODO == -- proper upper layer management of HW alarms (this must be done in mod_openzap.c) - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/boost-tasks.txt b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/boost-tasks.txt deleted file mode 100644 index f0eab3a277..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/boost-tasks.txt +++ /dev/null @@ -1,146 +0,0 @@ -== General Design == - -NBE will do its current loading of spans and configuration process through Sangoma Board Manager (SBM). -After doing SangomaBoardManager::getInstance().configure -> start. It will proceed to initalize -the openzap stack (just as the TelesoftStack is loaded after starting SMB. The procedure will be: - -- create a static or malloced zap_io_interface_t -- call zap_global_set_logger with the logging hooks. -- call zap_global_set_memhandler() with the memory hooks. -- call zap_global_init() to initialize the stack -- call zap_add_io_iface() to add the I/O iface. -- iterate over all SBM spans configured for BRI or any boost-managed signaling and: - * call zap_span_create(NBE I/O mod, in_ptrSpan, SMB span name) - * Fill in some members like: - span->trunk_type = E1/T1/J1/FXO/FXS etc ... - * iterate over all channels in SMB span and: - * zap_span_add_channel(zap_span, sock, type:CAS|BCHAN|DCHAN|ETC) - * call zap_configure_span("sangoma_boost", span, sigmsg_callback, "param1", value1, "param2", value1 ...) - * zap_span_start(span); - - -At this point, NBE would receive signaling msgs via sigmsg_callback registered when configuring -and NBE would request hangup or making calls throug openzap API, like zap_set_state_* and zap_channel_outgoing_call() to place calls. - -When NBE wants to check for link status. - - zap_get_siglink_state() which would return - ZAP_SIG_STATE_UP (D-chan UP, R2 bits in IDLE, ss7?) - ZAP_SIG_STATE_SUSPENDED (D-chan in power saving mode?) - ZAP_SIG_STATE_DOWN (D-chan down, R2 bits in blocked, ss7?) - - Whenever a state in sig link changes, the sigmsg_callback will be used to notify NBE or any other user. - -NOTE: right now hardware alarms notification in openzap is seriously broken, -see ozmod_libpri.c process_event ... reads an event from hardware (zap_event_t *), -then checks the event type, if its ZAP_OOB_ALARM_TRAP prepares a zap_sigmsg_t -(signaling event) setting its event_id to ZAP_OOB_ALARM_TRAP, which is *WRONG* -because event_id is of type zap_signal_event_t and not zap_oob_event_t! -this means on alarm the user will get ZAP_SIGEVENT_PROGRESS_MEDIA!! which is -value 7 that is in conflict with ZAP_OOB_ALARM_TRAP, I think a separate -callback should be used if the outside user wants to be notified about -hardware events like HW DTMF or so. Currently there is alreadya generic DTMF -listener. - -== Tasks Stage 1 / OpenZAP and Boost changes (To be tested with FreeSWITCH) == - -- Change malloc and other mem functions in openzap - to use internal hooks provided via zap_global_set_memhandler() - which would be called before zap_global_init(), this is - already done for the logger via zap_global_set_logger() - - question: should the mem routines allow for memory pool ptr? - this could be useful to provide a memory pool to - the whole module. - - question: should we allow hooks for threads and locking? - I think we can skip this one unless needed. They already - use their own threading abstraction which is working for - Linux and Windows. If we ever need to profile threading - we can add profiling hooks. - - question: I had to add openzap calls to the hash table and libteletone implementations, is that acceptable? - -- Modify zap_global_init() API - - This API must just initialize vars, mutexes etc. - and NOT DO ANY CONFIGURATION LOADING, PARSING, SPAN CREATION and I/O - configuration, which is what is currently doing. - We don't want zap_global_init() to create the spans based on that configuration - since NBE will have its own configuration and will take care of creating - the needed data structures on its own. - -- Add new zap_std_io_config() API - - This API will parse the standard openzap.conf module and create the spans. - This will be used by FS but not by NBE, which will create the openzap spans by itself. - The NBE flow to initialize openzap will be: - -- Add new API zap_global_add_io_iface(), - - This API will add a new I/O interface structure to the internal openzap hash of I/O structs. - This is needed because NBE I/O structure will NOT be loaded from an openzap module (.so/.dll) - but rather just registered on runtime (probably from a static structure in NBE code). - This openzap hash is used by zap_api_execute() for example, to find the module that can - handle a given API, ie (oz libpri status). This is an example of how an openzap I/O interface - can decide to implement just the ->api() member to handle commands and NOTHING else, - so I/O interfaces not necessary are hardware-related. - -- Add new zap_channel_get_siglink_state(zap_channel, zap_siglink_status_t &status) - -- Modify mod_openzap.c to read proto= setting in boost spans, this will determine wich boost sig - module will handle the configuration and those channels. - - - - Then as first config arg to zap_config_span() the boost proto module name would be included as "sigmod" which will be used - by ozmod_sangoma_boost to decide which sig module must handle that span configuration - -- Create minimal boost mod interface. - - ozmod_boost_ss7 should load sig boost mods and get interface via dlsym(boost_get_interface) boost_get_interface(boost_iface); - The boost interface will have - * const char *name // boost sigmod name (brid,ss7d) - * set_write_boost_msg_cb(callback) // tell the stack how to send us boost messages - * set_sig_status_cb(callback); // tell the stack how to notify us about link status changes - * write_boost_msg(struct boost_msg) // send a boost msg to the stack - * configure_span(zap_span_t span, "configuration", value, "configuration", value) // configure a given span - * get_sig_status(openzap_sigstatus_t status) - * start(span) // to start a given openzap span - * stop(span) // to stop the stack on a given openzap span - -- Migrate current sangoma_brid sig module to openzap - * Make sangoma_brid a library - * Move from using malloc, threading, locking, logging and I/O to openzap functions. Export the boost sigmod interface and its supporting code. - -== State 2 Tasks == - -- Create the I/O NBE interface and supporting functions. It must be possible to poll over the span - given that ozmod_sangoma_boost BRI module and others may need to *wait* for data. The poll() - function in I/O NBE interface would wait on a pthread condition or Windows event, which would - be triggered by some external NBE component registered with Sangoma Board Manager (SMB) for d-chan - data, whenever d-chan data arrives, saves the data in a buffer and triggers the condition to wakeup - any waiter, then the waiter (sangoma_brid or any other boost client) calls zap_channel_read which calls - our own I/O NBE interface read method and retrieves the data from the buffer. - - Dropped alternative design: - Another option is to add a new API zap_span_push_incoming_data(span/chan, data); However this changes - the model openzap has followed and I don't think fits that well, since now we have 2 different models - to support in openzap. - -== TODO == - -- how about logging specific modules, like, just ozmod_boost, or just the BRI stack? - more work to be done so the BRI module uses zap_log instead of current syslog - then work to be done to be able to filter logs from specific openzap code? is it worth it? - -- remove FORCE_SEGFAULT from sprid - - -=== Shortcomings == - -- we had to drop smg support in the branch where we work on sangoma prid. - After all, most people using sangoma_prid is using freeswitch/openzap and not Sangoma Media Gateway - The problem is in freeswitch/openzap mode, sangoma_boost ozmod takes care of span events (POLLPRI) - where in SMG and Netborder POLLPRI is done typically by sangoma board manager. - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h deleted file mode 100644 index 6fbf272d07..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2007, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FTDM_SANGOMA_BOOST_H -#define FTDM_SANGOMA_BOOST_H -#include "sangoma_boost_client.h" -#include "freetdm.h" - -#define MAX_CHANS_PER_TRUNKGROUP 1024 - -typedef enum { - FTDM_SANGOMA_BOOST_RUNNING = (1 << 0), - FTDM_SANGOMA_BOOST_RESTARTING = (1 << 1), - FTDM_SANGOMA_BOOST_EVENTS_RUNNING = (1 << 2), -} ftdm_sangoma_boost_flag_t; - -typedef struct ftdm_sangoma_boost_data { - sangomabc_connection_t mcon; - sangomabc_connection_t pcon; - int iteration; - uint32_t flags; - boost_sigmod_interface_t *sigmod; - ftdm_queue_t *boost_queue; -} ftdm_sangoma_boost_data_t; - -typedef struct ftdm_sangoma_boost_trunkgroup { - ftdm_mutex_t *mutex; - ftdm_size_t size; /* Number of b-channels in group */ - unsigned int last_used_index; /* index of last b-channel used */ - ftdm_channel_t* ftdmchans[MAX_CHANS_PER_TRUNKGROUP]; - //TODO need to merge congestion timeouts to this struct -} ftdm_sangoma_boost_trunkgroup_t; -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2008.vcproj deleted file mode 100644 index 73e421818f..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2008.vcproj +++ /dev/null @@ -1,373 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 deleted file mode 100644 index 684e4326cb..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj +++ /dev/null @@ -1,206 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - ftmod_sangoma_boost - {D021EF2A-460D-4827-A0F7-41FDECF46F1B} - ftmod_sangoma_boost - Win32Proj - - - - DynamicLibrary - Unicode - true - - - DynamicLibrary - Unicode - - - DynamicLibrary - Unicode - true - - - DynamicLibrary - Unicode - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(SolutionDir)$(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(SolutionDir)$(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(SolutionDir)$(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - Disabled - ..\..\include;..\..\isdn\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level4 - true - EditAndContinue - 4100;%(DisableSpecificWarnings) - - - %(AdditionalDependencies) - $(OutDir);%(AdditionalLibraryDirectories) - true - Windows - MachineX86 - - - - - MaxSpeed - true - ..\..\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level4 - true - ProgramDatabase - 4100;%(DisableSpecificWarnings) - - - true - Windows - true - true - MachineX86 - - - - - X64 - - - Disabled - ..\..\include;..\..\isdn\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level4 - true - ProgramDatabase - 4100;%(DisableSpecificWarnings) - - - %(AdditionalDependencies) - $(OutDir);%(AdditionalLibraryDirectories) - true - Windows - MachineX64 - - - - - X64 - - - MaxSpeed - true - ..\..\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level4 - false - ProgramDatabase - 4100;%(DisableSpecificWarnings) - - - true - Windows - true - true - MachineX64 - - - - - - - - - - - - - - - {93b8812c-3ec4-4f78-8970-ffbfc99e167d} - false - - - - - - \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj.filters deleted file mode 100644 index 2aeed155cd..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj.filters +++ /dev/null @@ -1,35 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c deleted file mode 100644 index d0bc14c8d8..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ /dev/null @@ -1,2730 +0,0 @@ -/* - * Copyright (c) 2007, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Moises Silva - * David Yat Sin - * Nenad Corbic - * - */ - -/* NOTE: -On __WINDOWS__ platform this code works with sigmod ONLY, don't try to make sense of any socket code for win -I basically ifdef out everything that the compiler complained about -*/ - -#include "private/ftdm_core.h" -#include "sangoma_boost_client.h" -#include "ftdm_sangoma_boost.h" -#ifdef HAVE_SYS_SELECT_H -#include -#endif - -/* Boost signaling modules global hash and its mutex */ -ftdm_mutex_t *g_boost_modules_mutex = NULL; -ftdm_hash_t *g_boost_modules_hash = NULL; - -#define MAX_TRUNK_GROUPS 64 -//TODO need to merge congestion_timeouts with ftdm_sangoma_boost_trunkgroups -static time_t congestion_timeouts[MAX_TRUNK_GROUPS]; - -static ftdm_sangoma_boost_trunkgroup_t *g_trunkgroups[MAX_TRUNK_GROUPS]; - -static ftdm_io_interface_t ftdm_sangoma_boost_interface; -static ftdm_status_t ftdm_sangoma_boost_list_sigmods(ftdm_stream_handle_t *stream); - -#define BOOST_QUEUE_SIZE 500 - -/* get freetdm span and chan depending on the span mode */ -#define BOOST_SPAN(ftdmchan) ((ftdm_sangoma_boost_data_t*)(ftdmchan)->span->signal_data)->sigmod ? ftdmchan->physical_span_id : ftdmchan->physical_span_id-1 -#define BOOST_CHAN(ftdmchan) ((ftdm_sangoma_boost_data_t*)(ftdmchan)->span->signal_data)->sigmod ? ftdmchan->physical_chan_id : ftdmchan->physical_chan_id-1 - -/** - * \brief SANGOMA boost notification flag - */ -typedef enum { - SFLAG_SENT_FINAL_MSG = (1 << 0), - SFLAG_SENT_ACK = (1 << 1), - SFLAG_RECVD_ACK = (1 << 2), - SFLAG_HANGUP = (1 << 3), - SFLAG_TERMINATING = (1 << 4) -} sflag_t; - -typedef uint16_t sangoma_boost_request_id_t; - -/** - * \brief SANGOMA boost request status - */ -typedef enum { - BST_FREE, - BST_WAITING, - BST_READY, - BST_FAIL -} sangoma_boost_request_status_t; - -/** - * \brief SANGOMA boost request structure - */ -typedef struct { - sangoma_boost_request_status_t status; - sangomabc_short_event_t event; - ftdm_span_t *span; - ftdm_channel_t *ftdmchan; - int hangup_cause; - int flags; -} sangoma_boost_request_t; - -typedef struct { - int call_setup_id; - int last_event_id; -} sangoma_boost_call_t; - -#define CALL_DATA(ftdmchan) ((sangoma_boost_call_t*)((ftdmchan)->call_data)) - -//#define MAX_REQ_ID FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN * FTDM_MAX_CHANNELS_PHYSICAL_SPAN -#define MAX_REQ_ID 6000 - -static uint16_t SETUP_GRID[FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN+1][FTDM_MAX_CHANNELS_PHYSICAL_SPAN+1] = {{ 0 }}; - -static sangoma_boost_request_t OUTBOUND_REQUESTS[MAX_REQ_ID+1] = {{ 0 }}; - -static ftdm_mutex_t *request_mutex = NULL; - -static uint8_t req_map[MAX_REQ_ID+1] = { 0 }; -static uint8_t nack_map[MAX_REQ_ID+1] = { 0 }; - -/** - * \brief Releases span and channel from setup grid - * - * \note This is ALWAYS based on freetdm span/chan numbers! not boost event numbers - * is totally brain damaged to use event->span or event->chan to release the request - * use BOOST_SPAN_EVENT and BOOST_SPAN_CHAN to get the right index!! - * - * \param span Span number - * \param chan Channel number - * \param func Calling function - * \param line Line number on request - * \return NULL if not found, channel otherwise - */ -static void __release_request_id_span_chan(int span, int chan, const char *func, int line) -{ - int id; - - ftdm_mutex_lock(request_mutex); - if ((id = SETUP_GRID[span][chan])) { - ftdm_assert(id <= MAX_REQ_ID, "Invalid request id\n"); - req_map[id] = 0; - SETUP_GRID[span][chan] = 0; - } - ftdm_mutex_unlock(request_mutex); -} -#define release_request_id_span_chan(s, c) __release_request_id_span_chan(s, c, __FUNCTION__, __LINE__) - -/** - * \brief Releases request ID - * \param func Calling function - * \param line Line number on request - * \return NULL if not found, channel otherwise - */ -static void __release_request_id(sangoma_boost_request_id_t r, const char *func, int line) -{ - ftdm_assert(r <= MAX_REQ_ID, "Invalid request id\n"); - ftdm_mutex_lock(request_mutex); - req_map[r] = 0; - ftdm_mutex_unlock(request_mutex); -} -#define release_request_id(r) __release_request_id(r, __FUNCTION__, __LINE__) - -static sangoma_boost_request_id_t last_req = 0; - -/** - * \brief Gets the first available tank request ID - * \param func Calling function - * \param line Line number on request - * \return 0 on failure, request ID on success - */ -static sangoma_boost_request_id_t __next_request_id(const char *func, int line) -{ - sangoma_boost_request_id_t r = 0, i = 0; - int found=0; - - ftdm_mutex_lock(request_mutex); - //r = ++last_req; - //while(!r || req_map[r]) { - - for (i=1; i<= MAX_REQ_ID; i++){ - r = ++last_req; - - if (r >= MAX_REQ_ID) { - r = last_req = 1; - } - - if (req_map[r]) { - /* Busy find another */ - continue; - - } - - req_map[r] = 1; - found=1; - break; - - } - - ftdm_mutex_unlock(request_mutex); - - if (!found) { - return 0; - } - - return r; -} -#define next_request_id() __next_request_id(__FUNCTION__, __LINE__) - - -static void print_request_ids(void) -{ - sangoma_boost_request_id_t i = 0; - int cnt=0; - - ftdm_mutex_lock(request_mutex); - - for (i=1; i<= MAX_REQ_ID; i++){ - if (req_map[i]) { - ftdm_log(FTDM_LOG_CRIT, "Used Request ID=%i\n",i); - cnt++; - } - } - - ftdm_mutex_unlock(request_mutex); - ftdm_log(FTDM_LOG_CRIT, "Total Request IDs=%i\n",cnt); - - return; -} - - -/** - * \brief Finds the channel that triggered an event - * \param span Span where to search the channel - * \param event SANGOMA event - * \param force Do not wait for the channel to be available if in use - * \return NULL if not found, channel otherwise - */ -static ftdm_channel_t *find_ftdmchan(ftdm_span_t *span, sangomabc_short_event_t *event, int force) -{ - uint32_t i; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - uint32_t targetspan = BOOST_EVENT_SPAN(sangoma_boost_data->sigmod, event); - uint32_t targetchan = BOOST_EVENT_CHAN(sangoma_boost_data->sigmod, event); - - /* NC: Sanity check in case the call setup id does not relate - to span. This can happen if RESTART is received on a - full load. Where stray ACK messages can arrive after - a RESTART has taken place. - */ - if (!span) { - ftdm_log(FTDM_LOG_CRIT, "No Span for Event=%s s%dc%d cid=%d\n", - BOOST_DECODE_EVENT_ID(event->event_id), - targetspan, - targetchan, - event->call_setup_id); - return NULL; - } - - - for(i = 1; i <= span->chan_count; i++) { - if (span->channels[i]->physical_span_id == targetspan && span->channels[i]->physical_chan_id == targetchan) { - ftdmchan = span->channels[i]; - if (force || (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE))) { - break; - } else { - ftdmchan = NULL; - ftdm_log(FTDM_LOG_DEBUG, "Channel %d:%d ~ %d:%d is already in use in state %s\n", - span->channels[i]->span_id, - span->channels[i]->chan_id, - span->channels[i]->physical_span_id, - span->channels[i]->physical_chan_id, - ftdm_channel_state2str(span->channels[i]->state)); - break; - } - } - } - - return ftdmchan; -} - -static int check_congestion(int trunk_group) -{ - if (congestion_timeouts[trunk_group]) { - time_t now = time(NULL); - - if (now >= congestion_timeouts[trunk_group]) { - congestion_timeouts[trunk_group] = 0; - } else { - return 1; - } - } - - return 0; -} - - -/** - * \brief Requests an sangoma boost channel on a span (outgoing call) - * \param span Span where to get a channel - * \param chan_id Specific channel to get (0 for any) - * \param direction Call direction - * \param caller_data Caller information - * \param ftdmchan Channel to initialise - * \return Success or failure - */ -static FIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - ftdm_status_t status = FTDM_FAIL; - sangoma_boost_request_id_t r; - sangomabc_event_t event = {0}; - /* sanity has to be more than 8 seconds. - * In PRI specs, timeout is 4 seconds for remote switch to respond to a SETUP, - * and PRI stack will retransmit a second SETUP after the first timeout, so - * we should allow for at least 8 seconds. - */ - - int boost_request_timeout = 10000; - sangoma_boost_request_status_t st; - char dnis[128] = ""; - char *gr = NULL; - uint32_t count = 0; - int tg=0; - - /* NC: On large number of calls 10 seconds is not enough. - Resetting to 30 seconds. Especially on ss7 when - links are reset during large call volume */ - if (!sangoma_boost_data->sigmod) { - boost_request_timeout = 30000; - } - - if (sangoma_boost_data->sigmod) { - ftdm_log(FTDM_LOG_CRIT, "This function should not be called when sigmod was configured in boost\n"); - *ftdmchan = NULL; - return FTDM_FAIL; - } - - if (ftdm_test_flag(span, FTDM_SPAN_SUSPENDED)) { - ftdm_log(FTDM_LOG_CRIT, "SPAN is Suspended.\n"); - *ftdmchan = NULL; - return FTDM_FAIL; - } - - if (check_congestion(tg)) { - ftdm_log(FTDM_LOG_CRIT, "All circuits are busy. Trunk Group=%i (CONGESTION)\n",tg+1); - *ftdmchan = NULL; - return FTDM_FAIL; - } - - if (count >= span->chan_count) { - ftdm_log(FTDM_LOG_CRIT, "All circuits are busy.\n"); - *ftdmchan = NULL; - return FTDM_FAIL; - } - - r = next_request_id(); - if (r == 0) { - ftdm_log(FTDM_LOG_CRIT, "All tanks ids are busy.\n"); - *ftdmchan = NULL; - return FTDM_FAIL; - } - - /* After this point we must release request id before we leave the function - in case of an error. */ - - ftdm_set_string(dnis, caller_data->dnis.digits); - - if ((gr = strchr(dnis, '@'))) { - *gr++ = '\0'; - } - - if (gr && *(gr+1)) { - tg = atoi(gr+1); - if (tg > 0) { - tg--; - } - } - - sangomabc_call_init(&event, caller_data->cid_num.digits, dnis, r); - - event.trunk_group = tg; - - - ftdm_span_channel_use_count(span, &count); - - if (gr && *(gr+1)) { - switch(*gr) { - case 'g': - event.hunt_group = SIGBOOST_HUNTGRP_SEQ_ASC; - break; - case 'G': - event.hunt_group = SIGBOOST_HUNTGRP_SEQ_DESC; - break; - case 'r': - event.hunt_group = SIGBOOST_HUNTGRP_RR_ASC; - break; - case 'R': - event.hunt_group = SIGBOOST_HUNTGRP_RR_DESC; - break; - default: - ftdm_log(FTDM_LOG_WARNING, "Failed to determine huntgroup (%s)\n", gr); - event.hunt_group = SIGBOOST_HUNTGRP_SEQ_ASC; - } - } - - ftdm_set_string(event.calling_name, caller_data->cid_name); - ftdm_set_string(event.rdnis.digits, caller_data->rdnis.digits); - if (strlen(caller_data->rdnis.digits)) { - event.rdnis.digits_count = (uint8_t)strlen(caller_data->rdnis.digits)+1; - event.rdnis.ton = caller_data->rdnis.type; - event.rdnis.npi = caller_data->rdnis.plan; - } - - event.calling.screening_ind = caller_data->screen; - event.calling.presentation_ind = caller_data->pres; - - event.calling.ton = caller_data->cid_num.type; - event.calling.npi = caller_data->cid_num.plan; - - event.called.ton = caller_data->dnis.type; - event.called.npi = caller_data->dnis.plan; - - /* we're making a contract now that FreeTDM values for capability, layer 1 and such will be the same as for boost */ - event.bearer.capability = caller_data->bearer_capability; - event.bearer.uil1p = caller_data->bearer_layer1; - - if (caller_data->raw_data_len) { - ftdm_set_string(event.custom_data, caller_data->raw_data); - event.custom_data_size = (uint16_t)caller_data->raw_data_len; - } - - OUTBOUND_REQUESTS[r].status = BST_WAITING; - OUTBOUND_REQUESTS[r].span = span; - - if (sangomabc_connection_write(&sangoma_boost_data->mcon, &event) <= 0) { - ftdm_log(FTDM_LOG_CRIT, "Failed to tx boost event [%s]\n", strerror(errno)); - status = OUTBOUND_REQUESTS[r].status = FTDM_FAIL; - if (!sangoma_boost_data->sigmod) { - *ftdmchan = NULL; - } - goto done; - } - - while(ftdm_running() && OUTBOUND_REQUESTS[r].status == BST_WAITING) { - ftdm_sleep(1); - if (--boost_request_timeout <= 0) { - status = FTDM_FAIL; - if (!sangoma_boost_data->sigmod) { - *ftdmchan = NULL; - } - ftdm_log(FTDM_LOG_CRIT, "Csid:%d Timed out waiting for boost channel request response, current status: BST_WAITING\n", r); - goto done; - } - } - - if (OUTBOUND_REQUESTS[r].status == BST_READY && OUTBOUND_REQUESTS[r].ftdmchan) { - *ftdmchan = OUTBOUND_REQUESTS[r].ftdmchan; - status = FTDM_SUCCESS; - } else { - status = FTDM_FAIL; - if (!sangoma_boost_data->sigmod) { - *ftdmchan = NULL; - } - } - - done: - - st = OUTBOUND_REQUESTS[r].status; - OUTBOUND_REQUESTS[r].status = BST_FREE; - - if (status == FTDM_FAIL) { - if (st == BST_FAIL) { - caller_data->hangup_cause = OUTBOUND_REQUESTS[r].hangup_cause; - } else { - caller_data->hangup_cause = FTDM_CAUSE_RECOVERY_ON_TIMER_EXPIRE; - } - } - - if (st == BST_FAIL) { - release_request_id(r); - } else if (st != BST_READY) { - ftdm_assert_return(r <= MAX_REQ_ID, FTDM_FAIL, "Invalid index\n"); - nack_map[r] = 1; - if (sangoma_boost_data->sigmod) { - sangomabc_exec_command(&sangoma_boost_data->mcon, - BOOST_SPAN((*ftdmchan)), - BOOST_CHAN((*ftdmchan)), - r, - SIGBOOST_EVENT_CALL_START_NACK, - 0, 0); - } else { - sangomabc_exec_command(&sangoma_boost_data->mcon, - 0, - 0, - r, - SIGBOOST_EVENT_CALL_START_NACK, - 0, 0); - } - } - - return status; -} - -/** - * \brief Starts an sangoma boost channel (outgoing call) - * \param ftdmchan Channel to initiate call on - * \return Success - */ -static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(sangoma_boost_outgoing_call) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - - if (!sangoma_boost_data->sigmod) { - return FTDM_SUCCESS; - } - - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND); - - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DIALING); - - return FTDM_SUCCESS; -} - -/** - * \brief Handler for call start ack no media event - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_call_progress(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan; - - - if ((ftdmchan = find_ftdmchan(span, event, 1))) { - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - ftdm_mutex_lock(ftdmchan->mutex); - if (!sangoma_boost_data->sigmod && ftdmchan->state == FTDM_CHANNEL_STATE_HOLD) { - if ((event->flags & SIGBOOST_PROGRESS_MEDIA)) { - ftdmchan->init_state = FTDM_CHANNEL_STATE_PROGRESS_MEDIA; - ftdm_log(FTDM_LOG_DEBUG, "Channel init state updated to PROGRESS_MEDIA [Csid:%d]\n", event->call_setup_id); - } else if ((event->flags & SIGBOOST_PROGRESS_RING)) { - ftdmchan->init_state = FTDM_CHANNEL_STATE_PROGRESS; - ftdm_log(FTDM_LOG_DEBUG, "Channel init state updated to PROGRESS [Csid:%d]\n", event->call_setup_id); - } else { - ftdmchan->init_state = FTDM_CHANNEL_STATE_IDLE; - ftdm_log(FTDM_LOG_DEBUG, "Channel init state updated to IDLE [Csid:%d]\n", event->call_setup_id); - } - } else { - if ((event->flags & SIGBOOST_PROGRESS_MEDIA)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } else if ((event->flags & SIGBOOST_PROGRESS_RING)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); - } else { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); - } - } - ftdm_mutex_unlock(ftdmchan->mutex); - } -} - -/** - * \brief Handler for call start ack event - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_call_start_ack(sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - - ftdm_channel_t *ftdmchan = NULL; - uint32_t event_span = BOOST_EVENT_SPAN(mcon->sigmod, event); - uint32_t event_chan = BOOST_EVENT_CHAN(mcon->sigmod, event); - - - if (nack_map[event->call_setup_id]) { - /* In this scenario outgoing call was alrady stopped - via NACK and now we are expecting an NACK_ACK. - If we receive an ACK its a race condition thus - ignor it */ - return; - } - - if (mcon->sigmod) { - ftdmchan = OUTBOUND_REQUESTS[event->call_setup_id].ftdmchan; - } else { - ftdmchan = find_ftdmchan(OUTBOUND_REQUESTS[event->call_setup_id].span, event, 0); - } - - - if (ftdmchan) { - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - if (!mcon->sigmod && ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to open FTDM channel [%s]\n", ftdmchan->last_error); - } else { - - /* Only bind the setup id to GRID when we are sure that channel is ready - otherwise we could overwite the original call */ - OUTBOUND_REQUESTS[event->call_setup_id].event = *event; - SETUP_GRID[event_span][event_chan] = event->call_setup_id; - - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND); - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_INUSE); - ftdmchan->sflags = SFLAG_RECVD_ACK; - - if ((event->flags & SIGBOOST_PROGRESS_MEDIA)) { - if (sangoma_boost_data->sigmod) { - ftdm_log(FTDM_LOG_DEBUG, "Channel state changing to PROGRESS_MEDIA [Csid:%d]\n", event->call_setup_id); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } else { - ftdmchan->init_state = FTDM_CHANNEL_STATE_PROGRESS_MEDIA; - ftdm_log(FTDM_LOG_DEBUG, "Channel init state changed to PROGRESS_MEDIA [Csid:%d]\n", event->call_setup_id); - } - } else if ((event->flags & SIGBOOST_PROGRESS_RING)) { - if (sangoma_boost_data->sigmod) { - ftdm_log(FTDM_LOG_DEBUG, "Channel state changing to PROGRESS [Csid:%d]\n", event->call_setup_id); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); - } else { - ftdmchan->init_state = FTDM_CHANNEL_STATE_PROGRESS; - ftdm_log(FTDM_LOG_DEBUG, "Channel init state changed to PROGRESS [Csid:%d]\n", event->call_setup_id); - } - } else { - if (sangoma_boost_data->sigmod) { - /* should we set a state here? */ - } else { - ftdmchan->init_state = FTDM_CHANNEL_STATE_IDLE; - ftdm_log(FTDM_LOG_DEBUG, "Channel init state changed to IDLE [Csid:%d]\n", event->call_setup_id); - } - } - if (!sangoma_boost_data->sigmod) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HOLD); - ftdm_log(FTDM_LOG_DEBUG, "Assigned chan %d:%d (%d:%d) to CSid=%d\n", - ftdmchan->span_id, ftdmchan->chan_id, event_span, event_chan, event->call_setup_id); - OUTBOUND_REQUESTS[event->call_setup_id].ftdmchan = ftdmchan; - } - OUTBOUND_REQUESTS[event->call_setup_id].flags = event->flags; - OUTBOUND_REQUESTS[event->call_setup_id].status = BST_READY; - return; - } - - } else { - - ftdm_assert(!mcon->sigmod, "CALL STOP ACK: Invalid Sigmod Path"); - - if ((ftdmchan = find_ftdmchan(OUTBOUND_REQUESTS[event->call_setup_id].span, (sangomabc_short_event_t*)event, 1))) { - int r; - /* NC: If we get CALL START ACK and channel is in active state - then we are completely out of sync with the other end. - Treat CALL START ACK as CALL STOP and hangup the current call. - */ - - if (ftdmchan->state == FTDM_CHANNEL_STATE_UP || - ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA || - ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS) { - ftdm_log(FTDM_LOG_CRIT, "FTDMCHAN CALL ACK STATE UP -> Changed to TERMINATING %d:%d\n", event_span, event_chan); - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r); - } else if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP || ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) { - ftdm_log(FTDM_LOG_CRIT, "FTDMCHAN CALL ACK STATE HANGUP -> Changed to HANGUP COMPLETE %d:%d\n", event_span, event_chan); - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, r); - } else { - ftdm_log(FTDM_LOG_CRIT, "FTDMCHAN STATE INVALID State %s on IN CALL ACK %d:%d\n", - ftdm_channel_state2str(ftdmchan->state), event_span, event_chan); - } - ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG); - ftdmchan=NULL; - } - } - - - if (!ftdmchan) { - ftdm_log(FTDM_LOG_CRIT, "START ACK CANT FIND A CHAN %d:%d\n", event_span, event_chan); - } else { - /* only reason to be here is failed to open channel when we we're in sigmod */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG); - } - - sangomabc_exec_command(mcon, - event->span, - event->chan, - event->call_setup_id, - SIGBOOST_EVENT_CALL_STOPPED, - FTDM_CAUSE_DESTINATION_OUT_OF_ORDER, 0); - OUTBOUND_REQUESTS[event->call_setup_id].status = BST_FAIL; - OUTBOUND_REQUESTS[event->call_setup_id].hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER; -} - -/** - * \brief Handler for call done event - * \param span Span where event was fired - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_call_done(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan; - int r = 0; - - if ((ftdmchan = find_ftdmchan(span, event, 1))) { - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - ftdm_mutex_lock(ftdmchan->mutex); - - if (sangoma_boost_data->sigmod) { - /* not really completely done, but if we ever get an incoming call before moving to HANGUP_COMPLETE - * handle_incoming_call() will take care of moving the state machine to release the channel */ - sangomabc_exec_command(&sangoma_boost_data->mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_RELEASED, - 0, 0); - } - - if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN || ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP_COMPLETE || ftdm_test_sflag(ftdmchan, SFLAG_TERMINATING)) { - goto done; - } - - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, r); - if (r) { - ftdm_mutex_unlock(ftdmchan->mutex); - return; - } - } - - done: - - if (ftdmchan) { - ftdm_mutex_unlock(ftdmchan->mutex); - } - - if (event->call_setup_id) { - release_request_id(event->call_setup_id); - } else { - release_request_id_span_chan(BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - } -} - - -/** - * \brief Handler for call start nack event - * \param span Span where event was fired - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_call_start_nack(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { - uint32_t count = 0; - int delay = 0; - int tg=event->trunk_group; - - ftdm_span_channel_use_count(span, &count); - - delay = (int) (count / 100) * 2; - - if (delay > 10) { - delay = 10; - } else if (delay < 1) { - delay = 1; - } - - if (tg < 0 || tg >= MAX_TRUNK_GROUPS) { - ftdm_log(FTDM_LOG_CRIT, "Invalid All Ckt Busy trunk group number %i\n", tg); - tg=0; - } - - congestion_timeouts[tg] = time(NULL) + delay; - event->release_cause = 17; - - } else if (event->release_cause == SIGBOOST_CALL_SETUP_CSUPID_DBL_USE) { - event->release_cause = 17; - } - - if (event->call_setup_id) { - if (sangoma_boost_data->sigmod) { - ftdmchan = OUTBOUND_REQUESTS[event->call_setup_id].ftdmchan; - CALL_DATA(ftdmchan)->last_event_id = event->event_id; - CALL_DATA(ftdmchan)->call_setup_id = event->call_setup_id; - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - ftdm_clear_sflag_locked(ftdmchan, SFLAG_SENT_FINAL_MSG); - } else { - sangomabc_exec_command(mcon, - 0, - 0, - event->call_setup_id, - SIGBOOST_EVENT_CALL_START_NACK_ACK, - 0, 0); - OUTBOUND_REQUESTS[event->call_setup_id].event = *event; - OUTBOUND_REQUESTS[event->call_setup_id].status = BST_FAIL; - OUTBOUND_REQUESTS[event->call_setup_id].hangup_cause = event->release_cause; - ftdm_log(FTDM_LOG_DEBUG, "setting outbound request status %d to BST_FAIL\n", event->call_setup_id); - } - return; - } else { - if ((ftdmchan = find_ftdmchan(span, event, 1))) { - int r = 0; - - /* if there is no call setup id this should not be an outbound channel for sure */ - ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND), "Yay, outbound flag should not be set here!\n"); - - CALL_DATA(ftdmchan)->last_event_id = event->event_id; - ftdm_mutex_lock(ftdmchan->mutex); - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r); - if (r == FTDM_SUCCESS) { - ftdmchan->caller_data.hangup_cause = event->release_cause; - } - ftdm_mutex_unlock(ftdmchan->mutex); - if (r) { - return; - } - } - } - - if (ftdmchan) { - ftdm_set_sflag_locked(ftdmchan, SFLAG_SENT_FINAL_MSG); - } - - /* nobody else will do it so we have to do it ourselves */ - sangomabc_exec_command(mcon, - event->span, - event->chan, - event->call_setup_id, - SIGBOOST_EVENT_CALL_START_NACK_ACK, - 0, 0); -} - -static void handle_call_released(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan; - - if ((ftdmchan = find_ftdmchan(span, event, 1))) { - ftdm_log(FTDM_LOG_DEBUG, "Releasing completely chan s%dc%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), - BOOST_EVENT_CHAN(mcon->sigmod, event)); - ftdm_channel_close(&ftdmchan); - } else { - ftdm_log(FTDM_LOG_CRIT, "Odd, We could not find chan: s%dc%d to release the call completely!!\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - } -} - -/** - * \brief Handler for call stop event - * \param span Span where event was fired - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_call_stop(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan; - - if ((ftdmchan = find_ftdmchan(span, event, 1))) { - int r = 0; - - ftdm_mutex_lock(ftdmchan->mutex); - - if (ftdm_test_sflag(ftdmchan, SFLAG_HANGUP) || - ftdmchan->state == FTDM_CHANNEL_STATE_DOWN || - ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - - /* NC: Checking for state DOWN because ss7box can - send CALL_STOP twice in a row. If we do not check for - STATE_DOWN we will set the state back to termnating - and block the channel forever - */ - - /* racing condition where both sides initiated a hangup - * Do not change current state as channel is already clearing - * itself through local initiated hangup */ - - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_STOPPED_ACK, - 0, 0); - ftdm_mutex_unlock(ftdmchan->mutex); - return; - } else if (ftdmchan->state == FTDM_CHANNEL_STATE_HOLD) { - ftdmchan->init_state = FTDM_CHANNEL_STATE_TERMINATING; - ftdm_log(FTDM_LOG_DEBUG, "Channel init state updated to TERMINATING [Csid:%d]\n", event->call_setup_id); - OUTBOUND_REQUESTS[event->call_setup_id].hangup_cause = event->release_cause; - ftdmchan->caller_data.hangup_cause = event->release_cause; - ftdm_mutex_unlock(ftdmchan->mutex); - return; - } else { - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r); - } - - if (r == FTDM_SUCCESS) { - ftdmchan->caller_data.hangup_cause = event->release_cause; - } - - ftdm_mutex_unlock(ftdmchan->mutex); - - if (r) { - return; - } - } else { /* we have to do it ourselves.... */ - ftdm_log(FTDM_LOG_CRIT, "Odd, We could not find chan: s%dc%d\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - release_request_id_span_chan(BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - } -} - -/** - * \brief Handler for call answer event - * \param span Span where event was fired - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_call_answer(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan; - - if ((ftdmchan = find_ftdmchan(span, event, 1))) { - ftdm_mutex_lock(ftdmchan->mutex); - - if (ftdm_test_sflag(ftdmchan, SFLAG_HANGUP) || - ftdmchan->state == FTDM_CHANNEL_STATE_DOWN || - ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - - /* NC: Do nothing here because we are in process - of stopping the call. So ignore the ANSWER. */ - ftdm_log(FTDM_LOG_DEBUG, "Got answer but call is already hangup %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), - BOOST_EVENT_CHAN(mcon->sigmod, event)); - - } else if (ftdmchan->state == FTDM_CHANNEL_STATE_HOLD) { - ftdmchan->init_state = FTDM_CHANNEL_STATE_UP; - - } else { - int r = 0; - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_UP, r); - } - ftdm_mutex_unlock(ftdmchan->mutex); - } else { - ftdm_log(FTDM_LOG_CRIT, "Could not find channel %d:%d on answer message!\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - sangomabc_exec_command(mcon, - event->span, - event->chan, - event->call_setup_id, - SIGBOOST_EVENT_CALL_STOPPED, - FTDM_CAUSE_DESTINATION_OUT_OF_ORDER, 0); - } -} - -static __inline__ void stop_loop(ftdm_channel_t *ftdmchan); - -/** - * \brief Handler for call start event - * \param span Span where event was fired - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_event_t *event) -{ - ftdm_channel_t *ftdmchan = NULL; - int hangup_cause = FTDM_CAUSE_CALL_REJECTED; - int retry = 1; - -tryagain: - - if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 0))) { - if ((ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 1))) { - int r; - - /* NC: If we get CALL START and channel is in active state - then we are completely out of sync with the other end. - Treat CALL START as CALL STOP and hangup the current call. - The incoming call will also be NACKed. - */ - - if (ftdmchan->state == FTDM_CHANNEL_STATE_UP || - ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA || - ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS) { - ftdm_log(FTDM_LOG_CRIT, "s%dc%d: FTDMCHAN STATE UP -> Changed to TERMINATING\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r); - } else if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP || ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) { - ftdm_log(FTDM_LOG_CRIT, "s%dc%d: FTDMCHAN STATE HANGUP -> Changed to HANGUP COMPLETE\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, r); - } else if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) { - ftdm_log(FTDM_LOG_WARNING, "s%dc%d: Collision, hanging up incoming call\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - /* dont hangup the outgoing call, the other side will send a call start nack too - * and there we will move to terminating. If we move to terminating here. We used to move - * to terminating here, but that introduces a problem in handle_call_start_nack where - * when receiving call start nack we move the channel from DOWN to TERMINATING ( cuz we already - * hangup here ) and the channel gets stuck in terminating forever. So at this point we're trusting - * the other side to send the call start nack ( or proceed with the call ) - * ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r); - */ - } else if (ftdmchan->state == FTDM_CHANNEL_STATE_IN_LOOP && retry) { - retry = 0; - stop_loop(ftdmchan); - ftdm_channel_advance_states(ftdmchan); - goto tryagain; - } else { - ftdm_log(FTDM_LOG_ERROR, "s%dc%d: rejecting incoming call in channel state %s\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event), - ftdm_channel_state2str(ftdmchan->state)); - } - ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG); - ftdmchan = NULL; - } else { - ftdm_log(FTDM_LOG_CRIT, "s%dc%d: incoming call in invalid channel (channel not found)!\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - } - goto error; - } - - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "s%dc%d: failed to open channel on incoming call, rejecting!\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - goto error; - } - - ftdm_log(FTDM_LOG_DEBUG, "Got call start from s%dc%d mapped to freetdm logical s%dc%d, physical s%dc%d\n", - event->span, event->chan, - ftdmchan->span_id, ftdmchan->chan_id, - ftdmchan->physical_span_id, ftdmchan->physical_chan_id); - - ftdmchan->sflags = 0; - ftdm_set_string(ftdmchan->caller_data.cid_num.digits, (char *)event->calling.digits); - ftdm_set_string(ftdmchan->caller_data.cid_name, (char *)event->calling.digits); - ftdm_set_string(ftdmchan->caller_data.ani.digits, (char *)event->calling.digits); - ftdm_set_string(ftdmchan->caller_data.dnis.digits, (char *)event->called.digits); - ftdm_set_string(ftdmchan->caller_data.rdnis.digits, (char *)event->rdnis.digits); - if (event->custom_data_size) { - ftdm_set_string(ftdmchan->caller_data.raw_data, event->custom_data); - ftdmchan->caller_data.raw_data_len = event->custom_data_size; - } - - if (strlen(event->calling_name)) { - ftdm_set_string(ftdmchan->caller_data.cid_name, (char *)event->calling_name); - } - - ftdmchan->caller_data.cid_num.plan = event->calling.npi; - ftdmchan->caller_data.cid_num.type = event->calling.ton; - - ftdmchan->caller_data.ani.plan = event->calling.npi; - ftdmchan->caller_data.ani.type = event->calling.ton; - - ftdmchan->caller_data.dnis.plan = event->called.npi; - ftdmchan->caller_data.dnis.type = event->called.ton; - - ftdmchan->caller_data.rdnis.plan = event->rdnis.npi; - ftdmchan->caller_data.rdnis.type = event->rdnis.ton; - - ftdmchan->caller_data.screen = event->calling.screening_ind; - ftdmchan->caller_data.pres = event->calling.presentation_ind; - - ftdmchan->caller_data.bearer_capability = event->bearer.capability; - ftdmchan->caller_data.bearer_layer1 = event->bearer.uil1p; - - /* more info about custom data: http://www.ss7box.com/smg_manual.html#ISUP-IN-RDNIS-NEW */ - if (event->custom_data_size) { - char* p = NULL; - - p = strstr((char*)event->custom_data,"PRI001-ANI2-"); - if (p!=NULL) { - int ani2 = 0; - sscanf(p, "PRI001-ANI2-%d", &ani2); - snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", ani2); - } - } - - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING); - return; - - error: - hangup_cause = ftdmchan ? ftdmchan->caller_data.hangup_cause : FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL; - sangomabc_exec_command(mcon, - event->span, - event->chan, - event->call_setup_id, - SIGBOOST_EVENT_CALL_START_NACK, - hangup_cause, 0); - -} - -static void handle_call_loop_start(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_status_t res = FTDM_FAIL; - ftdm_channel_t *ftdmchan; - - if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 0))) { - ftdm_log(FTDM_LOG_CRIT, "CANNOT START LOOP, CHAN NOT AVAILABLE %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - return; - } - - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "CANNOT START LOOP, CANT OPEN CHAN %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - return; - } - - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP, res); - if (res != FTDM_SUCCESS) { - ftdm_channel_t *toclose = ftdmchan; - ftdm_log(FTDM_LOG_CRIT, "yay, could not set the state of the channel to IN_LOOP, loop will fail\n"); - ftdm_channel_close(&toclose); - return; - } - ftdm_log(FTDM_LOG_DEBUG, "%d:%d starting loop\n", ftdmchan->span_id, ftdmchan->chan_id); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_LOOP, NULL); -} - -static __inline__ void stop_loop(ftdm_channel_t *ftdmchan) -{ - ftdm_status_t res = FTDM_FAIL; - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); - /* even when we did not sent a msg we set this flag to avoid sending call stop in the DOWN state handler */ - ftdm_set_flag(ftdmchan, SFLAG_SENT_FINAL_MSG); - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_DOWN, res); - if (res != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "yay, could not set the state of the channel from IN_LOOP to DOWN\n"); - } -} - -static void handle_call_loop_stop(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan; - if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 1))) { - ftdm_log(FTDM_LOG_CRIT, "CANNOT STOP LOOP, INVALID CHAN REQUESTED %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - return; - } - if (ftdmchan->state != FTDM_CHANNEL_STATE_IN_LOOP) { - ftdm_log(FTDM_LOG_WARNING, "Got stop loop request in a channel that is not in loop, ignoring ...\n"); - return; - } - stop_loop(ftdmchan); -} - -/** - * \brief Handler for heartbeat event - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_heartbeat(sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - int err; - - err = sangomabc_connection_writep(mcon, (sangomabc_event_t*)event); - - if (err <= 0) { - ftdm_log(FTDM_LOG_CRIT, "Failed to tx on boost connection [%s]: %s\n", strerror(errno)); - } - return; -} - -/** - * \brief Handler for restart ack event - * \param mcon sangoma boost connection - * \param span Span where event was fired - * \param event Event to handle - */ -static void handle_restart_ack(sangomabc_connection_t *mcon, ftdm_span_t *span, sangomabc_short_event_t *event) -{ - ftdm_log(FTDM_LOG_DEBUG, "RECV RESTART ACK\n"); -} - -/** - * \brief Handler for restart event - * \param mcon sangoma boost connection - * \param span Span where event was fired - * \param event Event to handle - */ -static void handle_restart(sangomabc_connection_t *mcon, ftdm_span_t *span, sangomabc_short_event_t *event) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - mcon->rxseq_reset = 0; - ftdm_set_flag((&sangoma_boost_data->mcon), MSU_FLAG_DOWN); - ftdm_set_flag_locked(span, FTDM_SPAN_SUSPENDED); - ftdm_set_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RESTARTING); - -} - -/** - * \brief Handler for incoming digit event - * \param mcon sangoma boost connection - * \param span Span where event was fired - * \param event Event to handle - */ -static void handle_incoming_digit(sangomabc_connection_t *mcon, ftdm_span_t *span, sangomabc_event_t *event) -{ - ftdm_channel_t *ftdmchan = NULL; - char digits[MAX_DIALED_DIGITS + 2] = ""; - - if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t *)event, 1))) { - ftdm_log(FTDM_LOG_ERROR, "Invalid channel\n"); - return; - } - - if (event->called_number_digits_count == 0) { - ftdm_log(FTDM_LOG_WARNING, "Error Incoming digit with len %s %d [w%dg%d]\n", - event->called_number_digits, - event->called_number_digits_count, - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - return; - } - - ftdm_log(FTDM_LOG_WARNING, "Incoming digit with len %s %d [w%dg%d]\n", - event->called_number_digits, - event->called_number_digits_count, - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - - memcpy(digits, event->called_number_digits, event->called_number_digits_count); - ftdm_channel_queue_dtmf(ftdmchan, digits); - - return; -} - - -/** - * \brief Checks if span has state changes pending and processes - * \param span Span where event was fired - * \param event Event to handle - * \return The locked FTDM channel associated to the event if any, NULL otherwise - */ -static ftdm_channel_t* event_process_states(ftdm_span_t *span, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan = NULL; - ftdm_sangoma_boost_data_t *signal_data = span->signal_data; - - switch (event->event_id) { - case SIGBOOST_EVENT_CALL_START_NACK: - case SIGBOOST_EVENT_CALL_START_NACK_ACK: - if (event->call_setup_id && !signal_data->sigmod) { - return NULL; - } - //if event->span and event->chan is valid, fall-through - case SIGBOOST_EVENT_CALL_START: - case SIGBOOST_EVENT_CALL_START_ACK: - case SIGBOOST_EVENT_CALL_STOPPED: - case SIGBOOST_EVENT_CALL_PROGRESS: - case SIGBOOST_EVENT_CALL_ANSWERED: - case SIGBOOST_EVENT_CALL_STOPPED_ACK: - case SIGBOOST_EVENT_DIGIT_IN: - case SIGBOOST_EVENT_INSERT_CHECK_LOOP: - case SIGBOOST_EVENT_REMOVE_CHECK_LOOP: - case SIGBOOST_EVENT_CALL_RELEASED: - if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 1))) { - ftdm_log(FTDM_LOG_CRIT, "could not find channel %d:%d to process pending state changes!\n", - BOOST_EVENT_SPAN(signal_data->sigmod, event), - BOOST_EVENT_CHAN(signal_data->sigmod, event)); - return NULL; - } - break; - case SIGBOOST_EVENT_HEARTBEAT: - case SIGBOOST_EVENT_SYSTEM_RESTART_ACK: - case SIGBOOST_EVENT_SYSTEM_RESTART: - case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE: - return NULL; - default: - ftdm_log(FTDM_LOG_CRIT, "Unhandled event id: %d\n", event->event_id); - return NULL; - } - - ftdm_mutex_lock(ftdmchan->mutex); - ftdm_channel_advance_states(ftdmchan); - return ftdmchan; -} - -/** - * \brief Handler for sangoma boost event - * \param span Span where event was fired - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static int parse_sangoma_event(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t* ftdmchan = NULL; - - if (!ftdm_running()) { - ftdm_log(FTDM_LOG_WARNING, "System is shutting down.\n"); - return -1; - } - - ftdm_assert_return(event->call_setup_id <= MAX_REQ_ID, -1, "Unexpected call setup id\n"); - - /* process all pending state changes for that channel before - * processing the new boost event */ - ftdmchan = event_process_states(span, event); - - switch(event->event_id) { - case SIGBOOST_EVENT_CALL_START: - handle_call_start(span, mcon, (sangomabc_event_t*)event); - break; - case SIGBOOST_EVENT_CALL_STOPPED: - handle_call_stop(span, mcon, event); - break; - case SIGBOOST_EVENT_CALL_RELEASED: - handle_call_released(span, mcon, event); - break; - case SIGBOOST_EVENT_CALL_START_ACK: - handle_call_start_ack(mcon, event); - break; - case SIGBOOST_EVENT_CALL_PROGRESS: - handle_call_progress(span, mcon, event); - break; - case SIGBOOST_EVENT_CALL_START_NACK: - handle_call_start_nack(span, mcon, event); - break; - case SIGBOOST_EVENT_CALL_ANSWERED: - handle_call_answer(span, mcon, event); - break; - case SIGBOOST_EVENT_HEARTBEAT: - handle_heartbeat(mcon, event); - break; - case SIGBOOST_EVENT_CALL_STOPPED_ACK: - handle_call_done(span, mcon, event); - break; - case SIGBOOST_EVENT_CALL_START_NACK_ACK: - /* On NACK ack span chan are always invalid - All there is to do is to clear the id */ - if (event->call_setup_id) { - nack_map[event->call_setup_id] = 0; - release_request_id(event->call_setup_id); - } else { - handle_call_done(span, mcon, event); - } - break; - case SIGBOOST_EVENT_INSERT_CHECK_LOOP: - handle_call_loop_start(span, mcon, event); - break; - case SIGBOOST_EVENT_REMOVE_CHECK_LOOP: - handle_call_loop_stop(span, mcon, event); - break; - case SIGBOOST_EVENT_SYSTEM_RESTART_ACK: - handle_restart_ack(mcon, span, event); - break; - case SIGBOOST_EVENT_SYSTEM_RESTART: - handle_restart(mcon, span, event); - break; - case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE: - //handle_gap_abate(event); - break; - case SIGBOOST_EVENT_DIGIT_IN: - handle_incoming_digit(mcon, span, (sangomabc_event_t*)event); - break; - default: - ftdm_log(FTDM_LOG_WARNING, "No handler implemented for [%s]\n", sangomabc_event_id_name(event->event_id)); - break; - } - - if(ftdmchan != NULL) { - ftdm_channel_advance_states(ftdmchan); - ftdm_mutex_unlock(ftdmchan->mutex); - } - - return 0; - -} - -/** - * \brief Handler for channel state change - * \param ftdmchan Channel to handle - */ -static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - sangomabc_connection_t *mcon = &sangoma_boost_data->mcon; - ftdm_sigmsg_t sig; - ftdm_status_t status; - - - ftdm_assert_return(ftdmchan->last_state != ftdmchan->state, FTDM_FAIL, "Channel state already processed\n"); - - ftdm_log(FTDM_LOG_DEBUG, "%d:%d PROCESSING STATE [%s]\n", ftdmchan->span_id, ftdmchan->chan_id, ftdm_channel_state2str(ftdmchan->state)); - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = ftdmchan->chan_id; - sig.span_id = ftdmchan->span_id; - sig.channel = ftdmchan; - - ftdm_channel_complete_state(ftdmchan); - - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_DOWN: - { - int call_stopped_ack_sent = 0; - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_IN_LOOP) { - ftdm_log(FTDM_LOG_DEBUG, "%d:%d terminating loop\n", ftdmchan->span_id, ftdmchan->chan_id); - } else { - release_request_id_span_chan(ftdmchan->physical_span_id, ftdmchan->physical_chan_id); - - if (!ftdm_test_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG)) { - ftdm_set_sflag_locked(ftdmchan, SFLAG_SENT_FINAL_MSG); - - if (ftdmchan->call_data && CALL_DATA(ftdmchan)->last_event_id == SIGBOOST_EVENT_CALL_START_NACK) { - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - CALL_DATA(ftdmchan)->call_setup_id, - SIGBOOST_EVENT_CALL_START_NACK_ACK, - 0, 0); - - } else { - /* we got a call stop msg, time to reply with call stopped ack */ - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_STOPPED_ACK, - 0, 0); - call_stopped_ack_sent = 1; - } - } - } - - ftdmchan->sflags = 0; - memset(ftdmchan->call_data, 0, sizeof(sangoma_boost_call_t)); - if (sangoma_boost_data->sigmod && call_stopped_ack_sent) { - /* we dont want to call ftdm_channel_close just yet until call released is received */ - ftdm_log(FTDM_LOG_DEBUG, "Waiting for call release confirmation before declaring chan %d:%d as available \n", - ftdmchan->span_id, ftdmchan->chan_id); - } else { - ftdm_channel_t *toclose = ftdmchan; - ftdm_channel_close(&toclose); - } - } - break; - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA; - if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } - } else { - if (!ftdm_test_sflag(ftdmchan, SFLAG_SENT_ACK)) { - ftdm_set_sflag(ftdmchan, SFLAG_SENT_ACK); - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_START_ACK, - 0, 0); - } - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_PROGRESS, - 0, SIGBOOST_PROGRESS_MEDIA); - } - } - break; - case FTDM_CHANNEL_STATE_PROGRESS: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_PROGRESS; - if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } - } else { - if (!ftdm_test_sflag(ftdmchan, SFLAG_SENT_ACK)) { - ftdm_set_sflag(ftdmchan, SFLAG_SENT_ACK); - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_START_ACK, - 0, SIGBOOST_PROGRESS_RING); - } - } - } - break; - case FTDM_CHANNEL_STATE_IDLE: - case FTDM_CHANNEL_STATE_HOLD: - { - /* twiddle */ - } - break; - case FTDM_CHANNEL_STATE_RING: - { - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_START; - if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } - } - } - break; - case FTDM_CHANNEL_STATE_RESTART: - { - sig.event_id = FTDM_SIGEVENT_RESTART; - status = ftdm_span_send_signal(ftdmchan->span, &sig); - ftdm_set_sflag_locked(ftdmchan, SFLAG_SENT_FINAL_MSG); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - break; - case FTDM_CHANNEL_STATE_UP: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_UP; - if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } - } else { - if (!(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_PROGRESS) || ftdm_test_flag(ftdmchan, FTDM_CHANNEL_MEDIA))) { - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_START_ACK, - 0, 0); - } - - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_ANSWERED, - 0, 0); - } - } - break; - case FTDM_CHANNEL_STATE_DIALING: - { - char dnis[128] = ""; - sangoma_boost_request_id_t r; - sangomabc_event_t event = {0}; - - ftdm_assert(sangoma_boost_data->sigmod != NULL, "We should be in sigmod here!\n"); - - ftdm_set_string(dnis, ftdmchan->caller_data.dnis.digits); - - r = next_request_id(); - if (r == 0) { - ftdm_log(FTDM_LOG_CRIT, "All boost request ids are busy.\n"); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - } - - sangomabc_call_init(&event, ftdmchan->caller_data.cid_num.digits, dnis, r); - - event.span = (uint8_t)ftdmchan->physical_span_id; - event.chan = (uint8_t)ftdmchan->physical_chan_id; - /* because we already have a span/chan here we bind to the SETUP_GRID now and not on call start ack */ - SETUP_GRID[event.span][event.chan] = event.call_setup_id; - - ftdm_set_string(event.calling_name, ftdmchan->caller_data.cid_name); - ftdm_set_string(event.rdnis.digits, ftdmchan->caller_data.rdnis.digits); - if (strlen(ftdmchan->caller_data.rdnis.digits)) { - event.rdnis.digits_count = (uint8_t)strlen(ftdmchan->caller_data.rdnis.digits)+1; - event.rdnis.ton = ftdmchan->caller_data.rdnis.type; - event.rdnis.npi = ftdmchan->caller_data.rdnis.plan; - } - - event.calling.screening_ind = ftdmchan->caller_data.screen; - event.calling.presentation_ind = ftdmchan->caller_data.pres; - - event.calling.ton = ftdmchan->caller_data.cid_num.type; - event.calling.npi = ftdmchan->caller_data.cid_num.plan; - - event.called.ton = ftdmchan->caller_data.dnis.type; - event.called.npi = ftdmchan->caller_data.dnis.plan; - - if (ftdmchan->caller_data.raw_data_len) { - ftdm_set_string(event.custom_data, ftdmchan->caller_data.raw_data); - event.custom_data_size = (uint16_t)ftdmchan->caller_data.raw_data_len; - } - - OUTBOUND_REQUESTS[r].status = BST_WAITING; - OUTBOUND_REQUESTS[r].span = ftdmchan->span; - OUTBOUND_REQUESTS[r].ftdmchan = ftdmchan; - - ftdm_log(FTDM_LOG_DEBUG, "Dialing number %s over boost channel with request id %d\n", event.called_number_digits, r); - if (sangomabc_connection_write(&sangoma_boost_data->mcon, &event) <= 0) { - release_request_id(r); - ftdm_log(FTDM_LOG_CRIT, "Failed to tx boost event [%s]\n", strerror(errno)); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - } - - } - break; - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - break; - case FTDM_CHANNEL_STATE_HANGUP: - { - ftdm_set_sflag_locked(ftdmchan, SFLAG_HANGUP); - - if (ftdm_test_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG) || ftdm_test_sflag(ftdmchan, SFLAG_TERMINATING)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - } else { - ftdm_set_sflag_locked(ftdmchan, SFLAG_SENT_FINAL_MSG); - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_ANSWERED) || - ftdm_test_flag(ftdmchan, FTDM_CHANNEL_PROGRESS) || - ftdm_test_flag(ftdmchan, FTDM_CHANNEL_MEDIA) || - ftdm_test_sflag(ftdmchan, SFLAG_RECVD_ACK)) { - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_STOPPED, - ftdmchan->caller_data.hangup_cause, 0); - } else { - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_START_NACK, - ftdmchan->caller_data.hangup_cause, 0); - } - } - } - break; - case FTDM_CHANNEL_STATE_TERMINATING: - { - ftdm_set_sflag_locked(ftdmchan, SFLAG_TERMINATING); - sig.event_id = FTDM_SIGEVENT_STOP; - status = ftdm_span_send_signal(ftdmchan->span, &sig); - } - break; - case FTDM_CHANNEL_STATE_IN_LOOP: - { - /* nothing to do, we sent the FTDM_COMMAND_ENABLE_LOOP command in handle_call_loop_start() right away */ - } - break; - default: - break; - } - return FTDM_SUCCESS; -} - -/** - * \brief Initialises outgoing requests array - */ -static __inline__ void init_outgoing_array(void) -{ - memset(&OUTBOUND_REQUESTS, 0, sizeof(OUTBOUND_REQUESTS)); -} - -/** - * \brief Checks current state on a span - * \param span Span to check status on - */ -static __inline__ void check_state(ftdm_span_t *span) -{ - ftdm_channel_t *ftdmchan = NULL; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - int susp = ftdm_test_flag(span, FTDM_SPAN_SUSPENDED); - - if (susp && ftdm_check_state_all(span, FTDM_CHANNEL_STATE_DOWN)) { - susp = 0; - } - - if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE) || susp) { - uint32_t j; - ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE); - if (susp) { - for(j = 1; j <= span->chan_count; j++) { - if (ftdm_test_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE) || susp) { - ftdm_mutex_lock(span->channels[j]->mutex); - ftdm_clear_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE); - if (susp && span->channels[j]->state != FTDM_CHANNEL_STATE_DOWN) { - ftdm_set_state(span->channels[j], FTDM_CHANNEL_STATE_RESTART); - } - ftdm_channel_advance_states(span->channels[j]); - ftdm_mutex_unlock(span->channels[j]->mutex); - } - } - } else { - while ((ftdmchan = ftdm_queue_dequeue(span->pendingchans))) { - /* it can happen that someone else processed the chan states - * but without taking the chan out of the queue, so check th - * flag before advancing the state */ - ftdm_mutex_lock(ftdmchan->mutex); - ftdm_channel_advance_states(ftdmchan); - ftdm_mutex_unlock(ftdmchan->mutex); - } - } - } - - if (ftdm_test_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RESTARTING)) { - if (ftdm_check_state_all(span, FTDM_CHANNEL_STATE_DOWN)) { - sangomabc_exec_command(&sangoma_boost_data->mcon, - 0, - 0, - -1, - SIGBOOST_EVENT_SYSTEM_RESTART_ACK, - 0, 0); - ftdm_clear_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RESTARTING); - ftdm_clear_flag_locked(span, FTDM_SPAN_SUSPENDED); - ftdm_clear_flag((&sangoma_boost_data->mcon), MSU_FLAG_DOWN); - init_outgoing_array(); - } - } -} - - -/** - * \brief Checks for events on a span - * \param span Span to check for events - */ -static __inline__ ftdm_status_t check_events(ftdm_span_t *span, int ms_timeout) -{ - ftdm_status_t status; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - status = ftdm_span_poll_event(span, ms_timeout, NULL); - - switch(status) { - case FTDM_SUCCESS: - { - ftdm_event_t *event; - while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) { - switch (event->enum_id) { - case FTDM_OOB_ALARM_TRAP: - if (sangoma_boost_data->sigmod) { - sangoma_boost_data->sigmod->on_hw_link_status_change(event->channel, FTDM_HW_LINK_DISCONNECTED); - } - break; - case FTDM_OOB_ALARM_CLEAR: - if (sangoma_boost_data->sigmod) { - sangoma_boost_data->sigmod->on_hw_link_status_change(event->channel, FTDM_HW_LINK_CONNECTED); - } - break; - } - } - } - break; - case FTDM_FAIL: - { - if (!ftdm_running()) { - break; - } - ftdm_log(FTDM_LOG_ERROR, "Boost Check Event Failure Failure: %s\n", span->last_error); - return FTDM_FAIL; - } - break; - default: - break; - } - - return FTDM_SUCCESS; -} - -/** - * \brief Main thread function for sangoma boost span (monitor) - * \param me Current thread - * \param obj Span to run in this thread - */ -static void *ftdm_sangoma_events_run(ftdm_thread_t *me, void *obj) -{ - ftdm_span_t *span = (ftdm_span_t *) obj; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - unsigned errs = 0; - - while (ftdm_test_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_EVENTS_RUNNING) && ftdm_running()) { - if (check_events(span, 100) != FTDM_SUCCESS) { - if (errs++ > 50) { - ftdm_log(FTDM_LOG_ERROR, "Too many event errors, quitting sangoma events thread\n"); - return NULL; - } - } - } - - ftdm_log(FTDM_LOG_DEBUG, "Sangoma Boost Events thread ended.\n"); - - ftdm_clear_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_EVENTS_RUNNING); - - return NULL; -} - -static ftdm_status_t ftdm_boost_connection_open(ftdm_span_t *span) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - if (sangoma_boost_data->sigmod) { - if (sangoma_boost_data->sigmod->start_span(span) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - ftdm_clear_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RESTARTING); - ftdm_clear_flag_locked(span, FTDM_SPAN_SUSPENDED); - ftdm_clear_flag((&sangoma_boost_data->mcon), MSU_FLAG_DOWN); - } - - sangoma_boost_data->pcon = sangoma_boost_data->mcon; - - /* when sigmod is present, all arguments: local_ip etc, are ignored by sangomabc_connection_open */ - if (sangomabc_connection_open(&sangoma_boost_data->mcon, - sangoma_boost_data->mcon.cfg.local_ip, - sangoma_boost_data->mcon.cfg.local_port, - sangoma_boost_data->mcon.cfg.remote_ip, - sangoma_boost_data->mcon.cfg.remote_port) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Error: Opening MCON Socket [%d] %s\n", sangoma_boost_data->mcon.socket, strerror(errno)); - return FTDM_FAIL; - } - - if (sangomabc_connection_open(&sangoma_boost_data->pcon, - sangoma_boost_data->pcon.cfg.local_ip, - ++sangoma_boost_data->pcon.cfg.local_port, - sangoma_boost_data->pcon.cfg.remote_ip, - ++sangoma_boost_data->pcon.cfg.remote_port) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Error: Opening PCON Socket [%d] %s\n", sangoma_boost_data->pcon.socket, strerror(errno)); - return FTDM_FAIL; - } - - /* try to create the boost sockets interrupt objects */ - if (ftdm_interrupt_create(&sangoma_boost_data->pcon.sock_interrupt, sangoma_boost_data->pcon.socket) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Span %s could not create its boost msock interrupt!\n", span->name); - return FTDM_FAIL; - } - - if (ftdm_interrupt_create(&sangoma_boost_data->mcon.sock_interrupt, sangoma_boost_data->mcon.socket) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Span %s could not create its boost psock interrupt!\n", span->name); - return FTDM_FAIL; - } - - return FTDM_SUCCESS; -} - -/*! - \brief wait for a boost event - \return -1 on error, 0 on timeout, 1 when there are events - */ -static int ftdm_boost_wait_event(ftdm_span_t *span) -{ - ftdm_status_t res; - ftdm_interrupt_t *ints[3]; - int numints; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - ftdm_queue_get_interrupt(span->pendingchans, &ints[0]); - numints = 1; - /* if in queue mode wait for both the pendingchans queue and the boost msg queue */ - if (sangoma_boost_data->sigmod) { - ftdm_queue_get_interrupt(sangoma_boost_data->boost_queue, &ints[1]); - numints = 2; - } -#ifndef __WINDOWS__ - else { - /* socket mode ... */ - ints[1] = sangoma_boost_data->mcon.sock_interrupt; - ints[2] = sangoma_boost_data->pcon.sock_interrupt; - numints = 3; - sangoma_boost_data->iteration = 0; - } -#endif - res = ftdm_interrupt_multiple_wait(ints, numints, 100); - if (FTDM_SUCCESS != res && FTDM_TIMEOUT != res) { - ftdm_log(FTDM_LOG_CRIT, "Unexpected return value from interrupt waiting: %d\n", res); - return -1; - } - return 0; -} - - -static sangomabc_event_t *ftdm_boost_read_event(ftdm_span_t *span) -{ - sangomabc_event_t *event = NULL; - sangomabc_connection_t *mcon, *pcon; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - mcon = &sangoma_boost_data->mcon; - pcon = &sangoma_boost_data->pcon; - - event = sangomabc_connection_readp(pcon, sangoma_boost_data->iteration); - - /* if there is no event and this is not a sigmod-driven span it's time to try the other connection for events */ - if (!event && !sangoma_boost_data->sigmod) { - event = sangomabc_connection_read(mcon, sangoma_boost_data->iteration); - } - - return event; -} - -/** - * \brief Main thread function for sangoma boost span (monitor) - * \param me Current thread - * \param obj Span to run in this thread - */ -static void *ftdm_sangoma_boost_run(ftdm_thread_t *me, void *obj) -{ - ftdm_span_t *span = (ftdm_span_t *) obj; - sangomabc_connection_t *mcon, *pcon; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - mcon = &sangoma_boost_data->mcon; - pcon = &sangoma_boost_data->pcon; - - /* sigmod overrides socket functionality if not null */ - if (sangoma_boost_data->sigmod) { - mcon->span = span; - pcon->span = span; - /* everything could be retrieved through span, but let's use shortcuts */ - mcon->sigmod = sangoma_boost_data->sigmod; - pcon->sigmod = sangoma_boost_data->sigmod; - mcon->boost_queue = sangoma_boost_data->boost_queue; - pcon->boost_queue = sangoma_boost_data->boost_queue; - } - - if (ftdm_boost_connection_open(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "ftdm_boost_connection_open failed\n"); - goto end; - } - - init_outgoing_array(); - if (!sangoma_boost_data->sigmod) { - sangomabc_exec_commandp(pcon, - 0, - 0, - -1, - SIGBOOST_EVENT_SYSTEM_RESTART, - 0); - ftdm_set_flag(mcon, MSU_FLAG_DOWN); - } - - while (ftdm_test_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING)) { - sangomabc_event_t *event = NULL; - - if (!ftdm_running()) { - if (!sangoma_boost_data->sigmod) { - sangomabc_exec_commandp(pcon, - 0, - 0, - -1, - SIGBOOST_EVENT_SYSTEM_RESTART, - 0); - ftdm_set_flag(mcon, MSU_FLAG_DOWN); - } - ftdm_log(FTDM_LOG_DEBUG, "ftdm is no longer running\n"); - break; - } - - if (ftdm_boost_wait_event(span) < 0) { - ftdm_log(FTDM_LOG_ERROR, "ftdm_boost_wait_event failed\n"); - } - - while ((event = ftdm_boost_read_event(span))) { - parse_sangoma_event(span, pcon, (sangomabc_short_event_t*)event); - sangoma_boost_data->iteration++; - } - - check_state(span); - } - -end: - if (!sangoma_boost_data->sigmod) { - sangomabc_connection_close(&sangoma_boost_data->mcon); - sangomabc_connection_close(&sangoma_boost_data->pcon); - } - - ftdm_clear_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING); - - ftdm_log(FTDM_LOG_DEBUG, "Sangoma Boost thread ended.\n"); - return NULL; -} - -#if 0 -static int sigmod_ss7box_isup_exec_cmd(ftdm_stream_handle_t *stream, char *cmd) -{ - FILE *fp; - int status=0; - char path[1024]; - - fp = popen(cmd, "r"); - if (fp == NULL) { - stream->write_function(stream, "%s: -ERR failed to execute cmd: %s\n", - __FILE__,cmd); - return -1; - } - - while (fgets(path, sizeof(path)-1, fp) != NULL) { - path[sizeof(path)-1]='\0'; - stream->write_function(stream,"%s", path); - } - - - status = pclose(fp); - if (status == -1) { - /* Error reported by pclose() */ - } else { - /* Use macros described under wait() to inspect `status' in order - to determine success/failure of command executed by popen() */ - } - - return status; -} -#endif - -static void ftdm_cli_span_state_cmd(ftdm_span_t *span, char *state) -{ - unsigned int j; - int cnt=0; - ftdm_channel_state_t state_e = ftdm_str2ftdm_channel_state(state); - if (state_e == FTDM_CHANNEL_STATE_INVALID) { - ftdm_log(FTDM_LOG_CRIT, "Checking for channels not in the INVALID state is probably not what you want\n"); - } - for(j = 1; j <= span->chan_count; j++) { - if (span->channels[j]->state != state_e) { - ftdm_channel_t *ftdmchan = span->channels[j]; - ftdm_log(FTDM_LOG_CRIT, "Channel %i s%dc%d State=%s\n", - j, ftdmchan->physical_span_id-1, ftdmchan->physical_chan_id-1, ftdm_channel_state2str(ftdmchan->state)); - cnt++; - } - } - ftdm_log(FTDM_LOG_CRIT, "Total Channel Cnt %i\n",cnt); -} - -#define FTDM_BOOST_SYNTAX "list sigmods | | tracelevel " -/** - * \brief API function to kill or debug a sangoma_boost span - * \param stream API stream handler - * \param data String containing argurments - * \return Flags - */ -static FIO_API_FUNCTION(ftdm_sangoma_boost_api) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - - if (data) { - mycmd = ftdm_strdup(data); - argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (argc > 1) { - if (!strcasecmp(argv[0], "list")) { - if (!strcasecmp(argv[1], "sigmods")) { - if (ftdm_sangoma_boost_list_sigmods(stream) != FTDM_SUCCESS) { - stream->write_function(stream, "-ERR failed to list sigmods\n"); - goto done; - } - goto done; - } - - if (!strcasecmp(argv[1], "ids")) { - print_request_ids(); - goto done; - } - } else if (!strcasecmp(argv[0], "tracelevel")) { - ftdm_status_t status; - const char *levelname = NULL; - int dbglevel; - ftdm_sangoma_boost_data_t *sangoma_boost_data; - ftdm_span_t *span; - - if (argc <= 2) { - stream->write_function(stream, "-ERR usage: tracelevel \n"); - goto done; - } - - status = ftdm_span_find_by_name(argv[1], &span); - if (FTDM_SUCCESS != status) { - stream->write_function(stream, "-ERR failed to find span by name %s\n", argv[1]); - goto done; - } - - if (span->signal_type != FTDM_SIGTYPE_SANGOMABOOST) { - stream->write_function(stream, "-ERR span %s is not of boost type\n", argv[1]); - goto done; - } - - for (dbglevel = 0; (levelname = FTDM_LEVEL_NAMES[dbglevel]); dbglevel++) { - if (!strcasecmp(levelname, argv[2])) { - break; - } - } - - if (!levelname) { - stream->write_function(stream, "-ERR invalid log level %s\n", argv[2]); - goto done; - } - - sangoma_boost_data = span->signal_data; - sangoma_boost_data->pcon.debuglevel = dbglevel; - sangoma_boost_data->mcon.debuglevel = dbglevel; - stream->write_function(stream, "+OK span %s has now trace level %s\n", argv[1], FTDM_LEVEL_NAMES[dbglevel]); - goto done; -#ifndef __WINDOWS__ -#if 0 -/* NC: This code crashes the kernel due to fork on heavy fs load */ - } else if (!strcasecmp(argv[0], "ss7box_isupd_ckt")) { - - if (!strcasecmp(argv[1], "used")) { - stream->write_function(stream, "ss7box_isupd: in use\n", FTDM_BOOST_SYNTAX); - sigmod_ss7box_isup_exec_cmd(stream, (char*) "ckt_report.sh inuse"); - } else if (!strcasecmp(argv[1], "reset")) { - stream->write_function(stream, "ss7box_isupd: in reset\n", FTDM_BOOST_SYNTAX); - sigmod_ss7box_isup_exec_cmd(stream, (char*) "ckt_report.sh reset"); - } else if (!strcasecmp(argv[1], "ready")) { - stream->write_function(stream, "ss7box_isupd: ready \n", FTDM_BOOST_SYNTAX); - sigmod_ss7box_isup_exec_cmd(stream, (char*) "ckt_report.sh free"); - } else { - stream->write_function(stream, "ss7box_isupd: list\n", FTDM_BOOST_SYNTAX); - sigmod_ss7box_isup_exec_cmd(stream, (char*) "ckt_report.sh"); - } - - goto done; -#endif -#endif - - } else if (!strcasecmp(argv[0], "span")) { - int err; - sangomabc_connection_t *pcon; - ftdm_sangoma_boost_data_t *sangoma_boost_data; - ftdm_span_t *span; - - if (argc <= 2) { - stream->write_function(stream, "-ERR invalid span usage: span \n"); - goto done; - } - - err = ftdm_span_find_by_name(argv[1], &span); - if (FTDM_SUCCESS != err) { - stream->write_function(stream, "-ERR failed to find span by name %s\n",argv[1]); - goto done; - } - - if (!strcasecmp(argv[2], "restart")) { - sangoma_boost_data = span->signal_data; - pcon = &sangoma_boost_data->pcon; - - /* No need to set any span flags because - our RESTART will generate a RESTART from the sig daemon */ - sangomabc_exec_commandp(pcon, - 0, - 0, - -1, - SIGBOOST_EVENT_SYSTEM_RESTART, - 0); - } else if (!strcasecmp(argv[2], "state")) { - if (argc <= 3) { - stream->write_function(stream, "-ERR invalid span state: span state \n"); - goto done; - } - ftdm_cli_span_state_cmd(span,argv[3]); - } - - goto done; - - } else { - boost_sigmod_interface_t *sigmod_iface = NULL; - sigmod_iface = hashtable_search(g_boost_modules_hash, argv[0]); - if (sigmod_iface) { - char *p = strchr(data, ' '); - if (++p) { - char* mydup = strdup(p); - if(sigmod_iface->exec_api == NULL) { - stream->write_function(stream, "%s does not support api functions\n", sigmod_iface->name); - goto done; - } - //stream->write_function(stream, "sigmod:%s command:%s\n", sigmod_iface->name, mydup); - if (sigmod_iface->exec_api(stream, mydup) != FTDM_SUCCESS) { - stream->write_function(stream, "-ERR:failed to execute command:%s\n", mydup); - } - free(mydup); - } - - goto done; - } else { - stream->write_function(stream, "-ERR: Could not find sigmod %s\n", argv[0]); - } - } - } - stream->write_function(stream, "-ERR: Usage: %s\n", FTDM_BOOST_SYNTAX); -done: - ftdm_safe_free(mycmd); - return FTDM_SUCCESS; -} - -/** - * \brief Loads sangoma_boost IO module - * \param fio FreeTDM IO interface - * \return Success - */ -static FIO_IO_LOAD_FUNCTION(ftdm_sangoma_boost_io_init) -{ - ftdm_assert(fio != NULL, "fio is NULL"); - memset(&ftdm_sangoma_boost_interface, 0, sizeof(ftdm_sangoma_boost_interface)); - - ftdm_sangoma_boost_interface.name = "boost"; - ftdm_sangoma_boost_interface.api = ftdm_sangoma_boost_api; - - *fio = &ftdm_sangoma_boost_interface; - - return FTDM_SUCCESS; -} - -/** - * \brief Loads sangoma boost signaling module - * \param fio FreeTDM IO interface - * \return Success - */ -static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_boost_init) -{ - g_boost_modules_hash = create_hashtable(10, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - if (!g_boost_modules_hash) { - return FTDM_FAIL; - } - ftdm_mutex_create(&request_mutex); - ftdm_mutex_create(&g_boost_modules_mutex); - memset(&g_trunkgroups[0], 0, sizeof(g_trunkgroups)); - return FTDM_SUCCESS; -} - -static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_boost_destroy) -{ - ftdm_hash_iterator_t *i = NULL; - boost_sigmod_interface_t *sigmod = NULL; - const void *key = NULL; - void *val = NULL; - ftdm_dso_lib_t lib; - ftdm_log(FTDM_LOG_DEBUG, "Destroying sangoma boost module\n"); - for (i = hashtable_first(g_boost_modules_hash); i; i = hashtable_next(i)) { - hashtable_this(i, &key, NULL, &val); - if (key && val) { - sigmod = val; - lib = sigmod->pvt; - ftdm_log(FTDM_LOG_DEBUG, "destroying sigmod %s\n", sigmod->name); - sigmod->on_unload(); - ftdm_dso_destroy(&lib); - } - } - - hashtable_destroy(g_boost_modules_hash); - ftdm_mutex_destroy(&request_mutex); - ftdm_mutex_destroy(&g_boost_modules_mutex); - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_sangoma_boost_start(ftdm_span_t *span) -{ - int err; - - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - ftdm_set_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING); - err = ftdm_thread_create_detached(ftdm_sangoma_boost_run, span); - if (err) { - ftdm_clear_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING); - return err; - } - - // launch the events thread to handle HW DTMF and possibly - // other events in the future - ftdm_set_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_EVENTS_RUNNING); - err = ftdm_thread_create_detached(ftdm_sangoma_events_run, span); - if (err) { - ftdm_clear_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_EVENTS_RUNNING); - ftdm_clear_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING); - } - - return err; -} - -static ftdm_status_t ftdm_sangoma_boost_stop(ftdm_span_t *span) -{ - int cnt = 50; - ftdm_status_t status = FTDM_SUCCESS; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - if (sangoma_boost_data->sigmod) { - /* I think stopping the span before destroying the queue makes sense - otherwise may be boost events would still arrive when the queue is already destroyed! */ - status = sangoma_boost_data->sigmod->stop_span(span); - if (status != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to stop span %s boost signaling\n", span->name); - return FTDM_FAIL; - } - ftdm_queue_enqueue(sangoma_boost_data->boost_queue, NULL); - } - - while (ftdm_test_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING) && cnt-- > 0) { - ftdm_log(FTDM_LOG_DEBUG, "Waiting for boost thread\n"); - ftdm_sleep(100); - } - - if (!cnt) { - ftdm_log(FTDM_LOG_CRIT, "it seems boost thread in span %s may be stuck, we may segfault :-(\n", span->name); - return FTDM_FAIL; - } - - cnt = 50; - while (ftdm_test_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_EVENTS_RUNNING) && cnt-- > 0) { - ftdm_log(FTDM_LOG_DEBUG, "Waiting for boost events thread\n"); - ftdm_sleep(100); - } - - if (!cnt) { - ftdm_log(FTDM_LOG_CRIT, "it seems boost events thread in span %s may be stuck, we may segfault :-(\n", span->name); - return FTDM_FAIL; - } - - if (sangoma_boost_data->sigmod) { - ftdm_queue_destroy(&sangoma_boost_data->boost_queue); - } - - return status; -} - -static ftdm_state_map_t boost_state_map = { - { - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_ANY_STATE}, - {FTDM_CHANNEL_STATE_RESTART, FTDM_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESTART, FTDM_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_IDLE, FTDM_CHANNEL_STATE_HOLD, FTDM_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HOLD, FTDM_END}, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, - FTDM_CHANNEL_STATE_IDLE, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_HANGUP, FTDM_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_IDLE, FTDM_CHANNEL_STATE_DIALING, FTDM_END}, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_IDLE, FTDM_CHANNEL_STATE_DIALING, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_HANGUP, FTDM_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END} - }, - - /****************************************/ - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_ANY_STATE}, - {FTDM_CHANNEL_STATE_RESTART, FTDM_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESTART, FTDM_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN}, - {FTDM_CHANNEL_STATE_IN_LOOP, FTDM_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_IN_LOOP}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, - {FTDM_CHANNEL_STATE_RING, FTDM_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RING, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,FTDM_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_HANGUP, FTDM_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}, - }, - - - } -}; - -static BOOST_WRITE_MSG_FUNCTION(ftdm_boost_write_msg) -{ - sangomabc_short_event_t *shortmsg = NULL; - ftdm_sangoma_boost_data_t *sangoma_boost_data = NULL; - sangomabc_queue_element_t *element = NULL; - - ftdm_assert_return(msg != NULL, FTDM_FAIL, "Boost message to write was null"); - - if (!span) { - shortmsg = msg; - ftdm_log(FTDM_LOG_ERROR, "Unexpected boost message %d\n", shortmsg->event_id); - return FTDM_FAIL; - } - /* duplicate the event and enqueue it */ - element = ftdm_calloc(1, sizeof(*element)); - if (!element) { - return FTDM_FAIL; - } - memcpy(element->boostmsg, msg, msglen); - element->size = msglen; - - sangoma_boost_data = span->signal_data; - return ftdm_queue_enqueue(sangoma_boost_data->boost_queue, element); -} - -static BOOST_SIG_STATUS_CB_FUNCTION(ftdm_boost_sig_status_change) -{ - ftdm_sigmsg_t sig; - ftdm_log(FTDM_LOG_NOTICE, "%d:%d Signaling link status changed to %s\n", ftdmchan->span_id, ftdmchan->chan_id, ftdm_signaling_status2str(status)); - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = ftdmchan->chan_id; - sig.span_id = ftdmchan->span_id; - sig.channel = ftdmchan; - sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.ev_data.sigstatus.status = status; - ftdm_span_send_signal(ftdmchan->span, &sig); - return; -} - -static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(sangoma_boost_set_channel_sig_status) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - if (!sangoma_boost_data->sigmod) { - ftdm_log(FTDM_LOG_ERROR, "Cannot set signaling status in boost channel with no signaling module configured\n"); - return FTDM_FAIL; - } - if (!sangoma_boost_data->sigmod->set_channel_sig_status) { - ftdm_log(FTDM_LOG_ERROR, "Cannot set signaling status in boost channel: method not implemented\n"); - return FTDM_NOTIMPL; - } - return sangoma_boost_data->sigmod->set_channel_sig_status(ftdmchan, status); -} - -static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(sangoma_boost_get_channel_sig_status) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - if (!sangoma_boost_data->sigmod) { - return FTDM_FAIL; - } - if (!sangoma_boost_data->sigmod->get_channel_sig_status) { - return FTDM_NOTIMPL; - } - return sangoma_boost_data->sigmod->get_channel_sig_status(ftdmchan, status); -} - -static FIO_SPAN_SET_SIG_STATUS_FUNCTION(sangoma_boost_set_span_sig_status) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - if (!sangoma_boost_data->sigmod) { - ftdm_log(FTDM_LOG_ERROR, "Cannot set signaling status in boost span with no signaling module configured\n"); - return FTDM_FAIL; - } - if (!sangoma_boost_data->sigmod->set_span_sig_status) { - ftdm_log(FTDM_LOG_ERROR, "Cannot set signaling status in boost span: method not implemented\n"); - return FTDM_NOTIMPL; - } - return sangoma_boost_data->sigmod->set_span_sig_status(span, status); -} - -static FIO_SPAN_GET_SIG_STATUS_FUNCTION(sangoma_boost_get_span_sig_status) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - if (!sangoma_boost_data->sigmod) { - return FTDM_FAIL; - } - if (!sangoma_boost_data->sigmod->get_span_sig_status) { - ftdm_log(FTDM_LOG_ERROR, "Cannot get signaling status in boost span: method not implemented\n"); - return FTDM_NOTIMPL; - } - return sangoma_boost_data->sigmod->get_span_sig_status(span, status); -} - -/** - * \brief Initialises an sangoma boost span from configuration variables - * \param span Span to configure - * \param sig_cb Callback function for event signals - * \param ap List of configuration variables - * \return Success or failure - */ -static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_boost_configure_span) -{ -#define FAIL_CONFIG_RETURN(retstatus) \ - if (sangoma_boost_data) \ - ftdm_safe_free(sangoma_boost_data); \ - if (err) \ - ftdm_safe_free(err) \ - if (hash_locked) \ - ftdm_mutex_unlock(g_boost_modules_mutex); \ - if (lib) \ - ftdm_dso_destroy(&lib); \ - return retstatus; - - boost_sigmod_interface_t *sigmod_iface = NULL; - ftdm_sangoma_boost_data_t *sangoma_boost_data = NULL; - const char *local_ip = "127.0.0.65", *remote_ip = "127.0.0.66"; - const char *sigmod = NULL; - int local_port = 53000, remote_port = 53000; - const char *var = NULL, *val = NULL; - int hash_locked = 0; - ftdm_dso_lib_t lib = NULL; - char path[255] = ""; - char *err = NULL; - unsigned int j = 0; - unsigned paramindex = 0; - ftdm_status_t rc = FTDM_SUCCESS; - - for (; ftdm_parameters[paramindex].var; paramindex++) { - var = ftdm_parameters[paramindex].var; - val = ftdm_parameters[paramindex].val; - if (!strcasecmp(var, "sigmod")) { - sigmod = val; - } else if (!strcasecmp(var, "local_ip")) { - local_ip = val; - } else if (!strcasecmp(var, "remote_ip")) { - remote_ip = val; - } else if (!strcasecmp(var, "local_port")) { - local_port = atoi(val); - } else if (!strcasecmp(var, "remote_port")) { - remote_port = atoi(val); - } else if (!strcasecmp(var, "outbound-called-ton")) { - ftdm_set_ton(val, &span->default_caller_data.dnis.type); - } else if (!strcasecmp(var, "outbound-called-npi")) { - ftdm_set_npi(val, &span->default_caller_data.dnis.plan); - } else if (!strcasecmp(var, "outbound-calling-ton")) { - ftdm_set_ton(val, &span->default_caller_data.cid_num.type); - } else if (!strcasecmp(var, "outbound-calling-npi")) { - ftdm_set_npi(val, &span->default_caller_data.cid_num.plan); - } else if (!strcasecmp(var, "outbound-rdnis-ton")) { - ftdm_set_ton(val, &span->default_caller_data.rdnis.type); - } else if (!strcasecmp(var, "outbound-rdnis-npi")) { - ftdm_set_npi(val, &span->default_caller_data.rdnis.plan); - } else if (!sigmod) { - snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var); - FAIL_CONFIG_RETURN(FTDM_FAIL); - } - } - - if (!sigmod) { -#ifndef HAVE_NETINET_SCTP_H - ftdm_log(FTDM_LOG_CRIT, "No sigmod attribute in span %s, you must either specify a sigmod or re-compile with SCTP available to use socket mode boost!\n", span->name); - ftdm_set_string(span->last_error, "No sigmod configuration was set and there is no SCTP available!"); - FAIL_CONFIG_RETURN(FTDM_FAIL); -#else - if (!local_ip && local_port && remote_ip && remote_port && sig_cb) { - ftdm_set_string(span->last_error, "missing Sangoma boost IP parameters"); - FAIL_CONFIG_RETURN(FTDM_FAIL); - } -#endif - } - - sangoma_boost_data = ftdm_calloc(1, sizeof(*sangoma_boost_data)); - if (!sangoma_boost_data) { - FAIL_CONFIG_RETURN(FTDM_FAIL); - } - - /* WARNING: be sure to release this mutex on errors inside this if() */ - ftdm_mutex_lock(g_boost_modules_mutex); - hash_locked = 1; - if (sigmod && !(sigmod_iface = hashtable_search(g_boost_modules_hash, (void *)sigmod))) { - ftdm_build_dso_path(sigmod, path, sizeof(path)); - lib = ftdm_dso_open(path, &err); - if (!lib) { - ftdm_log(FTDM_LOG_ERROR, "Error loading Sangoma boost signaling module '%s': %s\n", path, err); - snprintf(span->last_error, sizeof(span->last_error), "Failed to load sangoma boost signaling module %s", path); - - FAIL_CONFIG_RETURN(FTDM_FAIL); - } - if (!(sigmod_iface = (boost_sigmod_interface_t *)ftdm_dso_func_sym(lib, BOOST_INTERFACE_NAME_STR, &err))) { - ftdm_log(FTDM_LOG_ERROR, "Failed to read Sangoma boost signaling module interface '%s': %s\n", path, err); - snprintf(span->last_error, sizeof(span->last_error), "Failed to read Sangoma boost signaling module interface '%s': %s", path, err); - - FAIL_CONFIG_RETURN(FTDM_FAIL); - } - rc = sigmod_iface->on_load(); - if (rc != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to load Sangoma boost signaling module interface '%s': on_load method failed (%d)\n", path, rc); - FAIL_CONFIG_RETURN(FTDM_FAIL); - } - sigmod_iface->pvt = lib; - sigmod_iface->set_write_msg_cb(ftdm_boost_write_msg); - sigmod_iface->set_sig_status_cb(ftdm_boost_sig_status_change); - hashtable_insert(g_boost_modules_hash, (void *)sigmod_iface->name, sigmod_iface, HASHTABLE_FLAG_NONE); - lib = NULL; /* destroying the lib will be done when going down and NOT on FAIL_CONFIG_RETURN */ - } - ftdm_mutex_unlock(g_boost_modules_mutex); - hash_locked = 0; - - if (sigmod_iface) { - /* try to create the boost queue */ - if (ftdm_queue_create(&sangoma_boost_data->boost_queue, BOOST_QUEUE_SIZE) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Span %s could not create its boost queue!\n", span->name); - FAIL_CONFIG_RETURN(FTDM_FAIL); - } - ftdm_log(FTDM_LOG_NOTICE, "Span %s will use Sangoma Boost Signaling Module %s\n", span->name, sigmod_iface->name); - sangoma_boost_data->sigmod = sigmod_iface; - sigmod_iface->configure_span(span, ftdm_parameters); - } else { - ftdm_log(FTDM_LOG_NOTICE, "Span %s will use boost socket mode\n", span->name); - ftdm_set_string(sangoma_boost_data->mcon.cfg.local_ip, local_ip); - sangoma_boost_data->mcon.cfg.local_port = local_port; - ftdm_set_string(sangoma_boost_data->mcon.cfg.remote_ip, remote_ip); - sangoma_boost_data->mcon.cfg.remote_port = remote_port; - } - - for (j = 1; j <= span->chan_count; j++) { - span->channels[j]->call_data = ftdm_calloc(1, sizeof(sangoma_boost_call_t)); - if (!span->channels[j]->call_data) { - FAIL_CONFIG_RETURN(FTDM_FAIL); - } - } - - span->signal_cb = sig_cb; - span->start = ftdm_sangoma_boost_start; - span->stop = ftdm_sangoma_boost_stop; - span->signal_data = sangoma_boost_data; - span->signal_type = FTDM_SIGTYPE_SANGOMABOOST; - span->outgoing_call = sangoma_boost_outgoing_call; - span->channel_request = sangoma_boost_channel_request; - span->get_channel_sig_status = sangoma_boost_get_channel_sig_status; - span->set_channel_sig_status = sangoma_boost_set_channel_sig_status; - span->get_span_sig_status = sangoma_boost_get_span_sig_status; - span->set_span_sig_status = sangoma_boost_set_span_sig_status; - span->state_map = &boost_state_map; - span->state_processor = state_advance; - sangoma_boost_data->mcon.debuglevel = FTDM_LOG_LEVEL_DEBUG; - sangoma_boost_data->pcon.debuglevel = FTDM_LOG_LEVEL_DEBUG; - ftdm_clear_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID); - ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE); - if (sigmod_iface) { - /* the core will do the hunting */ - span->channel_request = NULL; - } - ftdm_set_flag_locked(span, FTDM_SPAN_SUSPENDED); - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_sangoma_boost_list_sigmods(ftdm_stream_handle_t *stream) -{ - ftdm_hash_iterator_t *i = NULL; - boost_sigmod_interface_t *sigmod_iface = NULL; - const void *key = NULL; - void *val = NULL; - - stream->write_function(stream, "List of loaded sigmod modules:\n"); - for (i = hashtable_first(g_boost_modules_hash); i; i = hashtable_next(i)) { - hashtable_this(i, &key, NULL, &val); - if (key && val) { - sigmod_iface = val; - stream->write_function(stream, " %s\n", sigmod_iface->name); - } - } - stream->write_function(stream, "\n"); - return FTDM_SUCCESS; -} - -/** - * \brief FreeTDM sangoma boost signaling module definition - */ -EX_DECLARE_DATA ftdm_module_t ftdm_module = { - /*.name =*/ "sangoma_boost", - /*.io_load =*/ ftdm_sangoma_boost_io_init, - /*.io_unload =*/ NULL, - /*.sig_load = */ ftdm_sangoma_boost_init, - /*.sig_configure =*/ NULL, - /*.sig_unload = */ftdm_sangoma_boost_destroy, - /*.configure_span_signaling = */ ftdm_sangoma_boost_configure_span -}; - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.c deleted file mode 100644 index 6ddb74d253..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Copyright (c) 2007, Anthony Minessale II, Nenad Corbic - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _GNU_SOURCE - -#if HAVE_NETDB_H -#include -#endif - -#include "freetdm.h" -#include "sangoma_boost_client.h" - -#ifndef HAVE_GETHOSTBYNAME_R -extern int gethostbyname_r (const char *__name, - struct hostent *__result_buf, - char *__buf, size_t __buflen, - struct hostent **__result, - int *__h_errnop); -#endif - -struct sangomabc_map { - uint32_t event_id; - const char *name; -}; - -static struct sangomabc_map sangomabc_table[] = { - {SIGBOOST_EVENT_CALL_START, "CALL_START"}, - {SIGBOOST_EVENT_CALL_START_ACK, "CALL_START_ACK"}, - {SIGBOOST_EVENT_CALL_START_NACK, "CALL_START_NACK"}, - {SIGBOOST_EVENT_CALL_PROGRESS, "CALL PROGRESS"}, - {SIGBOOST_EVENT_CALL_START_NACK_ACK, "CALL_START_NACK_ACK"}, - {SIGBOOST_EVENT_CALL_ANSWERED, "CALL_ANSWERED"}, - {SIGBOOST_EVENT_CALL_STOPPED, "CALL_STOPPED"}, - {SIGBOOST_EVENT_CALL_STOPPED_ACK, "CALL_STOPPED_ACK"}, - {SIGBOOST_EVENT_CALL_RELEASED, "CALL_RELEASED"}, - {SIGBOOST_EVENT_SYSTEM_RESTART, "SYSTEM_RESTART"}, - {SIGBOOST_EVENT_SYSTEM_RESTART_ACK, "SYSTEM_RESTART_ACK"}, - {SIGBOOST_EVENT_HEARTBEAT, "HEARTBEAT"}, - {SIGBOOST_EVENT_INSERT_CHECK_LOOP, "LOOP START"}, - {SIGBOOST_EVENT_REMOVE_CHECK_LOOP, "LOOP STOP"}, - {SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE, "AUTO_CALL_GAP_ABATE"}, - {SIGBOOST_EVENT_DIGIT_IN, "DIGIT_IN"} -}; - - - -static void sangomabc_print_event_call(sangomabc_connection_t *mcon, sangomabc_event_t *event, int priority, int dir, const char *file, const char *func, int line) -{ - if (event->event_id == SIGBOOST_EVENT_HEARTBEAT) - return; - - ftdm_log(file, func, line, mcon->debuglevel, "%s EVENT (%s): %s:(%X) [w%dg%d] CSid=%i Seq=%i Cn=[%s] Cd=[%s] Ci=[%s] Rdnis=[%s]\n", - dir ? "TX":"RX", - priority ? "P":"N", - sangomabc_event_id_name(event->event_id), - event->event_id, - BOOST_EVENT_SPAN(mcon->sigmod, event), - BOOST_EVENT_CHAN(mcon->sigmod, event), - event->call_setup_id, - event->fseqno, - strlen(event->calling_name)?event->calling_name:"N/A", - (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), - (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"), - event->isup_in_rdnis); - -} -static void sangomabc_print_event_short(sangomabc_connection_t *mcon, sangomabc_short_event_t *event, int priority, int dir, const char *file, const char *func, int line) -{ - if (event->event_id == SIGBOOST_EVENT_HEARTBEAT) - return; - ftdm_log(file, func, line, mcon->debuglevel, "%s EVENT (%s): %s:(%X) [s%dc%d] Rc=%i CSid=%i Seq=%i \n", - dir ? "TX":"RX", - priority ? "P":"N", - sangomabc_event_id_name(event->event_id), - event->event_id, - BOOST_EVENT_SPAN(mcon->sigmod, event), - BOOST_EVENT_CHAN(mcon->sigmod, event), - event->release_cause, - event->call_setup_id, - event->fseqno); -} - - -static int create_conn_socket(sangomabc_connection_t *mcon, char *local_ip, int local_port, char *ip, int port) -{ -#ifndef WIN32 - int rc; - struct hostent *result, *local_result; - char buf[512], local_buf[512]; - int err = 0, local_err = 0; - - if (mcon->sigmod) { - ftdm_log(FTDM_LOG_WARNING, "I should not be called on a sigmod-managed connection!\n"); - return 0; - } - - memset(&mcon->remote_hp, 0, sizeof(mcon->remote_hp)); - memset(&mcon->local_hp, 0, sizeof(mcon->local_hp)); -#ifdef HAVE_NETINET_SCTP_H - ftdm_log(FTDM_LOG_DEBUG, "Creating SCTP socket L=%s:%d R=%s:%d\n", - local_ip, local_port, ip, port); - mcon->socket = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); -#else - ftdm_log(FTDM_LOG_DEBUG, "Creating UDP socket L=%s:%d R=%s:%d\n", - local_ip, local_port, ip, port); - mcon->socket = socket(AF_INET, SOCK_DGRAM, 0); -#endif - - if (mcon->socket >= 0) { - int flag; - - flag = 1; -#ifdef HAVE_GETHOSTBYNAME_R_FIVE - gethostbyname_r(ip, &mcon->remote_hp, buf, sizeof(buf), &err); - gethostbyname_r(local_ip, &mcon->local_hp, local_buf, sizeof(local_buf), &local_err); - if (!err && !local_err) { -#else - gethostbyname_r(ip, &mcon->remote_hp, buf, sizeof(buf), &result, &err); - gethostbyname_r(local_ip, &mcon->local_hp, local_buf, sizeof(local_buf), &local_result, &local_err); - if (result && local_result) { -#endif - mcon->remote_addr.sin_family = mcon->remote_hp.h_addrtype; - memcpy((char *) &mcon->remote_addr.sin_addr.s_addr, mcon->remote_hp.h_addr_list[0], mcon->remote_hp.h_length); - mcon->remote_addr.sin_port = htons(port); - - mcon->local_addr.sin_family = mcon->local_hp.h_addrtype; - memcpy((char *) &mcon->local_addr.sin_addr.s_addr, mcon->local_hp.h_addr_list[0], mcon->local_hp.h_length); - mcon->local_addr.sin_port = htons(local_port); - -#ifdef HAVE_NETINET_SCTP_H - setsockopt(mcon->socket, IPPROTO_SCTP, SCTP_NODELAY, - (char *)&flag, sizeof(int)); -#endif - - if ((rc = bind(mcon->socket, - (struct sockaddr *) &mcon->local_addr, - sizeof(mcon->local_addr))) < 0) { - close(mcon->socket); - mcon->socket = -1; - } else { -#ifdef HAVE_NETINET_SCTP_H - rc=listen(mcon->socket, 100); - if (rc) { - close(mcon->socket); - mcon->socket = -1; - } -#endif - } - } - } - - return mcon->socket; -#else - return 0; -#endif // ifndef WIN32 -} - -int sangomabc_connection_close(sangomabc_connection_t *mcon) -{ -#ifndef WIN32 - if (mcon->sigmod) { - ftdm_log(FTDM_LOG_WARNING, "I should not be called on a sigmod-managed connection!\n"); - return 0; - } - if (mcon->socket > -1) { - close(mcon->socket); - } - - if (mcon->mutex) { - ftdm_mutex_lock(mcon->mutex); - ftdm_mutex_unlock(mcon->mutex); - ftdm_mutex_destroy(&mcon->mutex); - } - memset(mcon, 0, sizeof(*mcon)); - mcon->socket = -1; -#endif - return 0; -} - -int sangomabc_connection_open(sangomabc_connection_t *mcon, char *local_ip, int local_port, char *ip, int port) -{ - ftdm_mutex_create(&mcon->mutex); - if (mcon->sigmod) { - /*value of mcon->socket will be ignored in sigmod mode */ - return 0; - } -#ifndef WIN32 - create_conn_socket(mcon, local_ip, local_port, ip, port); - return mcon->socket; -#else - return 0; -#endif -} - - -int sangomabc_exec_command(sangomabc_connection_t *mcon, int span, int chan, int id, int cmd, int cause, int flags) -{ - sangomabc_event_t *oevent; - sangomabc_short_event_t sevent; - sangomabc_event_t fevent; - int retry = 5; - - if (boost_full_event(cmd)) { - sangomabc_event_init((void *)&fevent, cmd, chan, span); - oevent = &fevent; - } else { - sangomabc_event_init(&sevent, cmd, chan, span); - sevent.release_cause = (uint8_t)cause; - oevent = (sangomabc_event_t *)&sevent; - } - oevent->flags = flags; - - if (cmd == SIGBOOST_EVENT_SYSTEM_RESTART || cmd == SIGBOOST_EVENT_SYSTEM_RESTART_ACK) { - mcon->rxseq_reset = 1; - mcon->txseq = 0; - mcon->rxseq = 0; - mcon->txwindow = 0; - } - - if (id >= 0) { - oevent->call_setup_id = (uint16_t)id; - } - - while (sangomabc_connection_write(mcon, (sangomabc_event_t*)oevent) <= 0) { - if (--retry <= 0) { - ftdm_log(FTDM_LOG_CRIT, "Failed to tx on boost socket: %s\n", strerror(errno)); - return -1; - } else { - ftdm_log(FTDM_LOG_WARNING, "Failed to tx on boost socket: %s :retry %i\n", strerror(errno), retry); - ftdm_sleep(1); - } - } - - return 0; -} - - -int sangomabc_exec_commandp(sangomabc_connection_t *pcon, int span, int chan, int id, int cmd, int cause) -{ - sangomabc_short_event_t oevent; - int retry = 5; - - sangomabc_event_init(&oevent, cmd, chan, span); - oevent.release_cause = (uint8_t)cause; - - if (id >= 0) { - oevent.call_setup_id = (uint16_t)id; - } - - while (sangomabc_connection_writep(pcon, (sangomabc_event_t*)&oevent) <= 0) { - if (--retry <= 0) { - ftdm_log(FTDM_LOG_CRIT, "Failed to tx on boost socket: %s\n", strerror(errno)); - return -1; - } else { - ftdm_log(FTDM_LOG_WARNING, "Failed to tx on boost socket: %s :retry %i\n", strerror(errno), retry); - ftdm_sleep(1); - } - } - - return 0; -} - -sangomabc_event_t *__sangomabc_connection_read(sangomabc_connection_t *mcon, int iteration, const char *file, const char *func, int line) -{ -#ifndef WIN32 - unsigned int fromlen = sizeof(struct sockaddr_in); -#endif - int bytes = 0; - int msg_ok = 0; - sangomabc_queue_element_t *e = NULL; - - if (mcon->sigmod) { - e = ftdm_queue_dequeue(mcon->boost_queue); - if (e) { - bytes = (int)e->size; - memcpy(&mcon->event, e->boostmsg, bytes); - ftdm_safe_free(e); - } - } -#ifndef WIN32 - else { - bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, - (struct sockaddr *) &mcon->local_addr, &fromlen); - } -#endif - if (bytes <= 0) { - return NULL; - } - - if (mcon->event.version != SIGBOOST_VERSION) { - ftdm_log(FTDM_LOG_CRIT, "Invalid Boost Version %i Expecting %i\n",mcon->event.version, SIGBOOST_VERSION); - } - - if ((bytes >= MIN_SIZE_CALLSTART_MSG) && boost_full_event(mcon->event.event_id)) { - msg_ok=1; - - } else if (bytes == sizeof(sangomabc_short_event_t)) { - msg_ok=1; - - } else { - msg_ok=0; - } - - if (msg_ok) { - if (sangomabc_test_flag(mcon, MSU_FLAG_DOWN)) { - if (mcon->event.event_id != SIGBOOST_EVENT_SYSTEM_RESTART && - mcon->event.event_id != SIGBOOST_EVENT_SYSTEM_RESTART_ACK && - mcon->event.event_id != SIGBOOST_EVENT_HEARTBEAT) { - ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "Not reading packets when connection is down. [%s]\n", - sangomabc_event_id_name(mcon->event.event_id)); - return NULL; - } - } - - if (boost_full_event(mcon->event.event_id)) { - sangomabc_print_event_call(mcon, &mcon->event, 0, 0, file, func, line); - } else { - sangomabc_print_event_short(mcon, (sangomabc_short_event_t*)&mcon->event, 0, 0, file, func, line); - } - -#if 0 -/* NC: NOT USED ANY MORE */ - if (mcon->rxseq_reset) { - //if (mcon->event.event_id == SIGBOOST_EVENT_SYSTEM_RESTART_ACK) { - ftdm_log(FTDM_LOG_DEBUG, "Rx sync ok\n"); - mcon->rxseq = mcon->event.fseqno; - return &mcon->event; - //} - errno=EAGAIN; - ftdm_log(FTDM_LOG_DEBUG, "Waiting for rx sync...\n"); - return NULL; - } -#endif - - mcon->txwindow = mcon->txseq - mcon->event.bseqno; - mcon->rxseq++; - -#if 0 - if (mcon->rxseq != mcon->event.fseqno) { - ftdm_log(FTDM_LOG_CRIT, "Invalid Sequence Number Expect=%i Rx=%i\n", mcon->rxseq, mcon->event.fseqno); - return NULL; - } -#endif - - return &mcon->event; - } else { - if (iteration == 0) { - ftdm_log(FTDM_LOG_CRIT, "NC - Invalid Event length from boost rxlen=%i evsz=%i\n", bytes, sizeof(mcon->event)); - return NULL; - } - } - - return NULL; -} - -sangomabc_event_t *__sangomabc_connection_readp(sangomabc_connection_t *mcon, int iteration, const char *file, const char *func, int line) -{ -#ifndef WIN32 - unsigned int fromlen = sizeof(struct sockaddr_in); -#endif - int bytes = 0; - - if (mcon->sigmod) { - /* priority stuff is handled just the same when there is a sigmod */ - return sangomabc_connection_read(mcon, iteration); - } -#ifndef WIN32 - else { - bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, (struct sockaddr *) &mcon->local_addr, &fromlen); - } -#endif - if (bytes <= 0) { - return NULL; - } - - if (mcon->event.version != SIGBOOST_VERSION) { - ftdm_log(FTDM_LOG_CRIT, "Invalid Boost Version %i Expecting %i\n",mcon->event.version, SIGBOOST_VERSION); - } - - if (bytes == sizeof(sangomabc_short_event_t)) { - - if (boost_full_event(mcon->event.event_id)) { - sangomabc_print_event_call(mcon, &mcon->event, 1, 0, file, func, line); - } else { - sangomabc_print_event_short(mcon, (sangomabc_short_event_t*)&mcon->event, 1, 0, file, func, line); - } - - return &mcon->event; - } else { - if (iteration == 0) { - ftdm_log(FTDM_LOG_CRIT, "Critical Error: PQ Invalid Event lenght from boost rxlen=%i evsz=%i\n", bytes, sizeof(mcon->event)); - return NULL; - } - } - - return NULL; -} - - -int __sangomabc_connection_write(sangomabc_connection_t *mcon, sangomabc_event_t *event, const char *file, const char *func, int line) -{ - int err = 0; - int event_size=MIN_SIZE_CALLSTART_MSG+event->isup_in_rdnis_size; - - ftdm_assert_return(event != NULL, -1, "No event!"); - ftdm_assert_return(mcon->socket >= 0, -1, "No mcon->socket!"); - ftdm_assert_return(mcon->mutex != NULL, -1, "No mcon->mutex!"); - - ftdm_assert_return(event->span <= FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN, -1, "Invalid span when writing boost event\n"); - ftdm_assert_return(event->chan <= FTDM_MAX_CHANNELS_PHYSICAL_SPAN, -1, "Invalid chan when writing boost event\n"); - - if (!boost_full_event(event->event_id)) { - event_size=sizeof(sangomabc_short_event_t); - } - - if (sangomabc_test_flag(mcon, MSU_FLAG_DOWN)) { - if (event->event_id != SIGBOOST_EVENT_SYSTEM_RESTART && - event->event_id != SIGBOOST_EVENT_SYSTEM_RESTART_ACK && - event->event_id != SIGBOOST_EVENT_HEARTBEAT) { - ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "Not writing packets when connection is down. [%s]\n", - sangomabc_event_id_name(event->event_id)); - return 0; - } - } - - ftdm_mutex_lock(mcon->mutex); - if (event->event_id == SIGBOOST_EVENT_SYSTEM_RESTART_ACK) { - mcon->txseq=0; - mcon->rxseq=0; - event->fseqno=0; - } else { - event->fseqno = mcon->txseq++; - } - event->bseqno = mcon->rxseq; - event->version = SIGBOOST_VERSION; - - if (boost_full_event(event->event_id)) { - sangomabc_print_event_call(mcon, event, 0, 1, file, func, line); - } else { - sangomabc_print_event_short(mcon, (sangomabc_short_event_t*)event, 0, 1, file, func, line); - } - - if (mcon->sigmod) { - mcon->sigmod->write_msg(mcon->span, event, event_size); - err = event_size; - } -#ifndef WIN32 - else { - err = sendto(mcon->socket, event, event_size, 0, (struct sockaddr *) &mcon->remote_addr, sizeof(mcon->remote_addr)); - } -#endif - - ftdm_mutex_unlock(mcon->mutex); - - ftdm_assert_return(err == event_size, -1, "Failed to send the boost message completely!"); - - return err; -} - - -int __sangomabc_connection_writep(sangomabc_connection_t *mcon, sangomabc_event_t *event, const char *file, const char *func, int line) -{ - int err = 0; - int event_size=sizeof(sangomabc_event_t); - - if (!mcon->sigmod) { - ftdm_assert_return(event != NULL, -1, "No event!"); - ftdm_assert_return(mcon->socket >= 0, -1, "No mcon->socket!"); - ftdm_assert_return(mcon->mutex != NULL, -1, "No mcon->mutex!"); - } - - if (!boost_full_event(event->event_id)) { - event_size=sizeof(sangomabc_short_event_t); - } - - ftdm_mutex_lock(mcon->mutex); - event->version = SIGBOOST_VERSION; - if (mcon->sigmod) { - mcon->sigmod->write_msg(mcon->span, event, event_size); - err = event_size; - - } -#ifndef WIN32 - else { - err = sendto(mcon->socket, event, event_size, 0, (struct sockaddr *) &mcon->remote_addr, sizeof(mcon->remote_addr)); - } -#endif - ftdm_mutex_unlock(mcon->mutex); - - ftdm_assert_return(err == event_size, -1, "Failed to send boost message completely!"); - - if (boost_full_event(event->event_id)) { - sangomabc_print_event_call(mcon, event, 1, 1, file, func, line); - } else { - sangomabc_print_event_short(mcon, (sangomabc_short_event_t*)event, 1, 1, file, func, line); - } - - return err; -} - - -void sangomabc_call_init(sangomabc_event_t *event, const char *calling, const char *called, int setup_id) -{ - memset(event, 0, sizeof(sangomabc_event_t)); - event->event_id = SIGBOOST_EVENT_CALL_START; - - if (calling) { - strncpy((char*)event->calling_number_digits, calling, sizeof(event->calling_number_digits)-1); - event->calling_number_digits_count = (uint8_t)strlen(calling); - } - - if (called) { - strncpy((char*)event->called_number_digits, called, sizeof(event->called_number_digits)-1); - event->called_number_digits_count = (uint8_t)strlen(called); - } - - event->call_setup_id = (uint16_t)setup_id; - -} - -void sangomabc_event_init(sangomabc_short_event_t *event, sangomabc_event_id_t event_id, int chan, int span) -{ - if (boost_full_event(event_id)) { - memset(event, 0, sizeof(sangomabc_event_t)); - } else { - memset(event, 0, sizeof(sangomabc_short_event_t)); - } - event->event_id = event_id; - event->chan = (uint8_t)chan; - event->span = (uint8_t)span; -} - -const char *sangomabc_event_id_name(uint32_t event_id) -{ - unsigned int x; - const char *ret = NULL; - - for (x = 0 ; x < sizeof(sangomabc_table)/sizeof(struct sangomabc_map); x++) { - if (sangomabc_table[x].event_id == event_id) { - ret = sangomabc_table[x].name; - break; - } - } - - return ret; -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.h b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.h deleted file mode 100644 index e333c4aba3..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2007, Anthony Minessale II, Nenad Corbic - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _SANGOMABC_H -#define _SANGOMABC_H - -#include "sangoma_boost_interface.h" - -#include -#include -#ifndef WIN32 -#include -#include -#include -#ifdef HAVE_NETINET_SCTP_H -#include -#endif -#include -#include -#include -#endif -#include -#include -#include -#include -#include -#include -#include "sigboost.h" - -#define sangomabc_test_flag(p,flag) ((p)->flags & (flag)) - -#define sangomabc_set_flag(p,flag) do { \ - ((p)->flags |= (flag)); \ - } while (0) - -#define sangomabc_clear_flag(p,flag) do { \ - ((p)->flags &= ~(flag)); \ - } while (0) - -#define sangomabc_copy_flags(dest,src,flagz) do { \ - (dest)->flags &= ~(flagz); \ - (dest)->flags |= ((src)->flags & (flagz)); \ - } while (0) - -typedef t_sigboost_callstart sangomabc_event_t; -typedef t_sigboost_short sangomabc_short_event_t; -typedef uint32_t sangomabc_event_id_t; - -typedef struct sangomabc_ip_cfg -{ - char local_ip[25]; - int local_port; - char remote_ip[25]; - int remote_port; -}sangomabc_ip_cfg_t; - -typedef enum { - MSU_FLAG_EVENT = (1 << 0), - MSU_FLAG_DOWN = (1 << 1) -} sangomabc_flag_t; - - -struct sangomabc_connection { - ftdm_socket_t socket; - struct sockaddr_in local_addr; - struct sockaddr_in remote_addr; - sangomabc_event_t event; - struct hostent remote_hp; - struct hostent local_hp; - unsigned int flags; - ftdm_mutex_t *mutex; - FILE *log; - unsigned int txseq; - unsigned int rxseq; - unsigned int txwindow; - unsigned int rxseq_reset; - sangomabc_ip_cfg_t cfg; - /* boost signaling mod interface pointer (if not working in TCP mode) */ - boost_sigmod_interface_t *sigmod; - ftdm_queue_t *boost_queue; - ftdm_interrupt_t *sock_interrupt; - ftdm_span_t *span; - int debuglevel; -}; - -typedef struct sangomabc_connection sangomabc_connection_t; - -typedef struct sangomabc_queue_element { - unsigned char boostmsg[sizeof(sangomabc_event_t)]; - ftdm_size_t size; -} sangomabc_queue_element_t; - -/* disable nagle's algorythm */ -static __inline__ void sctp_no_nagle(int socket) -{ -#ifdef HAVE_NETINET_SCTP_H - int flag = 1; - setsockopt(socket, IPPROTO_SCTP, SCTP_NODELAY, (char *) &flag, sizeof(int)); -#endif -} - -int sangomabc_connection_close(sangomabc_connection_t *mcon); -int sangomabc_connection_open(sangomabc_connection_t *mcon, char *local_ip, int local_port, char *ip, int port); -sangomabc_event_t *__sangomabc_connection_read(sangomabc_connection_t *mcon, int iteration, const char *file, const char *func, int line); -sangomabc_event_t *__sangomabc_connection_readp(sangomabc_connection_t *mcon, int iteration, const char *file, const char *func, int line); -int __sangomabc_connection_write(sangomabc_connection_t *mcon, sangomabc_event_t *event, const char *file, const char *func, int line); -int __sangomabc_connection_writep(sangomabc_connection_t *mcon, sangomabc_event_t *event, const char *file, const char *func, int line); -#define sangomabc_connection_write(_m,_e) __sangomabc_connection_write(_m, _e, __FILE__, __FUNCTION__, __LINE__) -#define sangomabc_connection_writep(_m,_e) __sangomabc_connection_writep(_m, _e, __FILE__, __FUNCTION__, __LINE__) -#define sangomabc_connection_read(_m,_e) __sangomabc_connection_read(_m, _e, __FILE__, __FUNCTION__, __LINE__) -#define sangomabc_connection_readp(_m,_e) __sangomabc_connection_readp(_m, _e, __FILE__, __FUNCTION__, __LINE__) -void sangomabc_event_init(sangomabc_short_event_t *event, sangomabc_event_id_t event_id, int chan, int span); -void sangomabc_call_init(sangomabc_event_t *event, const char *calling, const char *called, int setup_id); -const char *sangomabc_event_id_name(uint32_t event_id); -int sangomabc_exec_command(sangomabc_connection_t *mcon, int span, int chan, int id, int cmd, int cause, int flags); -int sangomabc_exec_commandp(sangomabc_connection_t *pcon, int span, int chan, int id, int cmd, int cause); - -#define BOOST_EVENT_SPAN(sigmod, event) ((sigmod) ? event->span : event->span + 1) -#define BOOST_EVENT_CHAN(sigmod, event) ((sigmod) ? event->chan : event->chan + 1) - - -#endif - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_interface.h b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_interface.h deleted file mode 100644 index f6130db444..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_interface.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2009, Sangoma Technologies - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SANGOMA_BOOST_INTERFACE_H -#define SANGOMA_BOOST_INTERFACE_H - -#include "private/ftdm_core.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - \brief Callback used to notify signaling status changes on a channel - \param ftdmchan The freetdm channel where the signaling status just changed - \param status The new signaling status - */ -#define BOOST_SIG_STATUS_CB_ARGS (ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status) -typedef void (*boost_sig_status_cb_func_t) BOOST_SIG_STATUS_CB_ARGS; -#define BOOST_SIG_STATUS_CB_FUNCTION(name) void name BOOST_SIG_STATUS_CB_ARGS - -/*! - \brief Write a boost msg to a boost endpoint - \param span The freetdm span where this msg was generated - \param msg The generic message pointer, owned by the caller - \param msglen The length of the provided structure pointed by msg - \return FTDM_SUCCESS or FTDM_FAIL - - The msg buffer is owned by the caller and it should - be either t_sigboost_callstart or t_sigboost_short - the endpoint receiving the msg will first cast to - t_sigboost_short, check the event type, and if needed. - */ -#define BOOST_WRITE_MSG_ARGS (ftdm_span_t *span, void *msg, ftdm_size_t msglen) -typedef ftdm_status_t (*boost_write_msg_func_t) BOOST_WRITE_MSG_ARGS; -#define BOOST_WRITE_MSG_FUNCTION(name) ftdm_status_t name BOOST_WRITE_MSG_ARGS - -/*! - \brief Set the callback to be used by a signaling module to write boost messages - \param callback The callback to be used by the signaling module - - The provided callback will be used for the signaling boost module to notify the - user with boost messages. - */ -#define BOOST_SET_WRITE_MSG_CB_ARGS (boost_write_msg_func_t callback) -typedef void (*boost_set_write_msg_cb_func_t) BOOST_SET_WRITE_MSG_CB_ARGS; -#define BOOST_SET_WRITE_MSG_CB_FUNCTION(name) void name BOOST_SET_WRITE_MSG_CB_ARGS - -/*! - \brief Notify hardware status change - \param ftdmchan The freetdm channel - \param status The hw status - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_ON_HW_LINK_STATUS_CHANGE_ARGS (ftdm_channel_t *ftdmchan, ftdm_channel_hw_link_status_t status) -typedef void (*boost_on_hw_link_status_change_func_t) BOOST_ON_HW_LINK_STATUS_CHANGE_ARGS; -#define BOOST_ON_HW_LINK_STATUS_CHANGE_FUNCTION(name) void name BOOST_ON_HW_LINK_STATUS_CHANGE_ARGS - -/*! - \brief Set signaling status callback used by the signaling module to report signaling status changes - \param callback The callback to be used by the signaling module - - The provided callback will be used for the signaling boost module to notify the - user with signaling link status changes. - */ -#define BOOST_SET_SIG_STATUS_CB_ARGS (boost_sig_status_cb_func_t callback) -typedef void (*boost_set_sig_status_cb_func_t) BOOST_SET_SIG_STATUS_CB_ARGS; -#define BOOST_SET_SIG_STATUS_CB_FUNCTION(name) void name BOOST_SET_SIG_STATUS_CB_ARGS - -/*! - \brief Get the signaling status on the given channel. - \param ftdmchan The freetdm channel - \param status The status pointer where the current signaling status will be set - */ -#define BOOST_GET_CHANNEL_SIG_STATUS_ARGS (ftdm_channel_t *ftdmchan, ftdm_signaling_status_t *status) -typedef ftdm_status_t (*boost_get_channel_sig_status_func_t) BOOST_GET_CHANNEL_SIG_STATUS_ARGS; -#define BOOST_GET_CHANNEL_SIG_STATUS_FUNCTION(name) ftdm_status_t name BOOST_GET_CHANNEL_SIG_STATUS_ARGS - -/*! - \brief Set the signaling status on the given channel. - \param ftdmchan The freetdm channel - \param status The new status for the channel - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_SET_CHANNEL_SIG_STATUS_ARGS (ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status) -typedef ftdm_status_t (*boost_set_channel_sig_status_func_t) BOOST_SET_CHANNEL_SIG_STATUS_ARGS; -#define BOOST_SET_CHANNEL_SIG_STATUS_FUNCTION(name) ftdm_status_t name BOOST_SET_CHANNEL_SIG_STATUS_ARGS - -/*! - \brief Get the signaling status on the given span. - \param span The freetdm span - \param status The status pointer where the current signaling status will be set - */ -#define BOOST_GET_SPAN_SIG_STATUS_ARGS (ftdm_span_t *span, ftdm_signaling_status_t *status) -typedef ftdm_status_t (*boost_get_span_sig_status_func_t) BOOST_GET_SPAN_SIG_STATUS_ARGS; -#define BOOST_GET_SPAN_SIG_STATUS_FUNCTION(name) ftdm_status_t name BOOST_GET_SPAN_SIG_STATUS_ARGS - -/*! - \brief Set the signaling status on the given span. - \param ftdmchan The freetdm span - \param status The new status for the span - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_SET_SPAN_SIG_STATUS_ARGS (ftdm_span_t *span, ftdm_signaling_status_t status) -typedef ftdm_status_t (*boost_set_span_sig_status_func_t) BOOST_SET_SPAN_SIG_STATUS_ARGS; -#define BOOST_SET_SPAN_SIG_STATUS_FUNCTION(name) ftdm_status_t name BOOST_SET_SPAN_SIG_STATUS_ARGS - -/*! - \brief Configure the given span signaling - \param span The freetdm span - \param parameters The array of configuration key,value pairs (must be null terminated) - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_CONFIGURE_SPAN_ARGS (ftdm_span_t *span, ftdm_conf_parameter_t *parameters) -typedef ftdm_status_t (*boost_configure_span_func_t) BOOST_CONFIGURE_SPAN_ARGS; -#define BOOST_CONFIGURE_SPAN_FUNCTION(name) ftdm_status_t name BOOST_CONFIGURE_SPAN_ARGS - -/*! - \brief Start the given span - \param span The freetdm span - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_START_SPAN_ARGS (ftdm_span_t *span) -typedef ftdm_status_t (*boost_start_span_func_t) BOOST_START_SPAN_ARGS; -#define BOOST_START_SPAN_FUNCTION(name) ftdm_status_t name BOOST_START_SPAN_ARGS - -/*! - \brief Stop the given span - \param span The freetdm span - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_STOP_SPAN_ARGS (ftdm_span_t *span) -typedef ftdm_status_t (*boost_stop_span_func_t) BOOST_START_SPAN_ARGS; -#define BOOST_STOP_SPAN_FUNCTION(name) ftdm_status_t name BOOST_STOP_SPAN_ARGS - -/*! - \brief Called when the module is being loaded BEFORE calling anything else - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_ON_LOAD_ARGS (void) -typedef ftdm_status_t (*boost_on_load_func_t) BOOST_ON_LOAD_ARGS; -#define BOOST_ON_LOAD_FUNCTION(name) ftdm_status_t name BOOST_ON_LOAD_ARGS - -/*! - \brief Called when the module is being unloaded, last chance to stop everything! - */ -#define BOOST_ON_UNLOAD_ARGS (void) -typedef ftdm_status_t (*boost_on_unload_func_t) BOOST_ON_UNLOAD_ARGS; -#define BOOST_ON_UNLOAD_FUNCTION(name) ftdm_status_t name BOOST_ON_UNLOAD_ARGS - -/*! - \brief Called when user wants to execute sigmod api function - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_API_ARGS (ftdm_stream_handle_t *stream, char *cmd) -typedef ftdm_status_t (*boost_api_func_t) BOOST_API_ARGS; -#define BOOST_API_FUNCTION(name) ftdm_status_t name BOOST_API_ARGS - - -/*! - \brief The boost signaling module interface - */ -typedef struct boost_sigmod_interface_s { - /*! \brief Module name */ - const char *name; - /*! \brief write boost message function */ - boost_write_msg_func_t write_msg; - /*! \brief set the user write boost message function */ - boost_set_write_msg_cb_func_t set_write_msg_cb; - /*! \brief set the user signaling status function */ - boost_set_sig_status_cb_func_t set_sig_status_cb; - /*! \brief get channel signaling status */ - boost_get_channel_sig_status_func_t get_channel_sig_status; - /*! \brief set channel signaling status */ - boost_set_channel_sig_status_func_t set_channel_sig_status; - /*! \brief get span signaling status */ - boost_get_span_sig_status_func_t get_span_sig_status; - /*! \brief set span signaling status */ - boost_set_span_sig_status_func_t set_span_sig_status; - /*! \brief set notify hardware link status change */ - boost_on_hw_link_status_change_func_t on_hw_link_status_change; - /*! \brief configure span signaling */ - boost_configure_span_func_t configure_span; - /*! \brief start freetdm span */ - boost_start_span_func_t start_span; - /*! \brief stop freetdm span */ - boost_stop_span_func_t stop_span; - /*! \brief the module was just loaded */ - boost_on_load_func_t on_load; - /*! \brief the module is about to be unloaded */ - boost_on_unload_func_t on_unload; - /*! \brief module api function */ - boost_api_func_t exec_api; - /*! \brief private pointer for the interface user */ - void *pvt; -} boost_sigmod_interface_t; - -#ifdef __cplusplus -} // extern C -#endif - -#define BOOST_INTERFACE_NAME boost_sigmod_interface -#define BOOST_INTERFACE_NAME_STR "boost_sigmod_interface" -/* use this in your sig boost module to declare your interface */ -#ifndef WIN32 -#define BOOST_INTERFACE boost_sigmod_interface_t BOOST_INTERFACE_NAME -#else -#define BOOST_INTERFACE __declspec(dllexport) boost_sigmod_interface_t BOOST_INTERFACE_NAME -#endif -#endif - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4: - */ - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sigboost.h b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sigboost.h deleted file mode 100644 index 7975dc5b93..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sigboost.h +++ /dev/null @@ -1,221 +0,0 @@ -/**************************************************************************** - * sigboost.h $Revision: 1.13 $ - * - * Definitions for the sigboost interface. - * - * WARNING WARNING WARNING - * - * This file is used by sangoma_mgd and perhaps other programs. Any changes - * to this file must be coordinated with other user programs, - * - * Copyright (C) 2005 Xygnada Technology, Inc. - * -****************************************************************************/ -#ifndef _SIGBOOST_H_ -#define _SIGBOOST_H_ - -#define SIGBOOST_VERSION 103 - -// handy to define integer types that actually work on both Lin and Win -#include - -enum e_sigboost_event_id_values -{ - SIGBOOST_EVENT_CALL_START = 0x80, /*128*/ - SIGBOOST_EVENT_CALL_START_ACK = 0x81, /*129*/ - SIGBOOST_EVENT_CALL_START_NACK = 0x82, /*130*/ - SIGBOOST_EVENT_CALL_START_NACK_ACK = 0x83, /*131*/ - SIGBOOST_EVENT_CALL_ANSWERED = 0x84, /*132*/ - SIGBOOST_EVENT_CALL_STOPPED = 0x85, /*133*/ - SIGBOOST_EVENT_CALL_STOPPED_ACK = 0x86, /*134*/ - SIGBOOST_EVENT_SYSTEM_RESTART = 0x87, /*135*/ - SIGBOOST_EVENT_SYSTEM_RESTART_ACK = 0x88, /*136*/ - /* CALL_RELEASED is aimed to fix a race condition that became obvious - * when the boost socket was replaced by direct function calls - * and the channel hunting was moved to freetdm, the problem is - * we can get CALL_STOPPED msg and reply with CALL_STOPPED_ACK - * but the signaling module will still (in PRI) send RELEASE and - * wait for RELEASE_COMPLETE from the isdn network before - * marking the channel as available, therefore freetdm should - * also not mark the channel as available until CALL_RELEASED - * is received, for socket mode we can continue working as usual - * with CALL_STOPPED being the last step because the hunting is - * done in the signaling module. - * */ - SIGBOOST_EVENT_CALL_RELEASED = 0x51, /* 81 */ - SIGBOOST_EVENT_CALL_PROGRESS = 0x50, /*decimal 80*/ - /* Following IDs are ss7boost to sangoma_mgd only. */ - SIGBOOST_EVENT_HEARTBEAT = 0x89, /*137*/ - SIGBOOST_EVENT_INSERT_CHECK_LOOP = 0x8a, /*138*/ - SIGBOOST_EVENT_REMOVE_CHECK_LOOP = 0x8b, /*139*/ - SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE = 0x8c, /*140*/ - SIGBOOST_EVENT_DIGIT_IN = 0x8d, /*141*/ -}; - -#define BOOST_DECODE_EVENT_ID(id) \ - (id==SIGBOOST_EVENT_CALL_START)?"SIGBOOST_EVENT_CALL_START": \ - (id==SIGBOOST_EVENT_CALL_START_ACK)?"SIGBOOST_EVENT_CALL_START_ACK": \ - (id==SIGBOOST_EVENT_CALL_START_NACK)?"SIGBOOST_EVENT_CALL_START_NACK": \ - (id==SIGBOOST_EVENT_CALL_ANSWERED)?"SIGBOOST_EVENT_CALL_ANSWERED": \ - (id==SIGBOOST_EVENT_CALL_STOPPED)?"SIGBOOST_EVENT_CALL_STOPPED": \ - (id==SIGBOOST_EVENT_CALL_STOPPED_ACK)?"SIGBOOST_EVENT_CALL_STOPPED_ACK": \ - (id==SIGBOOST_EVENT_SYSTEM_RESTART)?"SIGBOOST_EVENT_SYSTEM_RESTART": \ - (id==SIGBOOST_EVENT_SYSTEM_RESTART_ACK)?"SIGBOOST_EVENT_SYSTEM_RESTART_ACK": \ - (id==SIGBOOST_EVENT_CALL_RELEASED)?"SIGBOOST_EVENT_CALL_RELEASED": \ - (id==SIGBOOST_EVENT_CALL_PROGRESS)?"SIGBOOST_EVENT_CALL_PROGRESS": \ - (id==SIGBOOST_EVENT_HEARTBEAT)?"SIGBOOST_EVENT_HEARTBEAT": \ - (id==SIGBOOST_EVENT_INSERT_CHECK_LOOP)?"SIGBOOST_EVENT_INSERT_CHECK_LOOP": \ - (id==SIGBOOST_EVENT_REMOVE_CHECK_LOOP)?"SIGBOOST_EVENT_REMOVE_CHECK_LOOP": \ - (id==SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE)?"SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE": \ - (id==SIGBOOST_EVENT_DIGIT_IN)?"SIGBOOST_EVENT_DIGIT_IN": "Unknown" - -enum e_sigboost_release_cause_values -{ - SIGBOOST_RELEASE_CAUSE_UNDEFINED = 0, - SIGBOOST_RELEASE_CAUSE_NORMAL = 16, - /* probable elimination */ - //SIGBOOST_RELEASE_CAUSE_BUSY = 0x91, /* 145 */ - //SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST = 0x92, /* 146 */ - //SIGBOOST_RELEASE_CAUSE_CIRCUIT_RESET = 0x93, /* 147 */ - //SIGBOOST_RELEASE_CAUSE_NOANSWER = 0x94, /* 148 */ -}; - -enum e_sigboost_call_setup_ack_nack_cause_values -{ - //SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY = 34, /* Q.850 value - don't use */ - SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY = 117, /* non Q.850 value indicates local all ckt busy - causing sangoma_mgd to perform automatic call - gapping*/ - SIGBOOST_CALL_SETUP_NACK_TEST_CKT_BUSY = 17, /* Q.850 value */ - SIGBOOST_CALL_SETUP_NACK_INVALID_NUMBER = 28, /* Q.850 value */ - SIGBOOST_CALL_SETUP_CSUPID_DBL_USE = 200, /* unused Q.850 value */ -}; - - -enum e_sigboost_huntgroup_values -{ - SIGBOOST_HUNTGRP_SEQ_ASC = 0x00, /* sequential with lowest available first */ - SIGBOOST_HUNTGRP_SEQ_DESC = 0x01, /* sequential with highest available first */ - SIGBOOST_HUNTGRP_RR_ASC = 0x02, /* round-robin with lowest available first */ - SIGBOOST_HUNTGRP_RR_DESC = 0x03, /* round-robin with highest available first */ -}; - -enum e_sigboost_event_info_par_values -{ - SIGBOOST_EVI_SPARE = 0x00, - SIGBOOST_EVI_ALERTING = 0x01, - SIGBOOST_EVI_PROGRESS = 0x02, -}; - -enum e_sigboost_progress_flags -{ - SIGBOOST_PROGRESS_RING = (1 << 0), - SIGBOOST_PROGRESS_MEDIA = (1 << 1) -}; - -#define MAX_DIALED_DIGITS 31 - -/* Next two defines are used to create the range of values for call_setup_id - * in the t_sigboost structure. - * 0..((CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN) - 1) */ -#define CORE_MAX_SPANS 200 -#define CORE_MAX_CHAN_PER_SPAN 32 -#define MAX_PENDING_CALLS CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN -/* 0..(MAX_PENDING_CALLS-1) is range of call_setup_id below */ - -/* Should only be used by server */ -#define MAX_CALL_SETUP_ID 0xFFFF - -#define SIZE_CUSTOM 900 -#define SIZE_RDNIS SIZE_CUSTOM - - -#pragma pack(1) - -typedef struct -{ - uint8_t capability; - uint8_t uil1p; -} t_sigboost_bearer; - -typedef struct -{ - uint8_t digits_count; - char digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */ - uint8_t npi; - uint8_t ton; - uint8_t screening_ind; - uint8_t presentation_ind; -}t_sigboost_digits; - -typedef struct -{ - uint16_t version; - uint32_t event_id; - /* delete sequence numbers - SCTP does not need them */ - uint32_t fseqno; - uint32_t bseqno; - uint16_t call_setup_id; - uint32_t trunk_group; - uint8_t span; - uint8_t chan; - uint32_t flags; - /* struct timeval tv; */ - t_sigboost_digits called; - t_sigboost_digits calling; - t_sigboost_digits rdnis; - /* ref. Q.931 Table 4-11 and Q.951 Section 3 */ - char calling_name[MAX_DIALED_DIGITS + 1]; - t_sigboost_bearer bearer; - uint8_t hunt_group; - uint16_t custom_data_size; - char custom_data[SIZE_CUSTOM]; /* it's a null terminated string */ - -} t_sigboost_callstart; - -#define called_number_digits_count called.digits_count -#define called_number_digits called.digits -#define calling_number_digits_count calling.digits_count -#define calling_number_digits calling.digits -#define calling_number_screening_ind calling.screening_ind -#define calling_number_presentation calling.presentation_ind - -#define isup_in_rdnis_size custom_data_size -#define isup_in_rdnis custom_data - - -#define MIN_SIZE_CALLSTART_MSG sizeof(t_sigboost_callstart) - SIZE_CUSTOM - -typedef struct -{ - uint16_t version; - uint32_t event_id; - /* delete sequence numbers - SCTP does not need them */ - uint32_t fseqno; - uint32_t bseqno; - uint16_t call_setup_id; - uint32_t trunk_group; - uint8_t span; - uint8_t chan; - uint32_t flags; - /* struct timeval tv; */ - uint8_t release_cause; -} t_sigboost_short; -#pragma pack() - - -static __inline__ int boost_full_event(int event_id) -{ - switch (event_id) { - case SIGBOOST_EVENT_CALL_START: - case SIGBOOST_EVENT_DIGIT_IN: - case SIGBOOST_EVENT_CALL_PROGRESS: - return 1; - default: - break; - } - - return 0; -} - -#endif From b83a30caf68e290239f2d62c01bdc5ba7f8a5e15 Mon Sep 17 00:00:00 2001 From: Michal Bielicki - cypromis Date: Wed, 16 Feb 2011 20:35:11 +0100 Subject: [PATCH 214/245] added python eslmod installation to esl Makefiles --- libs/esl/Makefile | 3 +++ libs/esl/python/Makefile | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/libs/esl/Makefile b/libs/esl/Makefile index ab50bac4d9..fbc870ac24 100644 --- a/libs/esl/Makefile +++ b/libs/esl/Makefile @@ -95,4 +95,7 @@ managedmod: $(MYLIB) phpmod-install: phpmod $(MAKE) -C php install +pymod-install: pymod + $(MAKE) -C python install + everymod: perlmod phpmod luamod pymod rubymod javamod managedmod diff --git a/libs/esl/python/Makefile b/libs/esl/python/Makefile index 758aeaf500..6b7147bede 100644 --- a/libs/esl/python/Makefile +++ b/libs/esl/python/Makefile @@ -1,5 +1,6 @@ LOCAL_CFLAGS=`python ./python-config --includes` LOCAL_LDFLAGS=`python ./python-config --ldflags` +SITE_DIR=`python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"` all: _ESL.so @@ -12,6 +13,9 @@ esl_wrap.o: esl_wrap.cpp _ESL.so: esl_wrap.o $(CXX) $(SOLINK) esl_wrap.o $(MYLIB) $(LOCAL_LDFLAGS) -o _ESL.so -L. $(LIBS) +install: _ESL.so + install -o root -g root -m 644 _ESL.so $(SITE_DIR) + clean: rm -f *.o *.so *~ From 837c6ff6e828d1f81c8df2ac71d0733eb97f9fd1 Mon Sep 17 00:00:00 2001 From: Michal Bielicki - cypromis Date: Wed, 16 Feb 2011 20:35:56 +0100 Subject: [PATCH 215/245] adding centos standard java include parts to javamod esl module --- libs/esl/java/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/esl/java/Makefile b/libs/esl/java/Makefile index 9474a83276..3606edf331 100644 --- a/libs/esl/java/Makefile +++ b/libs/esl/java/Makefile @@ -1,4 +1,4 @@ -LOCAL_CFLAGS=-I../src/include -I/usr/java/jdk1.6.0_14/include -I/usr/java/jdk1.6.0_14/include/linux -I/usr/lib/jvm/java-6-openjdk/include/ +LOCAL_CFLAGS=-I../src/include -I/usr/java/jdk1.6.0_14/include -I/usr/java/jdk1.6.0_14/include/linux -I/usr/lib/jvm/java-6-openjdk/include/ -I/usr/lib/jvm/java/include -I/usr/lib/jvm/java/include/linux GCC_WARNING_JUNK=-w CLASSES=org/freeswitch/esl/* From e8335f588002217240ab49bc12504b42e89114d4 Mon Sep 17 00:00:00 2001 From: Michal Bielicki - cypromis Date: Wed, 16 Feb 2011 20:54:57 +0100 Subject: [PATCH 216/245] added DESTDIR to esl makefiles so that it can be used during rpm building --- libs/esl/php/Makefile | 6 +++--- libs/esl/python/Makefile | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/esl/php/Makefile b/libs/esl/php/Makefile index 44fdd22dae..e970ff7d82 100644 --- a/libs/esl/php/Makefile +++ b/libs/esl/php/Makefile @@ -25,6 +25,6 @@ swigclean: reswig: swigclean esl_wrap.cpp install: ESL.so - cp ESL.so $(shell php-config --extension-dir) - cp ESL.php $(shell php -r 'echo ini_get("include_path");' | cut -d: -f2) - echo 'extension=ESL.so' >> $(shell php-config --configure-options | tr " " "\n" | grep -- --with-config-file-scan-dir | cut -f2 -d=)/esl.ini + cp ESL.so $(DESTDIR)/$(shell php-config --extension-dir) + cp ESL.php /$(DESTDIR)/$(shell php -r 'echo ini_get("include_path");' | cut -d: -f2) + echo 'extension=ESL.so' >> $(DESTDIR)/$(shell php-config --configure-options | tr " " "\n" | grep -- --with-config-file-scan-dir | cut -f2 -d=)/esl.ini diff --git a/libs/esl/python/Makefile b/libs/esl/python/Makefile index 6b7147bede..0d9ca84cbd 100644 --- a/libs/esl/python/Makefile +++ b/libs/esl/python/Makefile @@ -1,6 +1,6 @@ LOCAL_CFLAGS=`python ./python-config --includes` LOCAL_LDFLAGS=`python ./python-config --ldflags` -SITE_DIR=`python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"` +SITE_DIR=$(DESTDIR)/`python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"` all: _ESL.so From 3ce98c4ebddec0e459c564942f6beb583350188a Mon Sep 17 00:00:00 2001 From: Michal Bielicki - cypromis Date: Thu, 17 Feb 2011 00:02:37 +0100 Subject: [PATCH 217/245] major cleanups, mod_skinny and skypopen and sangoma ftdm modules added to rpm spec file --- freeswitch.spec | 162 +++++++++++++++++++++++++++++++++++---- libs/esl/python/Makefile | 2 +- 2 files changed, 150 insertions(+), 14 deletions(-) diff --git a/freeswitch.spec b/freeswitch.spec index 7fb9f80d8e..9b6e60f123 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -27,6 +27,14 @@ # Maintainer(s): Michal Bielicki 910 @@ -282,14 +295,72 @@ German language phrases module and directory structure for say module and voicem Summary: Provides a unified interface to hardware TDM cards and ss7 stacks for FreeSWITCH Group: System/Libraries Requires: %{name} = %{version}-%{release} -%{?with_sang_isdn: Requires: wanpipe } -%{?with_sang_isdn: Requires: libsng_isdn } -%{?with_sang_isdn: BuildRequires: wanpipe } -%{?with_sang_isdn: BuildRequires: libang_isdn } %description freetdm FreeTDM +%if %{build_sng_isdn} + +%package freetdm-sng-isdn +Summary: Sangoma ISDN Module for FreeTDM +Group: System/Libraries +Requires: %{name} = %{version}-%{release} +Requires: %{name}-freetdm = %{version}-%{release} +Requires: wanpipe +Requires: libsng_isdn +BuildRequires: wanpipe +BuildRequires: libsng_isdn + +%description freetdm-sng-isdn +Sangoma ISDN Module for freetdm + +%endif + +%if %{build_sng_ss7} + +%package freetdm-sng-ss7 +Summary: Provides a unified interface to hardware TDM cards and ss7 stacks for FreeSWITCH, Sangoma SS7 Module +Group: System/Libraries +Requires: %{name} = %{version}-%{release} +Requires: %{name}-freetdm = %{version}-%{release} +Requires: wanpipe +Requires: libsng_ss7 +BuildRequires: wanpipe +BuildRequires: libsng_ss7 + +%description freetdm-sng-ss7 +Sangoma SMG-SS7 drivers for FreeTDM + +%endif + + +%if %{build_sng_tc} + +%package sangoma-codec +Summary: Sangoma D100 and D500 Codec Card Support +Group: System/Libraries +Requires: %{name} = %{version}-%{release} +Requires: sng-tc-linux +BuildRequires: sng-tc-linux + +%description sangoma-codec +Sangoma D100 and D500 Codec Card Support + +%endif + +%package skypopen +Summary: Skype Endpoint +Group: System/Libraries +Requires: %{name} = %{version}-%{release} +Requires: libX11 +BuildRequires: libX11-devel + +%description skypopen +This software (Skypopen) uses the Skype API but is not endorsed, certified or otherwise approved in any way by Skype. +Skypopen is an endpoint (channel driver) that uses the Skype client as an interface to the Skype network, and allows +incoming and outgoing Skype calls to/from FreeSWITCH (that can be bridged, originated, answered, etc. as in all other +endpoints, e.g. Sofia-SIP). + ###################################################################################################################### # # Unpack and prepare Source archives, copy stuff around etc .. @@ -309,6 +380,8 @@ cp %{SOURCE8} libs/ cp %{SOURCE9} libs/ cp %{SOURCE10} libs/ cp %{SOURCE11} libs/ +cp %{SOURCE12} libs/ +cp %{SOURCE13} libs/ ###################################################################################################################### # @@ -358,7 +431,11 @@ ASR_TTS_MODULES="asr_tts/mod_pocketsphinx asr_tts/mod_flite asr_tts/mod_unimrcp" # ###################################################################################################################### CODECS_MODULES="codecs/mod_bv codecs/mod_h26x codecs/mod_speex codecs/mod_celt codecs/mod_codec2 codecs/mod_ilbc codecs/mod_mp4v \ - codecs/mod_silk codecs/mod_siren codecs/mod_theora" + codecs/mod_opus codecs/mod_silk codecs/mod_siren codecs/mod_theora " +# +%if %{build_sng_tc} +CODECS_MODULES+="codecs/mod_sangoma_codec" +%endif ###################################################################################################################### # # Dialplan Modules @@ -377,7 +454,7 @@ DIRECTORIES_MODULES="" # ###################################################################################################################### ENDPOINTS_MODULES="endpoints/mod_dingaling endpoints/mod_loopback ../../libs/freetdm/mod_freetdm endpoints/mod_portaudio \ - endpoints/mod_sofia" + endpoints/mod_sofia endpoints/mod_skinny endpoints/mod_skypopen" ###################################################################################################################### # @@ -483,11 +560,13 @@ fi %{?configure_options} #Create the version header file here -cat src/include/switch_version.h.in | sed "s/@SVN_VERSION@/%{version}/g" > src/include/switch_version.h -touch .noversion +#cat src/include/switch_version.h.in | sed "s/@SVN_VERSION@/%{version}/g" > src/include/switch_version.h +#touch .noversion %{__make} +cd libs/esl +%{__make} pymod ###################################################################################################################### # @@ -503,6 +582,11 @@ touch .noversion %{__mkdir} -p %{buildroot}%{logfiledir} %{__mkdir} -p %{buildroot}%{runtimedir} +#install the esl stuff +cd libs/esl +%{__make} DESTDIR=%{buildroot} pymod-install +cd ../.. + %ifos linux # Install init files # On SuSE: @@ -522,6 +606,23 @@ touch .noversion # Add monit file %{__install} -D -m 644 build/freeswitch.monitrc %{buildroot}/etc/monit.d/freeswitch.monitrc %endif +###################################################################################################################### +# +# Remove files that are not wanted if they exist +# +###################################################################################################################### + +%if %{build_sng_ss7} +#do not delete a thing +%else +rm %{prefix}/mod/ftdm_sangoma_ss7* +%endif +%if %{build_sng_isdn} +#do not delete a thing +%else +rm %{prefix}/mod/ftdm_sangoma_isdn* +%endif + ###################################################################################################################### @@ -545,8 +646,6 @@ fi chkconfig --add freeswitch - - %postun ###################################################################################################################### # @@ -790,6 +889,7 @@ fi %{prefix}/mod/mod_mp4v.so* %{prefix}/mod/mod_native_file.so* %{prefix}/mod/mod_nibblebill.so* +%{prefix}/mod/mod_opus.so* %{prefix}/mod/mod_pocketsphinx.so* %{prefix}/mod/mod_portaudio.so* %{prefix}/mod/mod_portaudio_stream.so* @@ -798,6 +898,7 @@ fi %{prefix}/mod/mod_shout.so* %{prefix}/mod/mod_silk.so* %{prefix}/mod/mod_siren.so* +%{prefix}/mod/mod_skinny.so* %{prefix}/mod/mod_sndfile.so* %{prefix}/mod/mod_snom.so* %{prefix}/mod/mod_sofia.so* @@ -831,7 +932,7 @@ fi %{prefix}/include/*.h ###################################################################################################################### # -# OpenZAP Module for TDM Interaction +# FreeTDM Module for TDM Interaction # ###################################################################################################################### %files freetdm @@ -844,7 +945,26 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/zt.conf %{prefix}/lib/libfreetdm.so* %{prefix}/mod/mod_freetdm.so* -%{prefix}/mod/ftm*.so* +%{prefix}/mod/ftmod_skel*.so* +%{prefix}/mod/ftmod_[a-r,t-z]*.so* + +%if %{build_sng_tc} +%files sangoma-codec +%defattr(-, freeswitch, daemon) +%{prefix}/mod/mod_sangoma_codec.so* +%endif + +%if %{build_sng_ss7} +%files freetdm-sng-ss7 +%defattr(-, freeswitch, daemon) +%{prefix}/mod/ftmod_sangoma_ss7.so* +%endif + +%if %{build_sng_isdn} +%files freetdm-sng-isdn +%defattr(-, freeswitch, daemon) +%{prefix}/mod/ftmod_sangoma_isdn.so* +%endif ###################################################################################################################### # @@ -899,9 +1019,13 @@ fi %defattr(-,freeswitch,daemon) %{prefix}/mod/mod_python*.so* %attr(0644, root, bin) /usr/lib/python*/site-packages/freeswitch.py* +%attr(0644, root, bin) /usr/lib/python*/site-packages/_ESL.so* %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/autoload_configs %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/python.conf.xml +%files skypopen +%defattr(-,freeswitch,daemon) +%{prefix}/mod/mod_skypopen.so* ###################################################################################################################### # # Language Modules @@ -956,6 +1080,17 @@ fi # ###################################################################################################################### %changelog +* Wed Feb 16 2011 - michal.bielicki@seventhsignal.de +- added mod_skinny +- added sangoma libraries +- added sangoma codec module for D100 and D150 and D500 +- added skypopen module +- fixes for ss7 freetdm modules +- added mod_opus +- added selector for sangoma modules +- addded python esl module to rpm +- some minor cleanups +- cut sangoma modules into separate rpms as addons for freetdm * Tue Jan 18 2011 - michal.bielicki@seventhsignal.de - Fedora adjustments * Fri Oct 15 2010 - michal.bielicki@seventhsignal.de @@ -1090,3 +1225,4 @@ fi - Added devel package * Thu Mar 15 2007 - peter+rpmspam@suntel.com.tr - Initial RPM release + diff --git a/libs/esl/python/Makefile b/libs/esl/python/Makefile index 0d9ca84cbd..784426ee1b 100644 --- a/libs/esl/python/Makefile +++ b/libs/esl/python/Makefile @@ -14,7 +14,7 @@ _ESL.so: esl_wrap.o $(CXX) $(SOLINK) esl_wrap.o $(MYLIB) $(LOCAL_LDFLAGS) -o _ESL.so -L. $(LIBS) install: _ESL.so - install -o root -g root -m 644 _ESL.so $(SITE_DIR) + install -m 755 _ESL.so $(SITE_DIR) clean: rm -f *.o *.so *~ From 2a3aea4cc8aa7a6f9f255fd548e29c30c32864fe Mon Sep 17 00:00:00 2001 From: Michal Bielicki - cypromis Date: Thu, 17 Feb 2011 02:01:46 +0100 Subject: [PATCH 218/245] its getting late and I am looking at this file the whole day already --- freeswitch.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freeswitch.spec b/freeswitch.spec index 9b6e60f123..6b7530d471 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -615,12 +615,12 @@ cd ../.. %if %{build_sng_ss7} #do not delete a thing %else -rm %{prefix}/mod/ftdm_sangoma_ss7* +rm -f %{prefix}/mod/ftmod_sangoma_ss7* %endif %if %{build_sng_isdn} #do not delete a thing %else -rm %{prefix}/mod/ftdm_sangoma_isdn* +rm -f %{prefix}/mod/ftmod_sangoma_isdn* %endif From 65d5932c9ffc17be3df98deb0fe0e3552565eb76 Mon Sep 17 00:00:00 2001 From: Michal Bielicki - cypromis Date: Thu, 17 Feb 2011 10:09:26 +0100 Subject: [PATCH 219/245] fixes for the python esl (we need ESL.py as well) deleting the sangoma modules if they are not defined to be build but are build anyway --- freeswitch.spec | 7 ++++--- libs/esl/python/Makefile | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/freeswitch.spec b/freeswitch.spec index 6b7530d471..1000a89239 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -615,12 +615,12 @@ cd ../.. %if %{build_sng_ss7} #do not delete a thing %else -rm -f %{prefix}/mod/ftmod_sangoma_ss7* +%{__rm} -f %{buildroot}/%{prefix}/mod/ftmod_sangoma_ss7* %endif %if %{build_sng_isdn} #do not delete a thing %else -rm -f %{prefix}/mod/ftmod_sangoma_isdn* +%{__rm} -f %{buildroot}/%{prefix}/mod/ftmod_sangoma_isdn* %endif @@ -1019,7 +1019,8 @@ fi %defattr(-,freeswitch,daemon) %{prefix}/mod/mod_python*.so* %attr(0644, root, bin) /usr/lib/python*/site-packages/freeswitch.py* -%attr(0644, root, bin) /usr/lib/python*/site-packages/_ESL.so* +%attr(0755, root, bin) /usr/lib/python*/site-packages/_ESL.so* +%attr(0755, root, bin) /usr/lib/python*/site-packages/ESL.py* %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/autoload_configs %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/python.conf.xml diff --git a/libs/esl/python/Makefile b/libs/esl/python/Makefile index 784426ee1b..7504665561 100644 --- a/libs/esl/python/Makefile +++ b/libs/esl/python/Makefile @@ -15,6 +15,7 @@ _ESL.so: esl_wrap.o install: _ESL.so install -m 755 _ESL.so $(SITE_DIR) + install -m 755 ESL.py $(SITE_DIR) clean: rm -f *.o *.so *~ From bb797286d012f67e9806ed061c0c14316dd12506 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 17 Feb 2011 09:17:41 -0500 Subject: [PATCH 220/245] freetdm: increase size of static buffer for DSO path --- libs/freetdm/src/ftdm_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 260892ada0..8b1925f84f 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -4866,7 +4866,7 @@ FT_DECLARE(int) ftdm_load_module(const char *name) { ftdm_dso_lib_t lib; int count = 0, x = 0; - char path[128] = ""; + char path[512] = ""; char *err; ftdm_module_t *mod; From 60395cea462ecfa0f34c546892918a5427979f51 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 17 Feb 2011 11:44:57 -0500 Subject: [PATCH 221/245] chlog: freetdm: Channel indicator IE only included in first response --- .../src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 2 ++ .../ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index 80dc73f0fa..b369deae1f 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -80,6 +80,8 @@ typedef enum { FLAG_ACTIVATING = (1 << 10), /* Used when we receive an ALERT msg + inband tones ready */ FLAG_MEDIA_READY = (1 << 11), + /* Set when we already sent a Channel ID IE */ + FLAG_SENT_CHAN_ID = (1 << 12), } sngisdn_flag_t; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index 23fe08b983..08e5984a4f 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -821,9 +821,17 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId) { + sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data; if (!ftdmchan) { return FTDM_SUCCESS; } + + if (ftdm_test_flag(sngisdn_info, FLAG_SENT_CHAN_ID)) { + /* Indicate channel ID only in first response */ + return FTDM_SUCCESS; + } + ftdm_set_flag(sngisdn_info, FLAG_SENT_CHAN_ID); + chanId->eh.pres = PRSNT_NODEF; chanId->prefExc.pres = PRSNT_NODEF; chanId->prefExc.val = IN_PE_EXCLSVE; From 4b62ff799e00a30fb898ddea2633d928d0d24eeb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 17 Feb 2011 11:32:00 -0600 Subject: [PATCH 222/245] put transport in the request uri on outbound registers if register_transport is set and proxy does not already contain a transport param --- src/mod/endpoints/mod_sofia/sofia.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 825d1bf46e..e9d2cada2e 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2148,8 +2148,13 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) if (!zstr(from_domain)) { gateway->from_domain = switch_core_strdup(gateway->pool, from_domain); } + + if (!zstr(register_transport) && !switch_stristr("transport=", proxy)) { + gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s;transport=%s", proxy, register_transport); + } else { + gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s", proxy); + } - gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s", proxy); gateway->register_from = switch_core_sprintf(gateway->pool, "", from_user, !zstr(from_domain) ? from_domain : proxy, register_transport); From b36a7c0ba6381699cc9dbbc096aef90bea1ad4d3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 17 Feb 2011 12:12:43 -0600 Subject: [PATCH 223/245] add multiple-registrations flag to the core similar to mod_sofia --- src/include/private/switch_core_pvt.h | 1 + src/switch_core.c | 2 ++ src/switch_core_sqldb.c | 9 ++++++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index f8c6a794b9..ab0777ed3b 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -248,6 +248,7 @@ struct switch_runtime { int max_sql_buffer_len; switch_dbtype_t odbc_dbtype; char hostname[256]; + int multiple_registrations; }; extern struct switch_runtime runtime; diff --git a/src/switch_core.c b/src/switch_core.c index 66731b61c8..5479229100 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1549,6 +1549,8 @@ static void switch_load_core_config(const char *file) if (tmp > -1 && tmp < 11) { switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp); } + } else if (!strcasecmp(var, "multiple-registrations")) { + runtime.multiple_registrations = switch_true(val); } else if (!strcasecmp(var, "sql-buffer-len")) { int tmp = atoi(val); diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index f135e9586d..1274213893 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1653,7 +1653,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, c return SWITCH_STATUS_FALSE; } - sql = switch_mprintf("delete from registrations where hostname='%q' and (url='%q' or token='%q')", switch_core_get_hostname(), url, switch_str_nil(token)); + if (runtime.multiple_registrations) { + sql = switch_mprintf("delete from registrations where hostname='%q' and (url='%q' or token='%q')", + switch_core_get_hostname(), url, switch_str_nil(token)); + } else { + sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q'", + user, realm, switch_core_get_hostname()); + } + switch_cache_db_execute_sql(dbh, sql, NULL); free(sql); From 28242f871ac338876ffafa79dd677485d2ce0f5e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 17 Feb 2011 12:14:48 -0600 Subject: [PATCH 224/245] add multiple-registrations flag to the core similar to mod_sofia --- conf/autoload_configs/switch.conf.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/conf/autoload_configs/switch.conf.xml b/conf/autoload_configs/switch.conf.xml index 95c43331e4..4f72c6a65d 100644 --- a/conf/autoload_configs/switch.conf.xml +++ b/conf/autoload_configs/switch.conf.xml @@ -98,7 +98,9 @@ - + + + From 0f8fb4b1fdb7f9256f21f55ab8c28afa280e7884 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Thu, 17 Feb 2011 14:12:42 -0500 Subject: [PATCH 225/245] add ability to jump to a specific message --- .../applications/mod_voicemail/mod_voicemail.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 894e49a511..ef843f683c 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1725,8 +1725,7 @@ static void update_mwi(vm_profile_t *profile, const char *id, const char *domain #define FREE_DOMAIN_ROOT() if (x_user) switch_xml_free(x_user); x_user = NULL - -static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *profile, const char *domain_name, const char *id, int auth) +static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *profile, const char *domain_name, const char *id, int auth, const char *uuid_in) { vm_check_state_t vm_check_state = VM_CHECK_START; switch_channel_t *channel = switch_core_session_get_channel(session); @@ -1900,6 +1899,9 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p cbt.type = play_msg_type; cbt.move = VM_MOVE_NEXT; vm_execute_sql_callback(profile, profile->mutex, sql, listen_callback, &cbt); + if (strcmp(cbt.uuid, uuid_in)) { + continue; + } status = listen_file(session, profile, &cbt); if (cbt.move == VM_MOVE_PREV) { if (cur_message <= 0) { @@ -3154,12 +3156,12 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p if (*buf != '\0') { greet_key_press: if (switch_stristr(buf, profile->login_keys)) { - voicemail_check_main(session, profile, domain_name, id, 0); + voicemail_check_main(session, profile, domain_name, id, 0, NULL); } else if ((!zstr(profile->operator_ext) || !zstr(operator_ext)) && !zstr(profile->operator_key) && !strcasecmp(buf, profile->operator_key) ) { int argc; char *argv[4]; char *mycmd; - + if ((!zstr(operator_ext) && (mycmd = switch_core_session_strdup(session, operator_ext))) || (!zstr(profile->operator_ext) && (mycmd = switch_core_session_strdup(session, profile->operator_ext)))) { argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); @@ -3292,7 +3294,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p #define VM_DESC "voicemail" -#define VM_USAGE "[check] [auth] []" +#define VM_USAGE "[check] [auth] [] [uuid]" SWITCH_STANDARD_APP(voicemail_function) { @@ -3304,6 +3306,7 @@ SWITCH_STANDARD_APP(voicemail_function) const char *domain_name = NULL; const char *id = NULL; const char *auth_var = NULL; + const char *uuid = NULL; int x = 0, check = 0, auth = 0; switch_channel_t *channel = switch_core_session_get_channel(session); @@ -3363,7 +3366,10 @@ SWITCH_STANDARD_APP(voicemail_function) } if (check) { - voicemail_check_main(session, profile, domain_name, id, auth); + if (argv[x]) { + uuid = argv[x++]; + } + voicemail_check_main(session, profile, domain_name, id, auth, uuid); } else { voicemail_leave_main(session, profile, domain_name, id); } From 2f9357b2a7cd262863459fbce042e17f47563ef8 Mon Sep 17 00:00:00 2001 From: Geovani Ricardo Wiedenhoft Date: Thu, 17 Feb 2011 17:41:56 -0200 Subject: [PATCH 226/245] - fxo-busy-disconnection timer for desconnection on FXO - khomp set changes configuration - KR2GotCategory variable - Disconnection forced R2 signaling (collect call) - restricted, omits the number of origin - Option to enable/disable dial with '#' on FXS - Added KR2StrCategory - Added "khomp dump config" command - KISDNOrigTypeOfNumber, KISDNDestTypeOfNumber, KISDNOrigNumberingPlan, KISDNDestNumberingPlan, KISDNOrigPresentation - New version of commons - Updated documentation --- .../mod_khomp/Install/files/khomp.conf.xml | 24 ++ .../mod_khomp/commons/base/config_commons.hpp | 2 +- .../mod_khomp/commons/base/config_options.hpp | 28 +- .../commons/base/configurator/configfile.cpp | 5 +- .../mod_khomp/commons/base/k3lapi.cpp | 9 + .../mod_khomp/commons/base/k3lapi.hpp | 2 + .../mod_khomp/commons/base/logger.hpp | 67 +---- .../mod_khomp/commons/base/simple_lock.hpp | 4 +- .../base/system/freeswitch/simple_lock.hpp | 2 +- .../mod_khomp/commons/base/verbose.cpp | 4 +- src/mod/endpoints/mod_khomp/docs/Manual.html | 12 +- src/mod/endpoints/mod_khomp/docs/Manual.pdf | Bin 470343 -> 470577 bytes src/mod/endpoints/mod_khomp/docs/README.html | 2 +- src/mod/endpoints/mod_khomp/docs/README.pdf | Bin 399119 -> 399111 bytes .../endpoints/mod_khomp/docs/README_en.html | 3 +- .../endpoints/mod_khomp/docs/README_en.pdf | Bin 314413 -> 314423 bytes .../endpoints/mod_khomp/docs/User_Guide.html | 11 +- .../endpoints/mod_khomp/docs/User_Guide.pdf | Bin 509260 -> 464991 bytes src/mod/endpoints/mod_khomp/include/cli.h | 38 +++ src/mod/endpoints/mod_khomp/include/k3l.h | 13 + .../endpoints/mod_khomp/include/khomp_pvt.h | 29 +- .../mod_khomp/include/khomp_pvt_fxo.h | 26 +- .../mod_khomp/include/khomp_pvt_kxe1.h | 150 +++++++--- src/mod/endpoints/mod_khomp/include/opt.h | 5 +- .../endpoints/mod_khomp/include/revision.h | 2 +- src/mod/endpoints/mod_khomp/src/cli.cpp | 99 ++++++- src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp | 48 ++-- .../endpoints/mod_khomp/src/khomp_pvt_fxo.cpp | 32 ++- .../endpoints/mod_khomp/src/khomp_pvt_gsm.cpp | 3 + .../mod_khomp/src/khomp_pvt_kxe1.cpp | 272 ++++++++++++------ src/mod/endpoints/mod_khomp/src/opt.cpp | 5 +- src/mod/endpoints/mod_khomp/src/spec.cpp | 2 - src/mod/endpoints/mod_khomp/src/utils.cpp | 27 +- 33 files changed, 654 insertions(+), 272 deletions(-) diff --git a/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml b/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml index 79c00516b9..069792935c 100644 --- a/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml +++ b/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml @@ -272,6 +272,15 @@ a FXS branch. --> + + + + ce6+xNn#ae@d3!6TkUfL=E`)^e zF6fO|SkDuFvkltKHcQjb=_awCuj}avsYn0Mv~=`qGfuVg{byQc`a)QIJIw#rBLn}v z&%o60drq=`XSM(N{SWT+MGeL8iwT_HQ!U{u3V5B0ObXt*7(oghRY=SFnunm)vslX1 z-|C2|_QXVwUcWA$?5dwrSp&B9#e)9g68JCi?=c6q6hZi(u)DMYpGb3=Q*==S1_qzl z@BvU>LWm*zoS3Jv41j3kXR$s&=+sM7p#IO6PqNgTJLV9^pi_{cP;=yQSr+F4$oYlL z8cbTw2^MfH}>ZI@|(wP&|#TDB{`Lyv;sydTPXBXL?IFp$)M4ae{mO+y0#qKf&TkdLjC z;0Q+hoW+3o`iC6=s5!}~k^ST{Z4-1zNo0d176WE=0VpTJs6Q3QQpWrjn1Sxf;wHxA zHE@piOfPj$wX%U5cAtuhpY3_rQP*<;P-UBV_4$VFN;}f1#1pseLJMUgWS^+iRa|g_ z=Tx2FEx&DOE_NCBI@ZuYc1{1dx=2G{LwM#vE02{~G{geLNrsRV|`IhZ1_ ziUh`_q-MP3d9Wx+?no*^+eqy=QQ$VRH9y~F91T)tQ68vJP(E3A++GNN!KaprU)eHM zeYq(|NPW^M>j1LiB%-KO@5D6h!&B5b5u)$ji1`~JRTTdMWwpzZK3+9l(g*SOaB#E( zg|uTWjW7nF`gf+V+M6x3=tcaNhn;8fz@jWGViwoRB$j{8AOKKKxa`TM#d6$BM=Y^* zeBkBv#sSRJZWsbM+KX{D?4goVc(3-z+q=l{DTj^r;J_ao`CVL?AIDNJR+o+R>+p?v zl?c%fC~;Ni-G0!462mnwwzQ>ocn7nF2lYjS{!0PSHpN(B*ooKCG4KwN={w)y&Hkku zFI;-yXan@1?VR=*lPTarV~NA^ky9UWn8I0$m`Zx$FH*Zp1 zLj1ete3%0U$I&-{z2G%PoYy=j{b${E7dzbvMVpLMPBZF$-^!U7S$&##@s;Q?GgTc? zbNe8m;-%dWTC2)ew%m``;z#GE!vnH9EW)=r!ed0o3kk{y_42P(o((v5Q8Qw^t=l&_otx-9(pPmyG>l|>fI9@gl*KjrjDRe zf_a}H$Gv-3p<+v&pJ{=j998-kUiM_&no+RCzGdZ1s(8~3+$kut%we@|qy`Y}YMS#+ z0sm(K_HjO6B*(H-XL|3iL1Sc&UG=h#Y}%<4_UlollU0U^%r!NaOK7VV0Jv^NN3yjV z01483kO=OLuT$NZfw}W3yDxX8dms}Y;d9NZS0Ezb7U*fzyt{t2@9#hkfwDv3HxLN}6Si@Cgd^i@QV0A#KtGdV|0 z1S)l^*X^ebtb~G7BgMSPzWU$08||^qQ{DUa82p~k$Md{-4&t-B132CubDvKySHuq= zj*^C)1l}%v_5j}MUO@4K!)-MB=kuBtbj=8`eetRjw_aWS*oTX>fYs~cp4n!r&V@yT zR)RpWYrtjWDvI|~J>PnvD{C8#OLC=+#H^l4x~x=Dd5mbeiy8g$S9@Aj$-$f56J?t5 zwLy1kFzK&cNleR=F+YLR2xcl{YPL%gDac6%&cYBB-MBm*R6ub=g$gR_L}3K!uH*4; zOg2$=+Ppt(+IT)F;B0;9;FI(OF3zBJQXa$CGK2Y zj!Ju}aE6XJStksQ3KnO=&U)eRoHN19U$7q?2)+)Fyl8=wWY^IyA+lp|0(^*ws#+De z@|=igvQya3+TWG04prtZk^w)0-v!b+>?R9M6JM!-eyw~F5!Za1?-i0O=hxNOg@<@v zB8(IxT5J8b&PDj!Zv{NmIr<^(Q6LO4X$Nl>4|1b3bHw`fIsU$qw{<|*+La_8I@PC5 zn>Y3vUi4?aexkiSebu?8W-{N`Uep3Xq{;|Dl>!F4mjRs$?X;p*u)F%%0)u~zW}82< zuvkXm`ep;t3`b^cW=Fw*mUJ|=30)>mQnW_nX)3(e92|h^MuP5GY_JBY%Z2)YS||dU ztZ9#eV~UtALgh0WmfyMVe@Wj$K^&I@VI&F@P$q{Tisie#C5RiSk=`e8<@})61gX^XR@NSu_6QW@sPaJM?X>C8aH(f>#BO1EU!QAlC$z@=()K*}CZyq&9# zn@<;U>X6@irrg3B;jBr07N5M?%&_^$N|XMnpa{@imRuwxC4ov3$Ddp*bApu#Y8^}` zq*g>lRf(VtwlBz}$(909ROwXu{q&wFzZ_i|(vHxG8uhehA!tKGGdA}8UobZJyg*7= z<#FNk5xrpju=DfdbaTf|=^HVvWgdw|r!BcxGoVQ@=@oF2Uy5b?kk*9PYUHi2l%d(B z*zW*C1TtzNlDJ;zsf<+}t)H$DpTWTP(yX*Q)9lgmq6|2{Con?}eg+C6g#4O=Hevax zsUq3$gI$1@BQU`%{2b-WO13UjUlI2}vCx}3T4F3v&U*NK4!WZ6hHvSQ#jeV4Y1cH( z(+~}vpUFb31+~ED?rMn?FjidrJJmfG(EbHDyoyfF=hVU7SB@<&gdYWx~%Ib9wIJDX@^Z$XA>kS5^1Y@Re_QUceaIpGPD9-$L3 zQa0~d6HR^FpFcwclo-Hih1N)J%;;zl<~k%25r5`=$a=52ArFc|4c=cf-tiSzDP)y{qv2Ty{3jA)FR2%@|_ zWA!*Ox`wSq$<`2Pv#j}Y1))w36soIbNof-EOTmn+;2Hz-xEQsPwEs;LtXOifko2Wm zIHH$itfh)js~%LxM!4UEo{c!(4oVD08nZlV#jrQBXs{ds$a@Ebt%y4SBTf#Gi8m6^ z(ftzHVIO_8AFR;he(AMAo;Eqg)OhM&Xu$M0H7&N(hodj?P@UeDfb$%0cT*~ z{33Bpi?24ba^{(X!Nck>^`roJ{}C%xxOcL!uPG6@^)O}J)(2D7M=--fg~P73@!s$C32_~_Y_%k zhRBk+a{Ik#a<3z^$+J>S9~kqyes2NjneF#0{6k`5Uk!7v;$XvOC0qvU%H(Q8sM|Tz z-#ucC?krou*1(GVHAINB>kMz-yMoYNX%>s`|540Q=-#N~buB#$1ByTJJ4 zdnceJ26W|(tNMd=iBAyF+oZ2Ee+ie$M$yZP0i$&HE`9xXuUmcn0pjdbl$d`oTOgH%IS9R*nv?BGQb-u=!)Ghz<6T zom8s0A`41-7LNCu#lz{&m{_gGnvXOAx{@+A%QzhL+>4SH+HAC>)9T(al_{*$p&K&` zvnM-;^z<#Gl!tc9&+=`d{gO6hYUFv*gxN7Vs!5KP&IJU7-C0Vz9@tzR{Vc@_z>yXy zr`h|7yS)k{WtA0yI|Oj@`H10H+Iz&D$dfP6g}axJK~CjcH_B}(@1%(=i*dKTayTOQ zuz;o6DtKGsSS^-!2MRjo5NmgFuq1{<@vV&Udsy$BV+39FQ+X4~U@wkC=5a+~s;lFyMgZvar`CI3_sK&}y_u6ba;+-2H0U0ki2xdq+)rba~^f*?9YMN_lW zi)vow4;eH8joV3&;LPF8d#wGw-arS&(_o@}uA?~+MSNIs%)tln%1niZm=-OWtV|MY zX|fqo^l5vKkD=0Lu)p#TYGPMqpL&L_FJr!yFx{u5-8_(fHm ztF$G}badLA(_O)bN_R{WFo~LknAI8B;{F}$rfE*BWwE>#bkn;Lnc2wj8G3c$@94?X zm_(DQ|CLuED^x}(nU2OiL}j4Rk`i~zG0h*Ky>FJ|#NLHR4V49sUTbZk+r^F7W7EE% z$UO-bc4L4RQ>`f%rTo_YSgc67XkyjFuC<_XAd^qwU<5BU^!51zV3SKL)+AVPGbpK1 zS(J_HjZ>Y$60HMRGONb9s3crMN4P~HT1S3VO(5Y=bmhb$Ai?qcAm@VqY7Ni6(LAtP z&#*S8WjR6E#5^>uDR_}d;tpV-bIKuHUHKu;{W-xz`JOlM+$3g3rfBZqdKh0k5NbqG zEecT*;L4_7ZK7rdI1?vt#pB*g(xNOk4wHoOHAm+~1Pb|#ni~QigNmefdo=Rk^9!nW zgu}*C**RE(4Ve2mS4`r4skG3E^E~xxbU3atMXLUoZKlaMM>QT@7je#iy~R#4S;?~D zcm~w|8|`yl?#r?F0r%yqxV;tZQ5X1*QDNn7t-hG^4K<`2uy01rFEa-*qlHS8m+6Fe zi;!HW&bV^Rs7;7<9I3=b4fo6;|5c_@b?QUQf)(m8lug``NwvH zdRjX9fO0P%h$M=}6^&v$i~nr}q`!}zp3y=%3B06dt6r2Z5QNNZGkroMQGzreH0se^}r7h1V{xyeC+4=|y)_%O0L z%LoAJ!G=Z#i=EVVKTOU#yFRCdR4$!#O;9%Yjz0w>03r8W(=?X74=U}Jd+9*e?ItVh zm^tM{kv_i&DGF2rlQcyhT$g|!R!<5mN9sDvg5Ofcylzt*^e$7aH&yj}G6k@@aRm-_ z7Q@0#dyG0}LPKe1{;*9;x^~T!qV1Gyg1;keLT9U*L}Ng{sriWO6g2gxzkD85Dt3*= zi7Tr$fN=t_uU2B3tX%Fr&Y^OLZQUdkE~ZRbQ|%qI|mum`ZHXWUrr?`5T2j&O4aVMgaqwg!_e(u7J?$3>xqpM5T&T@4@1FrK6^0viF&L=MhREr z66?@2`L~unmi%BMHfK|ms?{7l=+722&K|-V3;hwfW3$Ecuiv|JV1AuHUVZrkOESqP z01Aj|X6=hv4l#cR4k2H=H1;Ni==$lak_Hh|3ma2!X1CkZolDh*?mOrcHLBydYGC)- zFHM=|?8gFsn;cZ>U?(}wq$iG)=EEvnMvF}5@hlk8`ysYUpIscPy(sNO=reP=Iaa@I z17GUJ8yxuG!c!6kyvE+BIX6Qz7qSk%0S4`L$CnL5CAz1WxVQXP9vSp%G6(Z86c2f_yx0~xnIqmt?I##-&k<(`b?>4q8PEJEs#0T+rRCL^o z3X;85C-8`US!opfPxH9HP*ekvG4x0yX)B_kOT?=}!d3N=&-=*c!5K!HTO<#lJ7+T; zeJp?j6}UyKnAl8>l8f)GKRF=<+A>Q%S@;9c?QnFNoHd#p`hJ3N zg%$|5=j#zlPz4SZ`}m|N(MO*#TAsT7B~nK98vlXDCn(V77$HeL*FSV{*#K)M=jczV4MEaL_-B*#D}I`cMk;BJf0CT}K@0HM4ziSjrE z=3%G0hKGaIZ&(;22~xS8LJ$y>Wq%|R$vnK*HnSFA`!WN`pWMH8sId4VKT@-mGt{w$?rp3WkA2>pnVqiq5K42P=!72lnVZiunO8Sku4LXALN5oou^yQ<;bM-Jm-(OJgZq)_0 ztLB`#{)6(mvmw9s3e-xs1+)Sc{iTS0g4pNndZCiPpBb4Nk;$sB!H`k)4Lq|x#jI)` zG}ToRsu8BO0z1%=qQPpx4;Ydq*R8&i3Z3rz=a4qDku=!w0A>U{z0(+9V-J0*KeXPu zst1}!l}`YPR_(u0n~lEtOFcqkZWtbKe-)N1Fh(lVA=_eb#W;R1jo@=S_MeIjI4&h9 zvIuKiuQqQrPOq}?8rnB67V|W0E>;LM%~lj%^(G^1*5xm`?Z8p#ecJ}L@|1#r4*ztw zB?Z4CT!zqmL8!$HFyo#Ngu4#-PK|hiPrys_^0M1Hc%DdLcj|R5gob(OHC&>Qxj( zd)s$$G)bTR${Q9VJp}`bLGT1hSn9_cbmrjZ$Y!vuFjFa5)qm#9$H!Bf`6vek5}@W3 zn5LR@M&fY?*E3OF`GLkLZ69;C75&KH#?*UY7;6#|I18O6ypU+(#mspWFC;<;cBJAi zR+xnf#f}uoz~869j++`HUY>H&>PdIucl(53wQ0Xgh0gqEQ{&G3-v~1O$I6xo!3oOr zUC(=a_HF6kc3$H|@;k0w8Iu`JfUZ-LfMtgLc=<|qVbynb?f8q3XxLUmQDP?PJk?MWT*=A#L?G3N?SH3YtB;5 zRJc_~8A6WxGA&*B2R}Q(*U~X_toPJv>ES+8?ePTVN{yrLWza7SH5f>c&)7OUYAFr7 zpr$SxTu5BDqOK-c%AML2nm{g`=$ zxD_OX(L?EHqOLw5>Jze&a}8%&hrsUcZ&R4D6mghpNuml!$0TAq3@@o~Z&9i}l|fuu zyNV0Hyu3jb|Bg(f-&W1S@ za&$ThE`>}^*zhQ(*02=Qk_yokE7gscY+b|pB=NWahNRt^^R}m@Ygfnp6S$Zjlrtn@ zez$BL+<^gg5po^BN5v2pUZPvkE-Y52dP<1|15XoKy^X-NkE1r`HUfZ(v2F*nL$?am zXKm{R$zb$)T8pH;3e75r>;1LIj)&$DwtvA{a2ClD<|N3A`4Zr5%l8yc*bJMv1W&jH zVK!U66!T`^B)+DHpkMepem0viK|`sPif~J0Dt2ap5?s8p0{UvE{mr}0uX?RGb!%B?N=?RI2{9dgHdDF}TFx?T-ipDjL^2{+sqK7DTUhmxXzj% z3a)39nnBLk8^eL~D~rc%=?fEs=~D?I5UOSQPOy^_8T)CXG*+sIk`bt`3Tn6*NF;F( z-^@VP`;c?Uh4S(LqV22WqTIShr3R$CmF^w}hLCQM?rsq228mHh>1IT_ySqz55fJGT zkPsxKJMQ2)?|aUX_kK6Nd*>g1zr}u5ueH~+pS{3}erpWbee2 zl7{c1{E&eO8$OTZ(%hmi}4W{%uPZc^0go<%G3b`u%&+ zkk-GCF$KfN!o^ZEg(U^#in1!yV^6=dZ}u*{tfYp1p&w_jG0;;Dzwxp5if3(6e1U+9 z7E%jsf*obD67e)}+8YU0#|nXyOc}N&ZaFD5IF_zQj@l9B+~47{$0TgW`i|-#U=1-v z_S|#0RIV`L^fZAt4QL2dZ^rFggG25vJY5$Y3@D1L;uM$LFj_QD8*(sxalU(D=J7R{ zZ48K9vyNQ_S|jZMs^28_T7`CK!dq8b@k`p$Yd@*)s`lr5DB?k0X;5%9>C=<_MPRU6 zLo%YhW2e32c(*Y^f6?$wvZ-TB&n_ghRphO5r+Z0b*)n20=E`HEW)-WC=*CQKG~mFd z4v}@FdgXrM(x#v^X3@hp;WC(|=p9(puT#l%c0b}<0f!S}0QKFaTeK{LL%p!0puDfo zlg?S#w8YKux$JpnFiVIZGLjMIJJZvyn$hVpucA7%bxrurBGa3r%XP;|WTQf^x>g-p z*54sKW@t3;`oe1YrMwJWG}KY5;l8CMi>m7(?6RmbXroy=sbVspq)OO}l^|+ALr(>KIv#-6VABOLvMqE-){>TD zrjuaH!{1FfkKY~NRW)J`A@F{s*o5%0yzX}3OF$0`veB`rZcJg8z!JkciP8IQIHY~i z>L^`KnS9z{`i?h7DN-4&t5SMJ7U}!4v~?R@)U6HTjmhYSUK{rK9zG%4`25N^&*XPD zoz;1R9lg7HK2)9RA%Dh%EGs2ANNtyN3Z-7DpL;2_sY#@BKv;rRFKz|AZB}K|Z?Kxe z5wJ+Km1>25M7^1;q;qzxE7bBf!#LJUzJhag%_+)llvwaGxMVRKhFg2drYW%$#I2$H zwV%J=ICDJxRloFYgo;iY?-3;SiA9n|MIHt_IrjPolY%OvA&sgJkOW@z%Q427k1Fqu zQ&y`U^YL>^GJXg4TVq5)p2#i`R6Qjg&o*YJl5kUZaQe17Erm0P1&Peokl2TR;r?- zx#nGDYFDEeJeI~%u<)U>2zXV@ZX`7JBi+M_-#x7~xRju)dB5@rLH_^kqW54v>}U@k ztmEvx+>)mWJNV6q-+HP21W~8c@O>EVTv)1*ea(=A%Bo7|f;v0s*rF;?HaPd&*`lYc zuJf!A8$7}dwusf&*5vO6y3$NWB!=H>S!F$H7?^7;9%Za=(H4N@il$5BfUHIf6(q(*E!*a_f4{`PeU7!y=1e_1Eex2y;G$DOhukH6<+* zTd$;yXj#bL-m;Y9wj{}EECRkaWiQ0~_8iG+x2euDxc!vlcZtAKwAvHo-U!PbeV3;# z-J(!EukTUX_T|!RmcoZ#J^l@Pp|w8QoHKz}ZtXx4BZP2+ffYeip|m9E@p~?V9i&S5 z$l2O5{vg{7DZ$E?hhWi;DR}nB)BIK6qu1909)Ir;@o&ru6DrJt)gvC(M$~w5^Y!Ck z=|hSfa$WB)=Bo6%O#xAvM~wz~M>Pg3KUg-y^-asneBj#~vmA0CMAjBO%F&2geKcoH zm;AyuT@%uKlGbQ0nAIB?6ZwUFD-tOhh@3dQ*z7ze$aPC1kR`LkZGiVUdsb&b5N`K9 z8h+5L2#iO9pi(&%Hlu+Y^)7F9aQvzJPRULAkQjm;amT2I8q@Y|-TQ1EdP}WTd*U>i zIe>40ZNY8_6IIY)Q5#_y&GND=S)`G^KdFvFFCS#V1TN^toIX^PhIEhAWdkFWvOk42 zt=0b_ng&X^5P&mq^`WC3{PO{?7O>WNJ`K|g5z6XulJ62v#3z-&obYXAotQ%9IFxG6 zBnc{^ye2Z$u*>bcD7Knu&3oVoUQ18=Jy>G;G#r>xIq{IN*G;-XhLl`;RGQJ6^eHy} zWK=DLMRUq73ya3!rqc;!L%?F&Bzu-!1G^ce;)s~$Oh^f9sz#$O&NO%YxritlI_r|6 zE9!@N{n5x_y^Q`9P-Z*F9FuAt2?xokQjVKH30lNOq%_8Zs^TxFCH!Xy2HSsgLBxpbtu>Ph+99ce&LjB?9lh7@-(?^t@Nw?q;iAZ|m91#}ucN3v`yCXe;HkJK~&L3s}Pc|H8HNiSF_Lsvh$w4T9HEYl=QI6cnmHq|_B|qxr zuzgNvuNeE0-A3yAB7G*DR$VQA96pR%lrr8Yc`%vV`s|oCpYW!4T)A)orlf;Jfb)2r za=b%=3d?iVpV@dAXKUw*1rpjwegfWpo&n(LmK$Z|&8s0KI=1E%6Q7EyzVwzV!&lZe zE7b#vv2ya^=MaNc^TQvzBk_meM`7j-ImzfwiwlkWM#*tu4?`KUfcuqo!5T_y5z$UE zim3Lt{yBN%*Uqk<=VXT8SERCBd^%fnxs1^lgbX2At#%%Gwt6eEi|PV+-t62G=9W%Q z>|+N_HW;K|CN3TkG||ora)8kHeQ26fnD7i}XqG7+zJn;3zt{L?5vg87kTI8SHSZCX z6kO-erB9L=#+usKuFnztxTfEj#YSFp)jButGELd}tk0k|d?P%zR%0zfO?Cf=aVp+^ zr{LFZnZUQ*6Q^<&$|E%9i{N;p@nza^Gxaqr-B{sWz`DZl$cOgCm8AeGrO1y&1h`p6 zh4NQn8>f&b`u2GQ?U552iPR-XeT6o|&OT}ZgVPdUXfIW2Z9o6w$twj zHI3x2bookW*e(?xl=epk#-eAP#MYjss3nLt$YYUqg)WwwF?vOC!L~ujmhrD-I+T4g zLDNHtj4wg=zYyX8`!Jv4_vq`AhJS8-CnB5cDc%d|Caq@@(f8r#xW%zhrFzuT*)p6= z8bd#nxa9wO!XT7aN0iolV{oHRf#JCuJFJv~E^kYNO=Pz~Z}`oV#;`rEL?0NXrvyZ^ z1xoGNR_kaw5T0_JeI;o}dmF8nCU#DB0>;0rjt3P19XQrW+!aXS)->^G2l!R$6^v|KRgl zqIegNBF;)M^x|6BkXFgy(Ih&Tcyp|=Zw-V!lf>iUNsXVKeG21lAaCGP0x`Is2>}FN zB00KeFSJNB9~n~4=vIMFPDDi#wDb@*RJ^d_iad)nbzSh>#|O9HgPI23quS4uuu!b5 zOzS<5g*UNEodWVms%%p_(@`)_5j#k0Qw;ogiqg8t^%G*J&)=d*u=iU;T#ys(IBOuC3$&#G7v4}5Lsa@$b|w# zOD+zTPrFXh@_95RBrY*M*}CgKqAZ9JAvSxuB`OnX?sc4t?gnd1p@KDEsZ005@Y5R^ zq6Wck70=cmAT8VnJ%@(2^DI_@qeEp745aa{7pW(8)^o90o{lmN9MR~}ty!9r+i)ia zeG>UXOI-j5R;w@*{W7tQ64r;TA%!lXVtmCk$oZj9g>o_AwOR5esdL{f2 zZr3f>`*Y^c2P3*#j&gRdcjV?P8y{u&&$$x{7$NR&L=NNg(MNpnc;hzV6eM0rc=1!* zhq;S%6E1w1^fPHYZIkGX)x!bD?XSdaeP*vh&t#K!t)DUK?~c`9(!7;jci$fHm7ozM z-7h!}R$O1_?mG=w6HcwvIX(m$S@Ub|Yp?lh3*~>^C;q=ar1X2A;a`(sY%T24 zv8{3d5yW2kkQe{@tFiNxvRF2i++3}t4}BHf2zDSw-57n@rHNU?e$q6Z2jJ;Q^kSO_ zdKQwsIQ;Va)3sFBk)a;SU_^-8TT9O2tU_cgPUV#%!J&L-fLy9*``h=fFT7lMk~^D1 zTDm+-;DozcI6B_3r5dnPDwx!DZFvj#39{^d?S#}&3#=IE6%mw}(7d%LGmX-MU@EaQ z#N^+6VN5aqND!@+2U1C}vz9_Ic$dv1O>FX-O4PA437#E)(WYpd3zTi9++3tPZq?dgzqNDTGkL6fyMlG@Jszz~ z@e1-XfQf$5=GnSL=?l7U_oA%@F3z=`bZmMmlEVW_<~h z#L;P*1+Mb0$a3au#tFh)f;xUb8*|**0bh)sE#ru1S{Uk9G^7znvprNeZ{VW+35TS? zbtC32;V7BxL0pwKZad73v-wn#Eoy$1t>zFO_=(BWZ0{6mc=T=da0ZryEG2yjMeOAF z$R!&hpDf+8SQ_;|vIWbUBt*5zPLARl7a_8iO?RD^7E^*=C#YQc458$SmqgBIFY!H* z*YB1>)gC;YGkWJPiM*9#-l<=PQyw-*F_I+0#~V}BHjjUO(2$X8Rhi2gjbs0Xjqnyy z%Ied7C8>}}^GYh_?0pC7Vr4hZe9rQiuvDtqsf4#W6d20w ze&KZ`(ZwxZX2<2YY2ug)FB+&d25E|Wk?D@`z*D0w96y;pK{Fy5#-hWi2YA&q2Gl>? zoD6ixHxoXk`T*Bw!@zu0O!Vo}3y~!hqO?3&g!x!u^enTmprbRPxr}dqMU}x?LkfJp z*%~hVuGbYP9b}ib#=YkhGQYbVjv_d}NFB8a?cR-4Jf%O!&6kPYH!oEpq^qQN!gW!B zT@BoTTm`ZGB3@EjdUfWG`6@|Ht7w!R71SA6{spAexAJ)k&@u?=V*RK!M<0d zWx@8N7WOk69{SCMEnPqnAE>7vyhj}z$~tPsBY(dGGhY7P=A6Q-&e zb*iM+uTo~uRXa`}eJ`Dnrj0H240#Rf!)NI!n(#*$woR6$Gc z0@Wkcv%76sTM}8>q)lJrUp<2pUsM^5TsJx_5M?13ZWzGV)!o7+E<_;2OqyLIiJS<{Z~T=4ryBoi0q|d^ zz<(|P{^z~pu*3(3*3|;&iSeb>9LBms*C;vFC^-Y4X!z;GDmd%AXhRQc0aOraPKC^8 z44yH;HwGP%>;8zZC`7B@TtB_$^CReYqFWkT^%m|j-rGH^nCm=xfoY23omUwL>Q?YB zibjkfa!|;lC3}%{%bRS}f0FA1$AA5~=VP0-ADf5J{EnpZ+7I*>aJHy%2ah}6=_9o3 ztIcpLy`VqCNq0=|`9!*>CZetiS(?Q>WZ{7T}6o+5fo-8Z}n*%z2|ArM?Sg3>;< zEIB zdEeHmVq~rvf!!cmg~-tV1QY)f)6TYw>FZ{vE^9TbV*GnCG;{WtQo_{FT`pqZkvO=X z`3Co@#grp5IMrrt9$SB*=oE(}Zoa*qwzx$$LzxL*NgjI>i9omcf&2UO^Q#>Nm2#G7 z2jj(npE*-w6t7ben^zZ*ogK!7TDf1A1yWz}NuE1ryn)+ShZ3)AG-tfm?-j^x`oWk~ zlka4*WiUaH&%@>qt^aaiSfKyB;=RRCJzM>9&pc*u3?Mwp9Pgl0cupLiIrBh%Wx3L_iFO!ZViVWxOW%#w|h-@B^AXR`#J29|KL7A(#cX3(#fJ{5y|ReeYmYi4t%?JagI zQ;iI^)?MXTFMPE!fWK_3+O5boyMxr4$jE8D`!?3^tJAmwLIQ0b8ItKza4b;}^AThE zr7j`aIVt;i31_m6T^Y%<Z&X+fv$|6^qY zYv)J{oo)iSLmu~pz6|dwv3SYwtmUE@%K0Qkj5EaI)w(K3B88S4>?^DGy|5TH3AY#V zbz6f>ByPpSmHvPdJ$#>$IOV|Q8RCG>*_LJevNT$2T-gyI1FnXW>FC~gqZ<Ljw|$ zszhI|_c$0unvu%@RUrbQ2m|q~P&j!h?nA&-1?#Ma4ix7vv=dmScYaHNcC zKOj$rnzMn)1u0IX^2QP=9Mg9&jCZxjHZ!OA%QjyLrPiuYvN;gX3M zz-LNo>m`evc)&$MMiX^3A$BpKo*9S}j3YXZ%BtL?>lf z^Wu!>H?eOqyo5w=>w*+d;aFHyS-KM)xY_Zg=pcAVSo~`XIv+EkmNJ*^bjA;rVn4nU zm&(m087`XBWRSME<=}rH`+92WOS(mP;h1ZVBJcS0{=ZSnO#UVDOYF6Lc>it2X|1~JYnDIXimjac7u3!XLH@Hd7|l$S}QObrr}DCRpRo#4$mPQhuZ@O-qt_7$>d zJ@rKLD$ta;d_F>AK^Q@p9F#h*KQtqj&&AEew0t%L` z@V_&0a`gbfi2SgdZGZLugBr90OdwA}C@@;Lt}A~mKbrSB)3!HlOcf>XVJ^@c(+x<` znis+CVkX;;EJky#x|k+o@81awM4Csl?%F{Fop!BKy6Xy>ybCOPWLS&yc)~ zquufOdmDY)x4}#}y8B%M$-|jV3#R+vK(8Q+y;u1rd$>s_ZEU&UD>{N;dv75}RA7Q< z2s2TeWnPaMM^2@lMl#E92Mge?>c8oR(2kLRG*=?UxNaf4 zsj7FdDW>!JK|w~m+()vbvy+Q-VmBAXQ@>s}?E45biTXYFEBs-#4Xrq{7B!xW@|LHd zdVw$jWKD@-@ax3j&rP zyhM!U9Xu9!y22G(mK$Z0v?5u@cOj2wt8z}o54Dp+Yo1jBR<|FLOeU2=mR(pLkxuEE zz_l5+-x2@=qr9B$w<^aO9w#ND1i9PgPtWU)@|f4FQ&`BhEk~IEen)${$F{mu-T*#kaeYujc}xodc^y?w zno0&!9d7{o`deG%$Vr5!kk|(ky2j*30uIGuC<;vY4Gd~K(?(~lc8FBVXkDNik6E{A zu3#MBv4!`Sxi|1zEbkW|NP-_3s^R7kn|S7HrDmd~RehO6-Sk2&nOlonuQySY_7O!F zoHy(Aj2Bksph{P+LQ-0aUVpf!mOirQklR7Bf-GP$rR^)Q-OSFL4MAPzJ*}};i2Y!o zrho1lQl$4FKXHbSo+oZLQ$be$n|J&r3*9k=J=Pa^x|HgWlO@&+>{)KQxsSQ}hYn}7 ziPZa?`-R?31G;78?wt!8-w!|dhWL6u^;mxL4%{)u9xjaopBmL4IN>v?a)=xoi9k=?v z<2H$9gzu5eAeDTxME0dTNuC^E#?ot5*X|oLuRtfb4t>=w<+@dW@xa|K6TPy&KMj96M%kV;L!$?N zMSADJKdzShPg_9$&lU>oKESpJ!7e?%i+TbGtVfpbRE5rl9N?*Zt}ttX;;VIuy5(F& zGlHGKm)|7Qb8QC%*Q07vZ!U%(%LV60X4@bjR7pHOweqyKIvu0Te&|o#{Klp^la|6a z+Y*2Hdd%x_ALt=NZDVS%f^GBwzU_@~_J;(H zAq@1jO43__F0^6P>Y|UTD-)$~T&OmA7D*TVc&OP-2f770fsOGRk7;+F zCMD;5@%fnd`D`bB0%sPa5=Uti#C`L;00Nu|zm4!GuCPIX_mj1Tf$7>Y|*lNO#XK1uVQi&Z+XKMe39k%r*10`hMItfR@ncV#ZW_E^=fu6JoRO)6_gju-N&+bz*C+YjW2K%9*`^+Y{EU2ke6ag z$LhBtP?a% zoVI!cczzYw?cm_rP)!ff$r$CQljgS9m3%t;ZtD}A^%7CcLKh{-WPgsn|K|_JTe;`x ztFXqIC4in`B*$nh>E7Q%krx$!>e8cY_1Vpa`6W zMSu3Zxzy`L=2o7~l`Ws07|upWLToKQ8{2qdiQ{Y(5&iX5;iIo!S&>R}a*0Y-Ed@LI zjTPMEP(uNg)|dJ7v0d1peA&8VNkzGSYeh_8^?fZh2~sE-GnsGp7Nj7$s_TB!?e%7A|gn}~mB z-WrQAtoKZEsPsV8hAlW}LnhmdUbtG>q{72pTlc~oi-#AE*P9|k!a+>5qENc8kbJ3o;+?d4Ro7X6`Fn}< z#C{JG#r2d=J*6|yb|Xo5&sM8OPa{S2w*|V|^1-!?x|l{i-q-mw)es{L0p^vPNHGP- z1sYs4122ts*OXL^NIKu>UY<5*QUVeCwQbSK=kv8KmY_M=#5u$fZ%UP~L@F%GZ%M6N z^p&8_Ui`+NeTBO~w>7YJh*rG4|w1b2VSix&$z zsN0s`$0ZU*s7^6Q#!PbkHb0CFPPnQk;KA;>c)JnSSF9UAU3*_DbZh8W{v{v&Z*08( zG7MXr$oT+phZ}1k`3NXPKwh-J6l>XXg$@h>C=hd+8L^>pUw+Z)`SRbd=v2mFHY`*rNSeUfz|Gf7^OxHVxp1hK|9Om~;5B+b*?_xO^%DJ578XT0E-P zW?d%L>0O~>Q9KB^H1BD@8h5bq*iDL(tF6h4K~8;?FZfNdmnZ_IP*mY{`OhCJ@P=Q{ zai#}je}b3QI-L39*Sa|Ty>fKV{Xj;bi(}(*G1~jpW&Z=MnDozrx_nU3DF7~a#;_Xx z_Q}ChLdX{*Q5&@CQdCt`OQ{?E3qRb>1f;J&9X<^BmiX_BuRBdY>Le}y5zlFYc!Qew zuroSxqpAFx?UdR$4}?UAPKc%4#i6e0r3Qn&yhEPW^#IzzjH+ZMRNjOF^?gbyTm5K* zvC&*h61Sli@ud!mSK`SwSxH1awd=#I`gu%wdl^WB9|t<((2kZz-?I>(h;nYjmz>fm zMxm^^>Gh2Whs8r!MMePnap@l}W}75R8w=Avs~n2uQJ| z%jat&3Q?nc`W{>tug8LYwcP1|-f`5g-8vQ>`sO5;n!lfB3moQDHrT$!3uxxCMylAF zd&~tn_BQ-v9;{@p31T#)Uf-rkn5>BRt{z zAh!5Xa;p8VXN#$^m&ukI$UZO#4oABz= z@v>jJPl8x>^dR4qSY@EcYvo79(*w zACoV~mJNHGh{w!^ez8dpf0o7^-thE|FK1oMsE6SYV?4RbbusGDq3X-m``E$epTqYM zogpJPr35D;sDX@`;(oW?S8;`aH*i;uDi-+IqPOKiRQP-km!-0dW$cQwZ0Dk%5g-N4 zV1`FA=M5ui%j#CQyi90#G+!f7BI?a?c@`~8*Y3h zo>zo}bCt#))4oY@FChC|NP+rl4vSC~)*u3R@=?IjUa%|~vD#$8&>>1S9xilB8a7vlBTxItrH}}+ zveO^oRv&JB?n5lkTAT9x*d`_j|CA&LUMZq`~(hL&r2kALM4QC+}DR*^#;THm_LMjcL~C0BB}`5 z0(cJU0iL@_0W7V%XDh2zX})P!Xg4PCSlrN#`CsW`Z~m{I$^U%w{9EGiTYx2}|UHKS5+I8>txlQok0 z=|%6Mr3>BEC_6bPA`F_e^{#|VMOjZu)ykT%^+8)%#omewoCy=|BRi(LEsFT++!7la z(8V;!Fl>@zMUm8wf z*s?x%Hnq0WX1;yvwYa$)N-PqKp}m_ky~$Sraf$K;mUj+iMc=Zb1{3xo>?;pm<3muM zP0`ai;#gs$jH)kg=;VYT>q?8*Cw+UG$E102?kVvg1qP8L|zZ4 zyf~EfyyKgA;>Vvjc{Q3tarMQQDB1B#PfjBdiZaM7TRxAV6x0VpmVF!bQ0p{>D6M92 ze6mWPB}Bgo&ick-kZ4W+++(BUsG<*Yy*8B9S01 zaXq?q2l$j^bd^S_#Wm9{oQYICD|Kl)VwaC{X2q2wgX}0&oq|3E@45Fk{UANQzYrBFWeZj#h>pN zIDF-2S}$|Kq$6i84|mGgUaZ8X3G(-#`Rw(zKE3PbmWN$P>`>8B4^Eyk zW=~gY^aQo{FZdq!2vI&k##YK(^HpWFS-z2gy&~l9csRMt)#RoH_%MA6mxQ3JcD5Ef zp|3*RjfY8WCH!jo$V}y9Cf|K^f7&pP@#O=+G(Y^rEi2iAsa&EFYM>Cg)%jC1A6Q6) z8@$qH88U#h=pj7_M^}J@*gB}%%VSh3mg<~b)RQ%AfK4z!#o_gcFhOlI<5epohfuFT zsoV}Po`KA9*TRoFYlUtsNBd`n>MNR(VXn?~@b3wsZ8OYi>xW3JNp@j##$4?@NLMWq zv)350#Z!^YW;gMHn-84i>OMO8pl1*+6QtBInR{QNvag)H z*%n)OjZ}2$TF*G%a5xf4b;N{1%a(tohp)^3(`v%@8vu;J&ku$+EC9qH8dahNEzwFH zN4%8SOVG}@;%`N@Fu$6JOIMvk`)E+R7++eDM$+#rFR+F!iFJ>3b(FxRXYMS^>@4ka zy<{q_f0h=ZAFt`~0Isxpj(FR;2^!F~WrsO91CQ@x+h}&)Fi|1)KmwPzWNsDhY@cIe zpXBIbGtLoL$7@SN7QQW_3M>;kR-1e>{(B0m-=MhEDJ(AO_L(uSz1R@%)X z2XQYWU5YZOIq=+Tijv!T5ow^Y>^*6{iNuB;?OK=`^6iJ@hweMf>|C#()&Eekt9b9u z-vlj=W1iT4P6-Xe+p`?`@S)P*J;EZd3E#?NN--F21l`d;fCJ>YrcUUQsVt8MS1g*0p5%GH3g_orq<<0K}h-odspZLMvf!;3hSHw1T8ZIOq zKEHuqhrh`zs49C;-~dehl!1vvqLutJqfaZz=Sh#)5t`pA1RxYC$fc$V;q>(-(N^J# zH6Qhgu(6wPO0&qcw@FivYIf*d&`j1&CtEusj}`2?-BOn;B@b~Zo9i+)vhW_oqpGTV z9@CiZoV|m;wW)wN_rO7<0TWB|=VOMKJFiE^oWy0+HF!wkRfD3(=bAn(+i(p2pwKa= z>xl*wShBpY6b!`dhikVx)F+KGk=@|r+>y`m0wqhHeYKB%S`+^^0wsC2W65Z}G{hq< ziIt!*MQ-|ZV(I%5q^gr%4@$lIE7sLl|EIBzvIg5(&CLtCzq8ssZb+?^6Fd0yNw4m( zVJ9t#Nx)!<_F#4GM_dZZ7>^JZT5jyx^&Q1;BjWhQI!EWja${-c-Cb9MRRq%s&t9*h ze5j$;l8Sv;8Ie_b@D$+em-fA}vQhbFGE}?ubc=hpvfZLkMa0{)2?LU(C-XAPK|A{s zPP)w4+zCn9L{My$D>&{({Z^S+Z8*C>M@sVNK-=s-$(+ zEaz7ai(}a+K!+z{$23fS-K*mp{?A0E2b+Lw$3iwBhEHQyqZ7d9I@b!*QVEHUH3dRH zqK`~R9xjXeNl$)cK){gCprS`vRqbo(pN4mcF!z^L%C?NIy8H)fKP^c9pb9gVs6+-* zIr=emdFw1mhm|tR?_rF%bo5P>O*GETEjxwCh#(sbrR6WliHy1pUhN*sa}KMqtMvu4 z9#F>vPr=l(zyz-@?%|SC+~I4Xx0w-rq95I?z)0)HY4Z$@h1&3yPoX25ca}=}@!vjd zSpNgS2Nhidc*6BGG_C=55dh>TJ%u9Z(9%uV%k4VoVGdMo@0VA+*!%0#-haJ<38v)c z`{O(RKMTqK{OzA(ANC1@i<|$~c}Eh+X~lFgmfC|@TpPb;n+M=3yd2ptl*|Walzg!= z;rp@u^RXUBKLvecRC%Kzq+XXVRmSTf8nK-s>1A|9n^)SSd?O(Y5LSy5^~j&D zf^>#*$iWhvOHm!M6@^<{7Lz*M>H;{=ld`M{W8!-vxP~OvZHJF0XliScE@MPqi=a-u ztGS{tHxFe;{b2DRE#PChZ~L>cdTO25DQ~n`cGvt`_2MDI1#Aj@Z@{Ltc_xCVYCh)* z*q;@&%av~~Q6L?{)uPfMABdFL-bZ9UEV0Un>p^48boc|(!{UP#6}g-!>vby7o5-KOBBWo*Aw@^DpW=cWK;g|cKQnLgVUL@Vf2(RaY(29 zQx4>h2e}k-J%}#a)H*4U>iTECWpN5Y&(Bhr+g8pt;Nl&Ud7O$eXRntA2ZxZ1RS>NtI?9vh%=N=&1 zZ0LL8qBQi4-|NXke#&Lq?>2S>$ZaNAi0|!)WhOSv6&9ExtnoofCN`28SxEFADnetQ zT#3HCdBny4EHWLHy?QuaIy5~jf3?#?QQ39OpB*M7d2m)6taxvBTbss~UpT5*UTJXh?B3JL56Gg)&wFh({D?u_9cTGT8&pKz`sE-H8H=yr~O zj<58=6a__g8^;84hWnf(!_Fn*g^qt(bfao#+pzmL4NK2Qjq~r9J({xDPU7bFjT#y{ zST4v)!oTwFNh%S!AqO6lgM;00M{>Ned%K=|>*vz?U{%veKpf5f{YtaeD0tLrr6W6S z6eBYSG}P0L?BGF^!F~fb`zGo9_nswC=_3FotXGNk(SKuVLI3-OoKVJN04F>rC)8#i zwu7sHPItIW>K!#BDyZ@T4kXoI$}~z<)VMq4DJPW5i1CG&a|xkIFg0yKcfsf3`!fZT zFUf5ZqN@d$#<8XRvqjCTnj|pkw=eFpK^r3 zyB5z%y;o7am9VyuKrf)AEfRAO<38?W8WV-glAb)Rdn!t^rNnvNez7byMM5iwMU*>O zDavAKN{q84LB_)CH%!hR+e?7A7r=AbWvl0QAPwn%b>tI;q zDg^PtadAo-b;@~&%GqYTp^_ym#Kk28#y%3?C(H@%d~S(`VIzp<0;j?CM10m_SZ~h* zBJw>#(yr`KMUg<{tyq?Cv7lLqbn6;@X-->Nl@^w(S0HVN$F5r3X@mS02q0~-9c zrmlDfP9piTq=O6tLuMwFly~H)zRWbx0kR@`;j}vaOnXjcj}JK>_i)NE5Z~~%YbhGv zZlj4(!3W%W#Qd9-@o{Y77n`g-qO^WWt4JTir>H4rOdgCFDeRlR`II3AKU$e6K9JMC zP10LQIwd+8Jt2tAhS-dptSA)mnbEygNh^B6B)QLl>l_la@#p~_Vi0yOuLDAz z>E$RX%C`9CCFuzEu!pNrozgY^TOOtbu4d1g!fon$A5x<97iKb?xZ334RFoTA-o|IB z;zb%fHcYO(UHg5LUYaxyP@3Fxl=HTE6!v+3TFa7)K+B?*-3ji7jnD@`)(UgB{#qO^0!C{UQwr1)=2f#D}P^aFv}RVk(w&|{xAJ}|ItIgR@@?L}=tyPOEv4za?tsFvMUz)|*W;Ob1K{Dv3=qzW5$=7TX zihHkW+|py?Po$`jdBC&!lTu1?U-ZoddE1THb8{}u5`Buu`D?1;(Ay@ynIxRh zhNkSA)Q&%P)~b(S$w}s9hdkcWPAJR2ScA97yiu@C{`vuv-=d!Jwa2U$>TI!A^I^TV zx!!^-?nn9ENKMARG7F=yTyAlDf-i~miLP+P4X;;`rakQFC^W`#<=NM|hb zWyKXZm&94{w(^5e_Lm8Gol9Lm_W$;F{aCUwB51 z3#QbD)bP&eF)idAw8}Y=&CyaWDB1+EWZ5Fl`?VAqcTiA9L!BlKUgC!^5RoFTlJ#`q zEImP4Ahrr_$)3U()2r7;aQcY=SvsSxo@4YAc7JxV#pU>JT3A*A*|yPbSHz@j)}WJ= z-cdA@5>bb6_tK2R`aMJpy;Fii#s!7Jk7cBqLMPJ??2^zwV{AxynKN@eIXfmg`TE-m z|K{ziEw-o1CgVF*@9+;0*9(2;o*|UWy^87Yh{t-HOAH0PY^#C#&oS_@he7=o(ISPH z2-=!@x%*#J1H?QEgtoB`zBdn4qm2go(C*}62%v<1_R)%9S*e1kwo*;KZ6~OGwVB+T zh5~G3nDiOrs-RpZOg~&rPlZ0}n&=YeT6p%}yrOdp8)5wiCEr)sb_!Y@{jnA7C3?Qq z-0Hx^D%E`Z>hx*WNpAzTN)zq1X9LR8pI3`!sL0HshSgBk_>3a_ChUb*YMjewFSRVTd1(EkkHgK014(F z(fHKV)r}I!!v!rm2T;QSq3dS=5F9U*>>NM>2Z9P*`~vEn1DK$=7XVVEUk^c(F90lb zcOARbI3yh19o#6{xH+V4T<$P&|GI9K;}5jle9*mf02LepFyQ#1#FsFn zJW#_6023aV^A{E!T|L-eULZdury-Q<0zeFny9D6D2K8P5nBl>k(ESS-KfKWOO8^H9 zDtHNCBm3jc>5nIQz%a6g94aoB9xxWb(6FmteCJ;RXrLxn0CLzfepdi8YS0}ySi`X= zPdHReU0~S>Hu@iOa6zN50fcZ|P=PA|BTOB`*8mbE7*~{P(5E*rwh(UskD(1$fOoL} z6~iNwLCtRfc=Z3o0s5CN{@kfDWCx24JB5Vn&Ta$> zVE@Csg_#xfOQCm2DS;r~L|WuKtLoeW9>XsGzBAY#3ghO3sqYVkLHDl#c!`zBxFr7+ z>^!AOAz*xj=U#eur`K-5bXPybGwi z-@ov2^Kf$B=>qZ_5P0XR|AcV?`Cxr?{{iFU=emot-(cMLVEmjQ*nzEoi~|8V`8Z)Z z{_|PLFNtA5e*WJi0Re%W+%W(7bKsxjfG`E#gK_^2;lIX#?hN_cvpm0R1_Xov!NB_i z@0kPygl!$W#~?Qs&u`j-jpOFL4}*b!X9mQ_e@FLD|NpWH2nYu8{4OyF$a_zPuz_5^ z*%Jf;@&SKm5Cr50{^naC5H~0AZ!~_{9|q(C{$@`Y40um7AZ~8p@9GC}!%+Sv9f+HU z8y1rPP(O&9m-}}ufVd&xyZd*38_37~yGcOY{IF{hej5kkyi1(_d=|uYmyLdd0YQJ0 z`0jrom~^0D0>kA0xB6kwdrkv_S>!%pUjBPp0DDu4gNhX z!(e>(Lza(^_dX5&fB6FBZ))Y|`G;zLNz8xW)9;e{@0#J~#>ch0PoP3|RQl|LYV&iQvK0DNDqeD}kXALd>62=l|@<9BBG@B0kQn!iOD1eRww ze=iR1VD}Od4<{Gb@BRUU@%&4Ye+k0F3B2dPFxb5m41@83DSypBf5kQrCv5)wO%fRF zUWVg=`QUGoz?cT{{B9Ch66O3oNx@*Ce+vTnqvX2Fws(c_-S6KK!NbXWZx(~WV0Xs- zJ`Q{@ws|!+)O{F3$VRz)Ht^%y4ntG4o6R ze@P5W%lFjEb$`;~;rjKq^iOTU!u_5gT-^7H7g&7p{^jU@)_**(Qudx&x$aNLuyOb5 zL>^cb_Iv(-!G14BL3fkqJqBSnoZgF1ShWoE%-?Jb1cC247YOF9zmJ2}YxkZ7f&X4| z-66iKDt_U+)Bj)U=lu^}4Vz`}A>;#t?l~(T|GnCPmlJ%?KX|!d)c<1om;FJ!K(2c! zlNa_X@Vmsk+~E7;xcTqHU{mVyVJZX_pN+YjalNChNIE?^q&rWk>e91sm zz85dmuwJUYq2Pp+bMOVMe;PRX#>DvqhUPs6rJJyvkPeKVcmp8Vki~+F{X;_2lC6NU zF!PyB2=iujD4f`|!Srh+3*myD* zWWi3*M>aq7gh2(e#5DtCd2+%({sZLTv)m`h98>TCkjPmfLjiB@jhqjlCv(|;Xt(1> zKU8RfK5u_|bbrJ3({5MVz!(B8!iUez?g~#XUvFP-G<2QoTj#s?C_Q{5c<1}K;4}!r gMqK}|@w#4DU;B30e-HhpiZyzlUaHmV?(x3*1sc6?6951J diff --git a/src/mod/endpoints/mod_khomp/include/cli.h b/src/mod/endpoints/mod_khomp/include/cli.h index bb251bb16b..5df472bb66 100644 --- a/src/mod/endpoints/mod_khomp/include/cli.h +++ b/src/mod/endpoints/mod_khomp/include/cli.h @@ -733,17 +733,21 @@ struct Cli options.push_back("fxs-global-orig"); options.push_back("fxs-co-dialtone"); options.push_back("fxs-bina"); + options.push_back("fxs-sharp-dial"); options.push_back("disconnect-delay"); options.push_back("delay-ringback-co"); options.push_back("delay-ringback-pbx"); options.push_back("ignore-letter-dtmfs"); options.push_back("fxo-send-pre-audio"); + options.push_back("fxo-busy-disconnection"); options.push_back("fxs-digit-timeout"); options.push_back("drop-collect-call"); options.push_back("kommuter-activation"); options.push_back("kommuter-timeout"); options.push_back("user-transfer-digits"); options.push_back("flash-to-digits"); + options.push_back("accountcode"); + options.push_back("audio-packet-length"); brief = "Get configuration options in the Khomp channel."; @@ -821,17 +825,21 @@ struct Cli options.push_back("fxs-global-orig"); options.push_back("fxs-co-dialtone"); options.push_back("fxs-bina"); + options.push_back("fxs-sharp-dial"); options.push_back("disconnect-delay"); options.push_back("delay-ringback-co"); options.push_back("delay-ringback-pbx"); options.push_back("ignore-letter-dtmfs"); options.push_back("fxo-send-pre-audio"); + options.push_back("fxo-busy-disconnection"); options.push_back("fxs-digit-timeout"); options.push_back("drop-collect-call"); options.push_back("kommuter-activation"); options.push_back("kommuter-timeout"); options.push_back("user-transfer-digits"); options.push_back("flash-to-digits"); + options.push_back("accountcode"); + options.push_back("audio-packet-length"); brief = "Ajust configuration options in the Khomp channel."; @@ -933,6 +941,36 @@ struct Cli bool execute(int argc, char *argv[]); } KhompRevision; + /* khomp dump config */ + static struct _KhompDumpConfig : public Command + { + _KhompDumpConfig() + { + complete_name = "dump config"; + brief = "Dump configuration values on screen."; + + usage = \ +"\nUsage: khomp dump config\n\n" \ +"Dump configuration values loaded on memory.\n "; + + _commands.push_back(this); + } + + /* just to hide unavaible options */ + bool removeUnavaible(const std::string &s) + { + if(s == "atxfer" || s == "blindxfer" || s == "callgroup" || + s == "mohclass" || s == "native-bridge" || s == "recording" || + s == "record-prefix" || s == "transferdigittimeout" || + s == "pickupgroup" || s == "has-ctbus" || + s == "user-transfer-digits") + return true; + return false; + } + + bool execute(int argc, char *argv[]); + } KhompDumpConfig; + /* khomp send command */ static struct _KhompSendCommand : public Command { diff --git a/src/mod/endpoints/mod_khomp/include/k3l.h b/src/mod/endpoints/mod_khomp/include/k3l.h index 046bd666b1..51686d0296 100644 --- a/src/mod/endpoints/mod_khomp/include/k3l.h +++ b/src/mod/endpoints/mod_khomp/include/k3l.h @@ -231,6 +231,8 @@ struct KVoIPSeize #define CM_USER_INFORMATION 0x0F +#define CM_USER_INFORMATION_EX 0x2B + #define CM_VOIP_SEIZE 0x23 @@ -369,6 +371,8 @@ struct KVoIPSeize #define EV_USER_INFORMATION 0x0F +#define EV_USER_INFORMATION_EX 0x1D + #define EV_DIALED_DIGIT 0x10 #define EV_SIP_REGISTER_INFO 0x11 @@ -713,6 +717,8 @@ enum KH100CtbusFreq #define CM_START_CADENCE 0xA1 #define CM_STOP_CADENCE 0xA2 + +#define CM_SET_INPUT_MODE 0xA3 #if !defined KR2D_H #define KR2D_H @@ -925,6 +931,7 @@ enum KSignGroupII #ifndef _KISDN_H_ #define _KISDN_H_ #define KMAX_USER_USER_LEN 32 +#define KMAX_USER_USER_EX_LEN 254 #define KMAX_SUBADRESS_INFORMATION_LEN 20 enum KQ931Cause @@ -1845,6 +1852,12 @@ struct KUserInformation int32 UserInfoLength; byte UserInfo[ KMAX_USER_USER_LEN ]; }; +struct KUserInformationEx +{ + int32 ProtocolDescriptor; + int32 UserInfoLength; + byte UserInfo[ KMAX_USER_USER_EX_LEN ]; +}; struct KISDNSubaddressInformation { KQ931TypeOfSubaddress TypeOfSubaddress; diff --git a/src/mod/endpoints/mod_khomp/include/khomp_pvt.h b/src/mod/endpoints/mod_khomp/include/khomp_pvt.h index d09be88567..b17d163cc6 100644 --- a/src/mod/endpoints/mod_khomp/include/khomp_pvt.h +++ b/src/mod/endpoints/mod_khomp/include/khomp_pvt.h @@ -305,8 +305,6 @@ struct KhompPvt { try { - //std::string type((name == "input_volume")?"input":"output"); - int i = Strings::tolong(value); if (i < -10 || i > 10) @@ -614,6 +612,7 @@ public: virtual bool indicateRinging(); virtual bool sendDtmf(std::string digit); + virtual void cleanupIndications(bool force); /* Methods */ @@ -849,7 +848,31 @@ public: if(!name) return NULL; - return switch_core_get_variable(name); +#if SWITCH_LESS_THAN(1,0,6) + const char * tmp = switch_core_get_variable(name); + + if(!tmp) return NULL; + + const char * val = strdup(tmp); + + return val; +#else + return switch_core_get_variable_dup(name); +#endif + } + + void freeFSGlobalVar(const char ** val) + { + if(!val || !*val) return; + +#if SWITCH_LESS_THAN(1,0,6) + free((void *)*val); + *val = NULL; +#else + char * v = (char *)*val; + switch_safe_free(v); + *val=NULL; +#endif } bool mixer(const char *file, const char *func, int line, diff --git a/src/mod/endpoints/mod_khomp/include/khomp_pvt_fxo.h b/src/mod/endpoints/mod_khomp/include/khomp_pvt_fxo.h index d91705b626..6e51af35bd 100644 --- a/src/mod/endpoints/mod_khomp/include/khomp_pvt_fxo.h +++ b/src/mod/endpoints/mod_khomp/include/khomp_pvt_fxo.h @@ -138,7 +138,7 @@ struct KhompPvtFXO: public KhompPvt TriState _var_fax_adjust; - //ChanTimer::Index _idx_disconnect; + ChanTimer::Index _busy_disconnect; }; /******************************************************************************/ KhompPvtFXO(K3LAPIBase::GenericTarget & target) : KhompPvt(target) @@ -240,6 +240,7 @@ struct KhompPvtFXO: public KhompPvt bool autoGainControl(bool enable); void setAnswerInfo(int answer_info); bool indicateBusyUnlocked(int cause, bool sent_signaling = false); + static void busyDisconnect(Board::KhompPvt * pvt); void reportFailToReceive(int fail_code); bool validContexts(MatchExtension::ContextListType & contexts, std::string extra_context = ""); @@ -266,13 +267,20 @@ struct KhompPvtFXO: public KhompPvt virtual bool cleanup(CleanupType type = CLN_HARD) { - //Board::board(_target.device)->_timers.del(callFXO()->_idx_disconnect); - //callFXO()->_idx_disconnect.reset(); - + try + { + Board::board(_target.device)->_timers.del(callFXO()->_busy_disconnect); + } + catch (K3LAPITraits::invalid_device & err) + { + LOG(ERROR, PVT_FMT(target(), "Unable to get device: %d!") % err.device); + } + call()->_flags.clear(Kflags::CALL_WAIT_SEIZE); call()->_flags.clear(Kflags::EARLY_RINGBACK); _transfer->clear(); + callFXO()->_busy_disconnect.reset(); switch (type) { @@ -312,6 +320,16 @@ struct KhompPvtFXO: public KhompPvt // static void delayedDisconnect(Board::KhompPvt * pvt); + void cleanupIndications(bool force) + { + if (call()->_indication == INDICA_BUSY && !force) + { + DBG(FUNC, PVT_FMT(_target, "skipping busy indication cleanup on FXO channel.")); + return; + } + + KhompPvt::cleanupIndications(force); + } }; /******************************************************************************/ /******************************************************************************/ diff --git a/src/mod/endpoints/mod_khomp/include/khomp_pvt_kxe1.h b/src/mod/endpoints/mod_khomp/include/khomp_pvt_kxe1.h index 0267f33f24..c32071b981 100644 --- a/src/mod/endpoints/mod_khomp/include/khomp_pvt_kxe1.h +++ b/src/mod/endpoints/mod_khomp/include/khomp_pvt_kxe1.h @@ -272,24 +272,39 @@ struct KhompPvtISDN: public KhompPvtE1 bool process(std::string name, std::string value = "") { - if (name == "uui") + if ((name == "uui" ) || (name == "uui_ex")) { - Strings::vector_type values; - Strings::tokenize(value, values, "#", 2); - - try + if(value.find("#") != std::string::npos) { - std::string uui_proto_s = values[0]; - std::string uui_data_s = values[1]; + Strings::vector_type values; + Strings::tokenize(value, values, "#", 2); - _uui_descriptor = Strings::toulong(uui_proto_s); - _uui_information.append(uui_data_s); + try + { + std::string uui_proto_s = values[0]; + _uui_extended = (name == "uui_ex"); + _uui_descriptor = Strings::toulong(uui_proto_s); + _uui_information.clear(); - DBG(FUNC, FMT("uui adjusted (%s, '%s')!") % uui_proto_s.c_str() % uui_data_s.c_str()); - } - catch (...) + for (unsigned int i = 0; i < values[1].size(); ++i) + _uui_information += STG(FMT("%02hhx") % ((unsigned char)values[1][i])); + + DBG(FUNC, FMT("uui adjusted (ex=%s, proto=%s, data='%s')!") + % (_uui_extended ? "true" : "false") + % uui_proto_s.c_str() + % _uui_information.c_str()); + } + catch (...) + { + LOG(ERROR, FMT("invalid %s protocol descriptor: '%s' is not a number.") + % (_uui_extended ? "uui_ex" : "uui") + % value.c_str()); + } + } + else { - LOG(ERROR, FMT("invalid uui protocol descriptor: '%s' is not a number.") % value.c_str()); + LOG(ERROR, FMT("invalid %s protocol descriptor, need a '#'.") + % (_uui_extended ? "uui_ex" : "uui")) } } else if (name == "usr_xfer") @@ -306,6 +321,7 @@ struct KhompPvtISDN: public KhompPvtE1 bool clear() { + _uui_extended = false; _uui_descriptor = -1; _uui_information.clear(); _isdn_cause = -1; @@ -322,6 +338,7 @@ struct KhompPvtISDN: public KhompPvtE1 long int _uui_descriptor; std::string _uui_information; long int _isdn_cause; + bool _uui_extended; /* what should we dial to trigger an user-signaled transfer? */ /* used for xfer on user signaling */ @@ -329,6 +346,13 @@ struct KhompPvtISDN: public KhompPvtE1 std::string _user_xfer_buffer; std::string _digits_buffer; std::string _qsig_number; + + /* isdn information */ + std::string _isdn_orig_type_of_number; + std::string _isdn_orig_numbering_plan; + std::string _isdn_dest_type_of_number; + std::string _isdn_dest_numbering_plan; + std::string _isdn_orig_presentation; }; /******************************************************************************/ @@ -429,12 +453,29 @@ struct KhompPvtISDN: public KhompPvtE1 std::string descriptor = STG(FMT("%d") % callISDN()->_uui_descriptor); + setFSChannelVar("KUserInfoExtended", (callISDN()->_uui_extended ? "true" : "false")); setFSChannelVar("KUserInfoDescriptor", descriptor.c_str()); setFSChannelVar("KUserInfoData", callISDN()->_uui_information.c_str()); + callISDN()->_uui_extended = false; callISDN()->_uui_descriptor = -1; callISDN()->_uui_information.clear(); } + + if (!callISDN()->_isdn_orig_type_of_number.empty()) + setFSChannelVar("KISDNOrigTypeOfNumber", callISDN()->_isdn_orig_type_of_number.c_str()); + + if (!callISDN()->_isdn_dest_type_of_number.empty()) + setFSChannelVar("KISDNDestTypeOfNumber", callISDN()->_isdn_dest_type_of_number.c_str()); + + if (!callISDN()->_isdn_orig_numbering_plan.empty()) + setFSChannelVar("KISDNOrigNumberingPlan", callISDN()->_isdn_orig_numbering_plan.c_str()); + + if (!callISDN()->_isdn_dest_numbering_plan.empty()) + setFSChannelVar("KISDNDestNumberingPlan", callISDN()->_isdn_dest_numbering_plan.c_str()); + + if (!callISDN()->_isdn_orig_presentation.empty()) + setFSChannelVar("KISDNOrigPresentation", callISDN()->_isdn_orig_presentation.c_str()); } catch(Board::KhompPvt::InvalidSwitchChannel & err) { @@ -444,8 +485,33 @@ struct KhompPvtISDN: public KhompPvtE1 KhompPvtE1::setSpecialVariables(); } - Transfer * _transfer; + virtual void getSpecialVariables() + { + try + { + const char * isdn_orig_type = getFSChannelVar("KISDNOrigTypeOfNumber"); + const char * isdn_dest_type = getFSChannelVar("KISDNDestTypeOfNumber"); + const char * isdn_orig_numbering = getFSChannelVar("KISDNOrigNumberingPlan"); + const char * isdn_dest_numbering = getFSChannelVar("KISDNDestNumberingPlan"); + const char * isdn_orig_presentation = getFSChannelVar("KISDNOrigPresentation"); + LOG(ERROR, PVT_FMT(_target,"ISDNORIG: %s") % (isdn_orig_type ? isdn_orig_type : "")); + + callISDN()->_isdn_orig_type_of_number = (isdn_orig_type ? isdn_orig_type : ""); + callISDN()->_isdn_dest_type_of_number = (isdn_dest_type ? isdn_dest_type : ""); + callISDN()->_isdn_orig_numbering_plan = (isdn_orig_numbering ? isdn_orig_numbering : ""); + callISDN()->_isdn_dest_numbering_plan = (isdn_dest_numbering ? isdn_dest_numbering : ""); + callISDN()->_isdn_orig_presentation = (isdn_orig_presentation ? isdn_orig_presentation : ""); + } + catch(Board::KhompPvt::InvalidSwitchChannel & err) + { + LOG(ERROR, PVT_FMT(_target, "(ISDN) %s") % err._msg.c_str()); + } + + KhompPvt::getSpecialVariables(); + } + + Transfer * _transfer; }; /******************************************************************************/ /********************************* R2 Channel *********************************/ @@ -472,7 +538,6 @@ struct KhompPvtR2: public KhompPvtE1 { LOG(ERROR, FMT("invalid r2 category: '%s' is not a number.") % value.c_str()); } - } else { @@ -554,7 +619,23 @@ struct KhompPvtR2: public KhompPvtE1 { return (CallR2 *)call(); } - + + bool forceDisconnect(void) + { + char cmd[] = { 0x07, (char)(_target.object + 1) }; + + try + { + Globals::k3lapi.raw_command(_target.device, 0, cmd, sizeof(cmd)); + } + catch(K3LAPI::failed_raw_command &e) + { + return false; + } + + return true; + }; + int makeCall(std::string params = ""); bool doChannelAnswer(CommandRequest &); bool doChannelHangup(CommandRequest &); @@ -609,9 +690,9 @@ struct KhompPvtR2: public KhompPvtE1 /* r2 caller category */ if (callR2()->_r2_category != -1) { - setFSChannelVar("KR2GotCategory",Verbose::signGroupII((KSignGroupII)callR2()->_r2_category).c_str()); + setFSChannelVar("KR2GotCategory",STG(FMT("%d") % callR2()->_r2_category).c_str()); + setFSChannelVar("KR2StrCategory",Verbose::signGroupII((KSignGroupII)callR2()->_r2_category).c_str()); } - } catch(Board::KhompPvt::InvalidSwitchChannel & err) { @@ -834,9 +915,9 @@ struct KhompPvtFXS: public KhompPvt _ring_off_ext = -1; _incoming_exten.clear(); - _flash_transfer.clear(); + //_flash_transfer.clear(); - _uuid_other_session.clear(); + //_uuid_other_session.clear(); return Call::clear(); } @@ -850,10 +931,10 @@ struct KhompPvtFXS: public KhompPvt std::string _incoming_exten; - ChanTimer::Index _idx_transfer; + //ChanTimer::Index _idx_transfer; - std::string _flash_transfer; - std::string _uuid_other_session; + //std::string _flash_transfer; + //std::string _uuid_other_session; }; @@ -936,9 +1017,9 @@ struct KhompPvtFXS: public KhompPvt std::string extra_context = ""); bool isOK(void); - bool startTransfer(); - bool stopTransfer(); - bool transfer(std::string & context, bool blind = false); + //bool startTransfer(); + //bool stopTransfer(); + //bool transfer(std::string & context, bool blind = false); bool hasNumberDial() { return false; } @@ -996,7 +1077,7 @@ struct KhompPvtFXS: public KhompPvt static OrigToNseqMapType generateNseqMap(); static void dialTimer(KhompPvt * pvt); - static void transferTimer(KhompPvt * pvt); + //static void transferTimer(KhompPvt * pvt); static std::string padOrig(std::string orig_base, unsigned int padding) { @@ -1015,21 +1096,16 @@ struct KhompPvtFXS: public KhompPvt return STG(FMT(STG(FMT("%%0%dd") % orig_size)) % (orig_numb + padding)); } - /* - virtual void getSpecialVariables() + void cleanupIndications(bool force) { - try + if (call()->_indication == INDICA_BUSY && !force) { - } - catch(Board::KhompPvt::InvalidSwitchChannel & err) - { - LOG(ERROR, PVT_FMT(_target, "(FXS) %s") % err._msg.c_str()); + DBG(FUNC, PVT_FMT(_target, "skipping busy indication cleanup on FXS channel.")); + return; } - KhompPvt::getSpecialVariables(); + KhompPvt::cleanupIndications(force); } - */ - }; /******************************************************************************/ /******************************************************************************/ diff --git a/src/mod/endpoints/mod_khomp/include/opt.h b/src/mod/endpoints/mod_khomp/include/opt.h index 270adc7068..4bc65361a6 100644 --- a/src/mod/endpoints/mod_khomp/include/opt.h +++ b/src/mod/endpoints/mod_khomp/include/opt.h @@ -108,10 +108,13 @@ struct Options Config::Value< bool > _recording; Config::Value< bool > _has_ctbus; Config::Value< bool > _fxs_bina; - Config::Value< bool > _fxo_send_pre_audio; + Config::Value< bool > _fxs_sharp_dial; Config::Value< bool > _drop_collect_call; Config::Value< bool > _ignore_letter_dtmfs; Config::Value< bool > _optimize_audio_path; + + Config::Value< bool > _fxo_send_pre_audio; + Config::Value< unsigned int > _fxo_busy_disconnection; Config::Value< bool > _auto_fax_adjustment; Config::Value< unsigned int > _fax_adjustment_timeout; diff --git a/src/mod/endpoints/mod_khomp/include/revision.h b/src/mod/endpoints/mod_khomp/include/revision.h index b0ace1ad42..717124dda9 100644 --- a/src/mod/endpoints/mod_khomp/include/revision.h +++ b/src/mod/endpoints/mod_khomp/include/revision.h @@ -1 +1 @@ -#define MOD_KHOMP_VERSION "1.0 - (rev: 5891)" +#define MOD_KHOMP_VERSION "1.0 - (rev: 6034)" diff --git a/src/mod/endpoints/mod_khomp/src/cli.cpp b/src/mod/endpoints/mod_khomp/src/cli.cpp index 621afe6a20..b5bcbdd924 100644 --- a/src/mod/endpoints/mod_khomp/src/cli.cpp +++ b/src/mod/endpoints/mod_khomp/src/cli.cpp @@ -75,6 +75,7 @@ void Cli::registerCommands(APIFunc func,switch_loadable_module_interface_t **mod " khomp channels unblock {all | all | }\n" \ " khomp clear links [ []]\n" \ " khomp clear statistics [ []]\n" \ +" khomp dump config\n" \ " khomp get