From d48057e23f97af11cbdc482b20a06eaba776ea82 Mon Sep 17 00:00:00 2001 From: Hristo Trendev Date: Thu, 9 Oct 2014 11:37:52 +0200 Subject: [PATCH 1/3] account for lost frames during ptime detection This allows the "broken ptime" detection to work correctly when packet loss is present on the wire. In addition to the timestamps this patch adds frame sequence tracking and corrects the timestamp difference only as needed and according to the number of lost packets. FS-6898 #resolve --- src/switch_core_media.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 73d404cfa9..0bb1669215 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -95,6 +95,7 @@ typedef struct switch_rtp_engine_s { switch_codec_implementation_t write_impl; switch_size_t last_ts; + switch_size_t last_seq; uint32_t check_frames; uint32_t mismatch_count; uint32_t last_codec_ms; @@ -1743,6 +1744,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session engine->check_frames = 0; engine->last_ts = 0; + engine->last_seq = 0; do_cng = 1; } @@ -1869,8 +1871,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session uint32_t codec_ms = (int) (engine->read_frame.timestamp - engine->last_ts) / (engine->read_impl.samples_per_second / 1000); + if (engine->last_seq && (int) (engine->read_frame.seq - engine->last_seq) > 1) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Correcting calculated ptime value from %d to %d to compensate for %d lost packet(s)\n", codec_ms, codec_ms / (int) (engine->read_frame.seq - engine->last_seq), (int) (engine->read_frame.seq - engine->last_seq - 1)); + codec_ms = codec_ms / (int) (engine->read_frame.seq - engine->last_seq); + } + if ((codec_ms % 10) != 0 || codec_ms > engine->read_impl.samples_per_packet * 10) { engine->last_ts = 0; + engine->last_seq = 0; goto skip; } @@ -1918,11 +1926,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session } engine->last_ts = engine->read_frame.timestamp; + engine->last_seq = engine->read_frame.seq; } else { engine->mismatch_count = 0; engine->last_ts = 0; + engine->last_seq = 0; } } @@ -4560,6 +4570,7 @@ SWITCH_DECLARE(void) switch_core_media_reset_autofix(switch_core_session_t *sess engine->check_frames = 0; engine->last_ts = 0; + engine->last_seq = 0; } From 28bc992fcedbdf7814556074da856944fcbd9bfe Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Thu, 9 Oct 2014 11:38:53 -0400 Subject: [PATCH 2/3] mod_rayo: fix error in SRGS grammar parser... 7715 will return MATCH_END with input of 7 instead of MATCH since 715 is a potential match with further input. --- src/mod/event_handlers/mod_rayo/srgs.c | 6 +++++- src/mod/event_handlers/mod_rayo/test_srgs/main.c | 9 ++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/srgs.c b/src/mod/event_handlers/mod_rayo/srgs.c index ab4e570323..5eff43f0a4 100644 --- a/src/mod/event_handlers/mod_rayo/srgs.c +++ b/src/mod/event_handlers/mod_rayo/srgs.c @@ -1256,12 +1256,16 @@ static int is_match_end(pcre *compiled_regex, const char *input) search = search_set; } search_input[input_size] = *search++; - result = pcre_exec(compiled_regex, NULL, search_input, input_size + 1, 0, 0, + result = pcre_exec(compiled_regex, NULL, search_input, input_size + 1, 0, PCRE_PARTIAL, ovector, sizeof(ovector) / sizeof(ovector[0])); if (result > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "not match end\n"); return 0; } + if (result == PCRE_ERROR_PARTIAL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "partial match possible - not match end\n"); + return 0; + } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "is match end\n"); return 1; diff --git a/src/mod/event_handlers/mod_rayo/test_srgs/main.c b/src/mod/event_handlers/mod_rayo/test_srgs/main.c index 2a102e8939..237e9edad3 100644 --- a/src/mod/event_handlers/mod_rayo/test_srgs/main.c +++ b/src/mod/event_handlers/mod_rayo/test_srgs/main.c @@ -11,8 +11,9 @@ static const char *adhearsion_menu_grammar = " \n" " 01\n" " 15\n" - " 27\n" + " 77\n" " 39\n" + " 4715\n" " \n" " \n" "\n"; @@ -43,8 +44,10 @@ static void test_match_adhearsion_menu_grammar(void) ASSERT_STRING_EQUALS("1", interpretation); ASSERT_EQUALS(SMT_NO_MATCH, srgs_grammar_match(grammar, "6", &interpretation)); ASSERT_NULL(interpretation); - ASSERT_EQUALS(SMT_MATCH_END, srgs_grammar_match(grammar, "7", &interpretation)); - ASSERT_STRING_EQUALS("2", interpretation); + ASSERT_EQUALS(SMT_MATCH, srgs_grammar_match(grammar, "7", &interpretation)); + ASSERT_STRING_EQUALS("7", interpretation); + ASSERT_EQUALS(SMT_MATCH_END, srgs_grammar_match(grammar, "715", &interpretation)); + ASSERT_STRING_EQUALS("4", interpretation); ASSERT_EQUALS(SMT_NO_MATCH, srgs_grammar_match(grammar, "8", &interpretation)); ASSERT_NULL(interpretation); ASSERT_EQUALS(SMT_MATCH_END, srgs_grammar_match(grammar, "9", &interpretation)); From 855cc4b4e0f91e45f48f71372be312a9594b680b Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Thu, 9 Oct 2014 14:43:16 -0400 Subject: [PATCH 3/3] add 908-retry-seconds gateway param to set reg retry time when getting a 908 for backup interfaces to connect quickly --- src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia.c | 7 +++++++ src/mod/endpoints/mod_sofia/sofia_reg.c | 4 +++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 2aab666248..f4e361318c 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -505,6 +505,7 @@ struct sofia_gateway { switch_bool_t ping_monitoring; uint8_t flags[REG_FLAG_MAX]; int32_t retry_seconds; + int32_t fail_908_retry_seconds; int32_t reg_timeout_seconds; int32_t failure_status; reg_state_t state; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index af7d4b9857..94adf806ec 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -3320,6 +3320,7 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) *context = profile->context, *expire_seconds = "3600", *retry_seconds = "30", + *fail_908_retry_seconds = NULL, *timeout_seconds = "60", *from_user = "", *from_domain = NULL, *outbound_proxy = NULL, *register_proxy = NULL, *contact_host = NULL, *contact_params = "", *params = NULL, *register_transport = NULL, @@ -3434,6 +3435,8 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) context = val; } else if (!strcmp(var, "expire-seconds")) { expire_seconds = val; + } else if (!strcmp(var, "908-retry-seconds")) { + fail_908_retry_seconds = val; } else if (!strcmp(var, "retry-seconds")) { retry_seconds = val; } else if (!strcmp(var, "timeout-seconds")) { @@ -3547,6 +3550,10 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) gateway->retry_seconds = atoi(retry_seconds); + if (fail_908_retry_seconds) { + gateway->fail_908_retry_seconds = atoi(fail_908_retry_seconds); + } + if (gateway->retry_seconds < 5) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid retry-seconds of %d on gateway %s, using the value of 30 instead.\n", gateway->retry_seconds, name); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 8b3373ce9a..d4177195d1 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -493,7 +493,9 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now) { int sec; - if (gateway_ptr->failure_status == 503 || gateway_ptr->failure_status == 908 || gateway_ptr->failures < 1) { + if (gateway_ptr->fail_908_retry_seconds && gateway_ptr->failure_status == 908) { + sec = gateway_ptr->fail_908_retry_seconds; + } else if (gateway_ptr->failure_status == 503 || gateway_ptr->failure_status == 908 || gateway_ptr->failures < 1) { sec = gateway_ptr->retry_seconds; } else { sec = gateway_ptr->retry_seconds * gateway_ptr->failures;