From 36ffb292983b11702a90be48d9054ffbbd87dcd8 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 13 Jun 2016 12:25:22 +0300 Subject: [PATCH 001/128] FS-9256: mod_v8: Add DB.Finalize() in order to close statements. --- src/mod/languages/mod_v8/include/fscoredb.hpp | 1 + src/mod/languages/mod_v8/src/fscoredb.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/src/mod/languages/mod_v8/include/fscoredb.hpp b/src/mod/languages/mod_v8/include/fscoredb.hpp index 5ac0a052b5..e15e308f1d 100644 --- a/src/mod/languages/mod_v8/include/fscoredb.hpp +++ b/src/mod/languages/mod_v8/include/fscoredb.hpp @@ -72,6 +72,7 @@ public: JS_COREDB_FUNCTION_DEF(Prepare); JS_COREDB_FUNCTION_DEF(BindText); JS_COREDB_FUNCTION_DEF(BindInt); + JS_COREDB_FUNCTION_DEF(Finalize); JS_COREDB_GET_PROPERTY_DEF(GetProperty); }; diff --git a/src/mod/languages/mod_v8/src/fscoredb.cpp b/src/mod/languages/mod_v8/src/fscoredb.cpp index a846eb8bbf..9bcb00c38f 100644 --- a/src/mod/languages/mod_v8/src/fscoredb.cpp +++ b/src/mod/languages/mod_v8/src/fscoredb.cpp @@ -232,6 +232,14 @@ JS_COREDB_FUNCTION_IMPL(Step) StepEx(info, SWITCH_CORE_DB_DONE); } +JS_COREDB_FUNCTION_IMPL(Finalize) +{ + if (_stmt) { + switch_core_db_finalize(_stmt); + _stmt = NULL; + } +} + JS_COREDB_FUNCTION_IMPL(Fetch) { HandleScope handle_scope(info.GetIsolate()); @@ -415,6 +423,7 @@ static const js_function_t db_methods[] = { {"prepare", FSCoreDB::Prepare}, {"bindText", FSCoreDB::BindText}, {"bindInt", FSCoreDB::BindInt}, + {"finalize", FSCoreDB::Finalize}, {0} }; From 8fe1a584c8432dbfdfaf8a13641cec03f27f0cde Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 14 Jun 2016 13:27:10 -0500 Subject: [PATCH 002/128] FS-9244 fix debug lines --- src/switch_core_media.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index f1295b0ee5..5df93d519b 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -4849,7 +4849,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s continue; } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CONSOLE, "Video Codec Compare [%s:%d]/[%s:%d]\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d]/[%s:%d]\n", rm_encoding, map->rm_pt, imp->iananame, imp->ianacode); if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) { vmatch = (map->rm_pt == imp->ianacode) ? 1 : 0; @@ -4873,7 +4873,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s matches[m_idx].imp = imp; matches[m_idx].map = map; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CONSOLE, "Video Codec Compare [%s:%d] +++ is saved as a match\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d] +++ is saved as a match\n", imp->iananame, map->rm_pt); m_idx++; } From 5fea56286efbbc0498d03c7040aa276bd60a2599 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 14 Jun 2016 15:29:27 -0500 Subject: [PATCH 003/128] FS-9265 #resolve [INCOMPATIBLE_DESTINATION when there is no rtcp] --- src/switch_core_media.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 5df93d519b..9bed078a58 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3576,7 +3576,7 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t done_choosing: - if (!engine->ice_in.is_chosen[0] || !engine->ice_in.is_chosen[1]) { + if (!engine->ice_in.is_chosen[0]) { /* PUNT */ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "%s no suitable candidates found.\n", switch_channel_get_name(smh->session->channel)); From c0499fbb22b42839b7df8c7bcc8a15dfcb6c1c4e Mon Sep 17 00:00:00 2001 From: Seven Du Date: Wed, 15 Jun 2016 09:34:26 +0800 Subject: [PATCH 004/128] FS-9266 #resolve --- src/include/switch_core_video.h | 4 ++-- src/mod/applications/mod_cv/mod_cv.cpp | 2 +- src/mod/formats/mod_vlc/mod_vlc.c | 2 +- src/switch_core_video.c | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/include/switch_core_video.h b/src/include/switch_core_video.h index 068a138107..babe865f4e 100644 --- a/src/include/switch_core_video.h +++ b/src/include/switch_core_video.h @@ -352,10 +352,10 @@ SWITCH_DECLARE(void) switch_img_find_position(switch_img_position_t pos, int sw, * * \param[in] src The image descriptor * \param[in] dest The target memory address -* \param[in] size The size of target memory address used for bounds check +* \param[in] stride Bytes in a row for the destination. Pass 0 if the buffer has contiguous rows. Can be negative. A multiple of 16 is optimal. * \param[in] fmt The target format */ -SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *dest, switch_size_t size, switch_img_fmt_t fmt); +SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *dest, int stride, switch_img_fmt_t fmt); /*!\brief convert raw memory to switch_img_t * * if dest is NULL then a new img is created, user should destroy it later, diff --git a/src/mod/applications/mod_cv/mod_cv.cpp b/src/mod/applications/mod_cv/mod_cv.cpp index 5c10b8d42b..76cf155a6e 100644 --- a/src/mod/applications/mod_cv/mod_cv.cpp +++ b/src/mod/applications/mod_cv/mod_cv.cpp @@ -720,7 +720,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi switch_assert(context->rawImage->width * 3 == context->rawImage->widthStep); } - switch_img_to_raw(frame->img, context->rawImage->imageData, context->rawImage->widthStep * context->h, SWITCH_IMG_FMT_RGB24); + switch_img_to_raw(frame->img, context->rawImage->imageData, context->rawImage->widthStep, SWITCH_IMG_FMT_RGB24); detectAndDraw(context); if (context->detected.simo_count > 20) { diff --git a/src/mod/formats/mod_vlc/mod_vlc.c b/src/mod/formats/mod_vlc/mod_vlc.c index dbacf4e513..3cd8a2cebb 100644 --- a/src/mod/formats/mod_vlc/mod_vlc.c +++ b/src/mod/formats/mod_vlc/mod_vlc.c @@ -1659,7 +1659,7 @@ int vlc_write_video_imem_get_callback(void *data, const char *cookie, int64_t * } *output = context->video_frame_buffer; - switch_img_to_raw(img, *output, *size, SWITCH_IMG_FMT_YUY2); + switch_img_to_raw(img, *output, 0, SWITCH_IMG_FMT_YUY2); switch_img_free(&img); return 0; } diff --git a/src/switch_core_video.c b/src/switch_core_video.c index 4a32027fed..e4cb5f1ad3 100644 --- a/src/switch_core_video.c +++ b/src/switch_core_video.c @@ -2031,7 +2031,7 @@ static inline uint32_t switch_img_fmt2fourcc(switch_img_fmt_t fmt) } #endif -SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *dest, switch_size_t size, switch_img_fmt_t fmt) +SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *dest, int stride, switch_img_fmt_t fmt) { #ifdef SWITCH_HAVE_YUV uint32_t fourcc; @@ -2050,7 +2050,7 @@ SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *des ret = ConvertFromI420(src->planes[0], src->stride[0], src->planes[1], src->stride[1], src->planes[2], src->stride[2], - dest, size, + dest, stride, src->d_w, src->d_h, fourcc); From 05cc7708188fa040dcb903cdcdae28990fa177a8 Mon Sep 17 00:00:00 2001 From: Muhammad Zaka Date: Fri, 27 May 2016 11:52:38 +0100 Subject: [PATCH 005/128] FS-9192-proxy-hold: proxy hold when proxy media and proxy mode are disabled; its similiar to proxy-refer --- .../endpoints/mod_sofia/conf/sofia.conf.xml | 5 ++ src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia.c | 64 +++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/conf/sofia.conf.xml b/src/mod/endpoints/mod_sofia/conf/sofia.conf.xml index 46095e9a6d..a03f52ac00 100644 --- a/src/mod/endpoints/mod_sofia/conf/sofia.conf.xml +++ b/src/mod/endpoints/mod_sofia/conf/sofia.conf.xml @@ -495,6 +495,11 @@ really need to change this. --> + + + diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 1ff30451da..512f239eb4 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -293,6 +293,7 @@ typedef enum { PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER, PFLAG_FIRE_TRANFER_EVENTS, PFLAG_BLIND_AUTH_ENFORCE_RESULT, + PFLAG_PROXY_HOLD, /* No new flags below this line */ PFLAG_MAX diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 35062228dc..4addb1dedc 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -5617,6 +5617,12 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT); } + } else if (!strcasecmp(var, "proxy-hold")) { + if(switch_true(val)) { + sofia_set_pflag(profile, PFLAG_PROXY_HOLD); + } else { + sofia_clear_pflag(profile, PFLAG_PROXY_HOLD); + } } } @@ -7659,6 +7665,64 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } goto done; } else { + if (sofia_test_pflag(profile, PFLAG_PROXY_HOLD)) { + switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); + if (tech_pvt->mparams.num_codecs){ + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); + } + if (!match) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite Codec Error!\n"); + nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END()); + goto done; + } + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + switch_core_session_message_t *msg; + + msg = switch_core_session_alloc(other_session, sizeof(*msg)); + if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp)) { + const char *hold_msg = "hold"; + + msg->message_id = SWITCH_MESSAGE_INDICATE_HOLD; + if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) { + const char *info = switch_channel_get_variable(channel, "presence_call_info"); + + if (info) { + if (switch_stristr("private", info)) { + hold_msg = "hold-private"; + } + } + } + sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_set_flag(channel, CF_LEG_HOLDING); + switch_channel_presence(tech_pvt->channel, "unknown", hold_msg, NULL); + } else { + msg->message_id = SWITCH_MESSAGE_INDICATE_UNHOLD; + sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_clear_flag(channel, CF_LEG_HOLDING); + switch_channel_presence(tech_pvt->channel, "unknown", "unhold", NULL); + } + msg->from = __FILE__; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Indicating Hold to other leg.\n%s\n", r_sdp); + + switch_core_session_queue_message(other_session, msg); + switch_core_session_rwunlock(other_session); + } + switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + if (sofia_use_soa(tech_pvt)){ + nua_respond(tech_pvt->nh, SIP_200_OK, + SIPTAG_CONTACT_STR(tech_pvt->reply_contact), + SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str), + SOATAG_REUSE_REJECTED(1), + SOATAG_AUDIO_AUX("cn telephone-event"), + TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END()); + } else { + nua_respond(tech_pvt->nh, SIP_200_OK, + NUTAG_MEDIA_ENABLE(0), + SIPTAG_CONTACT_STR(tech_pvt->reply_contact), + SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END()); + } + goto done; + } if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_NEGOTIATED)) { nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END()); goto done; From 2475c2686f0757bad4039bc6da4782ff5a5b6742 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Wed, 15 Jun 2016 18:35:59 -0400 Subject: [PATCH 006/128] FS-9271: [mod_conference] fix segfault trying to record a canvas that does not exist --- src/mod/applications/mod_conference/conference_api.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index fe93d42ce9..1cfa8dbb48 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -2529,6 +2529,10 @@ switch_status_t conference_api_sub_record(conference_obj_t *conference, switch_s if (id == 0 && conference->canvases[0]) id = 1; + if (id > conference->canvas_count) { + id = 1; + } + if (id > 0) { stream->write_function(stream, "Record file %s canvas %d\n", argv[2], id); } else { From b0be5d67375fb8b23bccf2e4e544bc8a2afeb4e1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 15 Jun 2016 21:08:46 -0500 Subject: [PATCH 007/128] FS-9267 #resolve [Raw decoded image from vpx codec is corrupted by video media bugs that modify the image] --- src/include/switch_types.h | 6 ++++-- src/mod/applications/mod_cv/mod_cv.cpp | 4 ++-- src/switch_core_media.c | 12 +++++++++++- src/switch_vpx.c | 10 ++++++++++ 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 8279e10a7f..527f6e597c 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1627,7 +1627,8 @@ typedef enum { SWITCH_CODEC_FLAG_AAL2 = (1 << 6), SWITCH_CODEC_FLAG_PASSTHROUGH = (1 << 7), SWITCH_CODEC_FLAG_READY = (1 << 8), - SWITCH_CODEC_FLAG_HAS_PLC = (1 << 15) + SWITCH_CODEC_FLAG_HAS_PLC = (1 << 15), + SWITCH_CODEC_FLAG_VIDEO_PATCHING = (1 << 16) } switch_codec_flag_enum_t; typedef uint32_t switch_codec_flag_t; @@ -1769,7 +1770,8 @@ typedef enum { SMBF_WRITE_VIDEO_STREAM = (1 << 20), SMBF_VIDEO_PATCH = (1 << 21), SMBF_SPY_VIDEO_STREAM = (1 << 22), - SMBF_SPY_VIDEO_STREAM_BLEG = (1 << 23) + SMBF_SPY_VIDEO_STREAM_BLEG = (1 << 23), + SMBF_READ_VIDEO_PATCH = (1 << 24) } switch_media_bug_flag_enum_t; typedef uint32_t switch_media_bug_flag_t; diff --git a/src/mod/applications/mod_cv/mod_cv.cpp b/src/mod/applications/mod_cv/mod_cv.cpp index 76cf155a6e..ac643a3ff6 100644 --- a/src/mod/applications/mod_cv/mod_cv.cpp +++ b/src/mod/applications/mod_cv/mod_cv.cpp @@ -1167,7 +1167,7 @@ SWITCH_STANDARD_APP(cv_bug_start_function) int x, n; char *argv[25] = { 0 }; int argc; - switch_media_bug_flag_t flags = SMBF_READ_VIDEO_PING; + switch_media_bug_flag_t flags = SMBF_READ_VIDEO_PING | SMBF_READ_VIDEO_PATCH; const char *function = "mod_cv"; if ((bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_cv_bug_"))) { @@ -1228,7 +1228,7 @@ SWITCH_STANDARD_API(cv_bug_api_function) char *nested_cascade_path = NULL; char *lbuf = NULL; int x, n, i; - switch_media_bug_flag_t flags = SMBF_READ_VIDEO_PING; + switch_media_bug_flag_t flags = SMBF_READ_VIDEO_PING | SMBF_READ_VIDEO_PATCH; const char *function = "mod_cv"; if (zstr(cmd)) { diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 9bed078a58..d909c09ce2 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -11524,6 +11524,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core switch_io_event_hook_video_read_frame_t *ptr; uint32_t loops = 0; switch_media_handle_t *smh; + int patchers = 0; switch_assert(session != NULL); @@ -11679,7 +11680,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core if (bp->callback && switch_test_flag(bp, SMBF_READ_VIDEO_PING)) { + if (switch_test_flag(bp, SMBF_READ_VIDEO_PATCH)) { + patchers++; + } + bp->video_ping_frame = *frame; + if (bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_VIDEO_PING) == SWITCH_FALSE || (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL))) { ok = SWITCH_FALSE; @@ -11705,7 +11711,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core } } - + if (patchers) { + switch_set_flag((*frame)->codec, SWITCH_CODEC_FLAG_VIDEO_PATCHING); + } else { + switch_clear_flag((*frame)->codec, SWITCH_CODEC_FLAG_VIDEO_PATCHING); + } if (status == SWITCH_STATUS_SUCCESS) { switch_core_session_video_read_callback(session, *frame); diff --git a/src/switch_vpx.c b/src/switch_vpx.c index ebfe51da97..a6a475f577 100644 --- a/src/switch_vpx.c +++ b/src/switch_vpx.c @@ -299,6 +299,7 @@ struct vpx_context { switch_memory_pool_t *pool; switch_buffer_t *pbuffer; switch_time_t start_time; + switch_image_t *patch_img; }; typedef struct vpx_context vpx_context_t; @@ -1264,6 +1265,12 @@ end: switch_set_flag(frame, SFF_WAIT_KEY_FRAME); } + if (frame->img && (codec->flags & SWITCH_CODEC_FLAG_VIDEO_PATCHING)) { + switch_img_free(&context->patch_img); + switch_img_copy(frame->img, &context->patch_img); + frame->img = context->patch_img; + } + return status; } @@ -1326,6 +1333,9 @@ static switch_status_t switch_vpx_destroy(switch_codec_t *codec) vpx_context_t *context = (vpx_context_t *)codec->private_info; if (context) { + + switch_img_free(&context->patch_img); + if ((codec->flags & SWITCH_CODEC_FLAG_ENCODE)) { vpx_codec_destroy(&context->encoder); } From 6c3710df4dc14751b60ba8f8ed4780e0f6288ec8 Mon Sep 17 00:00:00 2001 From: Matthew Grooms Date: Thu, 16 Jun 2016 15:34:37 -0500 Subject: [PATCH 008/128] FS-9264: Introduce two new api calls named detect_audio and detect_audio_silence. The existing wait_for_silence call never actually waits for silence until it first detects non-silence. There is also no way to set an independent timeout for detecting both the non-silence and then silence. This causes problems when wait_for_silence is called on an already quiet channel. Splitting the function up into two separate calls with separate timeouts offers more flexibility. --- src/include/switch_ivr.h | 6 + .../applications/mod_dptools/mod_dptools.c | 60 +++++ src/switch_ivr_play_say.c | 253 ++++++++++++++++++ 3 files changed, 319 insertions(+) diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 7d6d6ac1db..06fa8c137a 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -414,6 +414,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_tone_detect_session(switch_core_sessi SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *session, switch_file_handle_t *fh, const char *file, switch_input_args_t *args); +SWITCH_DECLARE(switch_status_t) switch_ivr_detect_audio(switch_core_session_t *session, uint32_t thresh, uint32_t audio_hits, + uint32_t timeout_ms, const char *file); + +SWITCH_DECLARE(switch_status_t) switch_ivr_detect_silence(switch_core_session_t *session, uint32_t thresh, uint32_t silence_hits, + uint32_t timeout_ms, const char *file); + SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_silence(switch_core_session_t *session, uint32_t thresh, uint32_t silence_hits, uint32_t listen_hits, uint32_t timeout_ms, const char *file); diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index d071321ddb..669fa6583c 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -4356,6 +4356,62 @@ SWITCH_STANDARD_APP(wait_for_silence_function) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", WAIT_FOR_SILENCE_SYNTAX); } +#define DETECT_AUDIO_SYNTAX " []" +SWITCH_STANDARD_APP(detect_audio_function) +{ + char *argv[5] = { 0 }; + uint32_t thresh, audio_hits, timeout_ms = 0; + int argc; + char *lbuf = NULL; + + if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data)) + && (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 3) { + thresh = atoi(argv[0]); + audio_hits = atoi(argv[1]); + timeout_ms = atoi(argv[2]); + + if (argv[3]) { + timeout_ms = switch_atoui(argv[3]); + } + + if (thresh > 0 && audio_hits > 0) { + switch_ivr_detect_audio(session, thresh, audio_hits, timeout_ms, argv[4]); + return; + } + + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", DETECT_AUDIO_SYNTAX); +} + +#define DETECT_SILENCE_SYNTAX " []" +SWITCH_STANDARD_APP(detect_silence_function) +{ + char *argv[5] = { 0 }; + uint32_t thresh, silence_hits, timeout_ms = 0; + int argc; + char *lbuf = NULL; + + if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data)) + && (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 3) { + thresh = atoi(argv[0]); + silence_hits = atoi(argv[1]); + timeout_ms = atoi(argv[2]); + + if (argv[3]) { + timeout_ms = switch_atoui(argv[3]); + } + + if (thresh > 0 && silence_hits > 0) { + switch_ivr_detect_silence(session, thresh, silence_hits, timeout_ms, argv[4]); + return; + } + + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", DETECT_SILENCE_SYNTAX); +} + static switch_status_t event_chat_send(switch_event_t *message_event) { @@ -6270,6 +6326,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC); SWITCH_ADD_APP(app_interface, "say", "say", "say", say_function, SAY_SYNTAX, SAF_NONE); + SWITCH_ADD_APP(app_interface, "detect_audio", "detect_audio", "detect_audio", detect_audio_function, DETECT_AUDIO_SYNTAX, + SAF_NONE); + SWITCH_ADD_APP(app_interface, "detect_silence", "detect_silence", "detect_silence", detect_silence_function, DETECT_SILENCE_SYNTAX, + SAF_NONE); SWITCH_ADD_APP(app_interface, "wait_for_silence", "wait_for_silence", "wait_for_silence", wait_for_silence_function, WAIT_FOR_SILENCE_SYNTAX, SAF_NONE); SWITCH_ADD_APP(app_interface, "session_loglevel", "session_loglevel", "session_loglevel", session_loglevel_function, SESSION_LOGLEVEL_SYNTAX, diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 4a1d6da68c..5da20b25ae 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -2111,6 +2111,259 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_silence(switch_core_session_ return status; } +SWITCH_DECLARE(switch_status_t) switch_ivr_detect_audio(switch_core_session_t *session, uint32_t thresh, + uint32_t audio_hits, uint32_t timeout_ms, const char *file) +{ + uint32_t score, count = 0, j = 0; + double energy = 0; + switch_channel_t *channel = switch_core_session_get_channel(session); + int divisor = 0; + uint32_t channels; + switch_frame_t *read_frame; + switch_status_t status = SWITCH_STATUS_FALSE; + int16_t *data; + uint32_t hits = 0; + switch_codec_t raw_codec = { 0 }; + int16_t *abuf = NULL; + switch_frame_t write_frame = { 0 }; + switch_file_handle_t fh = { 0 }; + int32_t sample_count = 0; + switch_codec_implementation_t read_impl = { 0 }; + switch_core_session_get_read_impl(session, &read_impl); + + if (timeout_ms) { + sample_count = (read_impl.actual_samples_per_second / 1000) * timeout_ms; + } + + if (file) { + if (switch_core_file_open(&fh, + file, + read_impl.number_of_channels, + read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE); + return SWITCH_STATUS_NOTFOUND; + } + switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE); + write_frame.data = abuf; + write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; + } + + + if (switch_core_codec_init(&raw_codec, + "L16", + NULL, + NULL, + read_impl.actual_samples_per_second, + read_impl.microseconds_per_packet / 1000, + 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, + NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { + + status = SWITCH_STATUS_FALSE; + goto end; + } + + write_frame.codec = &raw_codec; + + divisor = read_impl.actual_samples_per_second / 8000; + channels = read_impl.number_of_channels; + + switch_core_session_set_read_codec(session, &raw_codec); + + while (switch_channel_ready(channel)) { + + status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); + + if (!SWITCH_READ_ACCEPTABLE(status)) { + break; + } + + if (sample_count) { + sample_count -= raw_codec.implementation->samples_per_packet; + if (sample_count <= 0) { + switch_channel_set_variable(channel, "detect_audio_timeout", "true"); + switch_channel_set_variable_printf(channel, "detect_audio_hits", "%d", hits); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "switch_ivr_detect_audio: TIMEOUT %d hits\n", hits); + break; + } + } + + if (abuf) { + switch_size_t olen = raw_codec.implementation->samples_per_packet; + + if (switch_core_file_read(&fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) { + break; + } + + write_frame.samples = (uint32_t) olen; + write_frame.datalen = (uint32_t) (olen * sizeof(int16_t) * fh.channels); + if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) { + break; + } + } + + data = (int16_t *) read_frame->data; + + for (energy = 0, j = 0, count = 0; count < read_frame->samples; count++) { + energy += abs(data[j++]); + j += channels; + } + + score = (uint32_t) (energy / (read_frame->samples / divisor)); + + if (score >= thresh) { + hits++; + } else { + hits=0; + } + + if (hits > audio_hits) { + switch_channel_set_variable(channel, "detect_audio_timeout", "false"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "switch_ivr_detect_audio: AUDIO DETECTED\n"); + break; + } + } + + switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE); + switch_core_codec_destroy(&raw_codec); + + end: + + if (abuf) { + + switch_core_file_close(&fh); + free(abuf); + } + + return status; +} + +SWITCH_DECLARE(switch_status_t) switch_ivr_detect_silence(switch_core_session_t *session, uint32_t thresh, + uint32_t silence_hits, uint32_t timeout_ms, const char *file) +{ + uint32_t score, count = 0, j = 0; + double energy = 0; + switch_channel_t *channel = switch_core_session_get_channel(session); + int divisor = 0; + uint32_t channels; + switch_frame_t *read_frame; + switch_status_t status = SWITCH_STATUS_FALSE; + int16_t *data; + uint32_t hits = 0; + switch_codec_t raw_codec = { 0 }; + int16_t *abuf = NULL; + switch_frame_t write_frame = { 0 }; + switch_file_handle_t fh = { 0 }; + int32_t sample_count = 0; + switch_codec_implementation_t read_impl = { 0 }; + switch_core_session_get_read_impl(session, &read_impl); + + + if (timeout_ms) { + sample_count = (read_impl.actual_samples_per_second / 1000) * timeout_ms; + } + + if (file) { + if (switch_core_file_open(&fh, + file, + read_impl.number_of_channels, + read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE); + return SWITCH_STATUS_NOTFOUND; + } + switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE); + write_frame.data = abuf; + write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; + } + + + if (switch_core_codec_init(&raw_codec, + "L16", + NULL, + NULL, + read_impl.actual_samples_per_second, + read_impl.microseconds_per_packet / 1000, + 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, + NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { + + status = SWITCH_STATUS_FALSE; + goto end; + } + + write_frame.codec = &raw_codec; + + divisor = read_impl.actual_samples_per_second / 8000; + channels = read_impl.number_of_channels; + + switch_core_session_set_read_codec(session, &raw_codec); + + while (switch_channel_ready(channel)) { + + status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); + + if (!SWITCH_READ_ACCEPTABLE(status)) { + break; + } + + if (sample_count) { + sample_count -= raw_codec.implementation->samples_per_packet; + if (sample_count <= 0) { + switch_channel_set_variable(channel, "detect_silence_timeout", "true"); + switch_channel_set_variable_printf(channel, "detect_silence_hits", "%d", hits); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "switch_ivr_detect_silence: TIMEOUT %d hits\n", hits); + break; + } + } + + if (abuf) { + switch_size_t olen = raw_codec.implementation->samples_per_packet; + + if (switch_core_file_read(&fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) { + break; + } + + write_frame.samples = (uint32_t) olen; + write_frame.datalen = (uint32_t) (olen * sizeof(int16_t) * fh.channels); + if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) { + break; + } + } + + data = (int16_t *) read_frame->data; + + for (energy = 0, j = 0, count = 0; count < read_frame->samples; count++) { + energy += abs(data[j++]); + j += channels; + } + + score = (uint32_t) (energy / (read_frame->samples / divisor)); + + if (score <= thresh) { + hits++; + } else { + hits=0; + } + + if (hits > silence_hits) { + switch_channel_set_variable(channel, "detect_silence_timeout", "false"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "switch_ivr_detect_silence: SILENCE DETECTED\n"); + break; + } + } + + switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE); + switch_core_codec_destroy(&raw_codec); + + end: + + if (abuf) { + + switch_core_file_close(&fh); + free(abuf); + } + + return status; +} + SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session, uint32_t min_digits, uint32_t max_digits, From 5502f4f53742e9731ea1a09a22ea0a1553817c69 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 17 Jun 2016 13:41:59 -0400 Subject: [PATCH 009/128] FS-9260: fix make detection to not fail on openbsed, and fix libtoolize detection to attempt to find libtoolize the same version as specified libtool --- bootstrap.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 97237d7a95..f3bed2d4e1 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -159,7 +159,7 @@ check_lt_ver() { check_libtoolize() { # check libtoolize availability if [ -n "${LIBTOOL}" ]; then - libtoolize=${LIBTOOLIZE:-`dirname "${libtool}"`/libtoolize} + libtoolize=${LIBTOOLIZE:-`dirname "${LIBTOOL}"`/libtoolize} else libtoolize=${LIBTOOLIZE:-`${LIBDIR}/apr/build/PrintPath glibtoolize libtoolize libtoolize22 libtoolize15 libtoolize14`} fi @@ -190,7 +190,7 @@ check_make() { make=`which make` if [ -x "$make" ]; then - make_version=`$make --version | grep GNU` + make_version=`$make --version || true | grep GNU` if [ $? -ne 0 ]; then make=`which gmake` if [ -x "$make" ]; then From 53ed9ce06f7a94c84432017a2ef3af3bd8b882c6 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 17 Jun 2016 15:31:18 -0400 Subject: [PATCH 010/128] FS-9260: [build] add -ltermcap for openbsd so it can correctly link to libedit --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index bfc55fa89e..274014e8a3 100644 --- a/configure.ac +++ b/configure.ac @@ -793,7 +793,7 @@ case "$host" in ;; *openbsd*) APR_ADDTO(CPPFLAGS, -I/usr/local/include) - APR_ADDTO(LDFLAGS, -L/usr/local/lib) + APR_ADDTO(LDFLAGS, -L/usr/local/lib -ltermcap) APR_ADDTO(SWITCH_AM_CFLAGS, -I/usr/local/include) ;; *netbsd*) From 257e8d6b2fcd387c20690d31649f23e2da54e042 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 17 Jun 2016 15:54:37 -0400 Subject: [PATCH 011/128] FS-9263: [build] attempt to find the proper lua5.2 version on openbsd --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 274014e8a3..0a3702cb46 100644 --- a/configure.ac +++ b/configure.ac @@ -597,7 +597,7 @@ AC_SUBST(SYS_XMLRPC_CFLAGS) AC_SUBST(SYS_XMLRPC_LDFLAGS) AM_CONDITIONAL([SYSTEM_XMLRPCC],[test "${enable_xmlrpcc}" = "yes"]) -for luaversion in lua5.2 lua-5.2 lua5.1 lua-5.1 lua; do +for luaversion in lua5.2 lua-5.2 lua52 lua5.1 lua-5.1 lua; do PKG_CHECK_MODULES([LUA],[${luaversion}],[have_lua=yes],[have_lua=no]) if test ${have_lua} = yes; then break From dc13f59ee87f7cd37cce0fc02eac9a68406f793b Mon Sep 17 00:00:00 2001 From: William King Date: Mon, 20 Jun 2016 08:59:04 -0700 Subject: [PATCH 012/128] FS-9283 --resolve --- src/mod/applications/mod_hiredis/mod_hiredis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_hiredis/mod_hiredis.c b/src/mod/applications/mod_hiredis/mod_hiredis.c index a81f86f8ff..00b04c6a7b 100644 --- a/src/mod/applications/mod_hiredis/mod_hiredis.c +++ b/src/mod/applications/mod_hiredis/mod_hiredis.c @@ -376,7 +376,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_hiredis_load) SWITCH_ADD_LIMIT(limit_interface, "hiredis", hiredis_limit_incr, hiredis_limit_release, hiredis_limit_usage, hiredis_limit_reset, hiredis_limit_status, hiredis_limit_interval_reset); - SWITCH_ADD_APP(app_interface, "hiredis_raw", "hiredis_raw", "hiredis_raw", raw_app, "", SAF_NONE); + SWITCH_ADD_APP(app_interface, "hiredis_raw", "hiredis_raw", "hiredis_raw", raw_app, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); SWITCH_ADD_API(api_interface, "hiredis_raw", "hiredis_raw", raw_api, ""); return SWITCH_STATUS_SUCCESS; From 841e2025a82e7e74843bbae25cfa4f4b048c0c9b Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Tue, 21 Jun 2016 09:48:55 -0400 Subject: [PATCH 013/128] FS-9287 Add channel variable to make spandsp_start_tone_detect easier to use from dialplan / embedded scripts. The following variables are added: execute_on_spandsp_tone_detect_ : executes APP when tone is detected. For example, if you have a tone named "SIT" defined in spandsp.conf.xml, the variable would be "execute_on_spandsp_tone_detect_SIT" api_on_spandsp_tone_detect_ : similar to execute_on except that it executes an API. spandsp_tone_detect_stop_on_tone : default is false. If true, detector will stop once the first matching tone is detected. --- .../applications/mod_spandsp/mod_spandsp_dsp.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c b/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c index 40b804f86a..5ca1fcb87c 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II + * Copyright (C) 2005-2016, Anthony Minessale II * * Version: MPL 1.1 * @@ -849,17 +849,22 @@ static switch_bool_t callprogress_detector_process_buffer(switch_media_bug_t *bu tone_detector_process_buffer(detector, frame->data, frame->samples, &detected_tone); if (detected_tone) { switch_event_t *event = NULL; - switch_channel_t *channel = NULL; + switch_channel_t *channel = switch_core_session_get_channel(session); + const char *execute_on_tone_var = switch_core_session_sprintf(session, "execute_on_spandsp_tone_detect_%s", detected_tone); + const char *api_on_tone_var = switch_core_session_sprintf(session, "api_on_spandsp_tone_detect_%s", detected_tone); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "DETECTED TONE: %s\n", detected_tone); + switch_channel_execute_on(channel, execute_on_tone_var); + switch_channel_api_on(channel, api_on_tone_var); if (switch_event_create(&event, SWITCH_EVENT_DETECTED_TONE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detected-Tone", detected_tone); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session)); - - channel = switch_core_session_get_channel(session); - if (channel) switch_channel_event_set_data(channel, event); - + switch_channel_event_set_data(channel, event); switch_event_fire(&event); } + if (switch_true(switch_channel_get_variable(channel, "spandsp_tone_detect_stop_on_tone"))) { + /* all done */ + return SWITCH_FALSE; + } } break; } From c4ebb8485af31581a012e0d18ca87c4548c1af75 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 22 Jun 2016 16:39:43 -0500 Subject: [PATCH 014/128] FS-9292 #resolve [Core dump playing videos or show images] --- src/switch_core_media.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index d909c09ce2..0a63c44970 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -5255,7 +5255,7 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void switch_core_media_gen_key_frame(session); - if (smh->video_write_fh->mm.source_fps) { + if (mh->video_write_fh && smh->video_write_fh->mm.source_fps) { fps = (int) smh->video_write_fh->mm.source_fps; } else { fps = video_globals.fps; From 459a696eba1cc9a703cb94819ef32379f5459a08 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 22 Jun 2016 17:10:59 -0500 Subject: [PATCH 015/128] FS-9292 #resolve [Core dump playing videos or show images] --- src/switch_core_media.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 0a63c44970..3f5249afb4 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -5255,7 +5255,7 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void switch_core_media_gen_key_frame(session); - if (mh->video_write_fh && smh->video_write_fh->mm.source_fps) { + if (smh->video_write_fh && smh->video_write_fh->mm.source_fps) { fps = (int) smh->video_write_fh->mm.source_fps; } else { fps = video_globals.fps; From ce087fcea6c6100fa7ad2850a41ff193aa0cd1f4 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 23 Jun 2016 16:07:31 -0500 Subject: [PATCH 016/128] FS-9296 #resolve [Video support for mod_httapi] --- src/mod/applications/mod_httapi/mod_httapi.c | 26 +++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_httapi/mod_httapi.c b/src/mod/applications/mod_httapi/mod_httapi.c index 87f2203742..39f9051c1a 100644 --- a/src/mod/applications/mod_httapi/mod_httapi.c +++ b/src/mod/applications/mod_httapi/mod_httapi.c @@ -2967,12 +2967,18 @@ static switch_status_t file_open(switch_file_handle_t *handle, const char *path, context->cache_file, handle->channels, handle->samplerate, - SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL)) != SWITCH_STATUS_SUCCESS) { + handle->flags, NULL)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid cache file %s opening url %s Discarding file.\n", context->cache_file, path); unlink(context->cache_file); unlink(context->meta_file); return status; } + + if (switch_test_flag(&context->fh, SWITCH_FILE_FLAG_VIDEO)) { + switch_set_flag(handle, SWITCH_FILE_FLAG_VIDEO); + } else { + switch_set_flag(handle, SWITCH_FILE_FLAG_VIDEO); + } } handle->private_info = context; @@ -3057,6 +3063,20 @@ static switch_status_t http_file_file_close(switch_file_handle_t *handle) } +static switch_status_t http_file_read_video(switch_file_handle_t *handle, switch_frame_t *frame, switch_video_read_flag_t flags) +{ + http_file_context_t *context = handle->private_info; + + return switch_core_file_read_video(&context->fh, frame, flags); +} + +static switch_status_t http_file_write_video(switch_file_handle_t *handle, switch_frame_t *frame) +{ + http_file_context_t *context = handle->private_info; + + return switch_core_file_write_video(&context->fh, frame); +} + static switch_status_t http_file_write(switch_file_handle_t *handle, void *data, size_t *len) { http_file_context_t *context = handle->private_info; @@ -3121,6 +3141,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_httapi_load) http_file_interface->file_read = http_file_file_read; http_file_interface->file_write = http_file_write; http_file_interface->file_seek = http_file_file_seek; + http_file_interface->file_read_video = http_file_read_video; + http_file_interface->file_write_video = http_file_write_video; https_file_supported_formats[0] = "https"; @@ -3132,6 +3154,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_httapi_load) https_file_interface->file_read = http_file_file_read; https_file_interface->file_write = http_file_write; https_file_interface->file_seek = http_file_file_seek; + https_file_interface->file_read_video = http_file_read_video; + https_file_interface->file_write_video = http_file_write_video; switch_snprintf(globals.cache_path, sizeof(globals.cache_path), "%s%shttp_file_cache", SWITCH_GLOBAL_dirs.storage_dir, SWITCH_PATH_SEPARATOR); switch_dir_make_recursive(globals.cache_path, SWITCH_DEFAULT_DIR_PERMS, pool); From 5c9f98b0163986ca1b45d352d4508fa15cfeb5bb Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 24 Jun 2016 16:45:29 -0500 Subject: [PATCH 017/128] FS-9297: [mod_sofia] fix multiple crashes from passing invalid null values in sofia.conf --- src/mod/endpoints/mod_sofia/sofia.c | 186 ++++++++++++++-------------- 1 file changed, 92 insertions(+), 94 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 4addb1dedc..811a45d753 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -4364,17 +4364,15 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s [%s]\n", var, val); - if (!strcasecmp(var, "debug")) { + if (!strcasecmp(var, "debug") && val) { profile->debug = atoi(val); } else if (!strcasecmp(var, "parse-invite-tel-params")) { profile->parse_invite_tel_params = switch_true(val); - } else if (!strcasecmp(var, "keepalive-method")) { - if (!zstr(val)) { - if (!strcasecmp(val, "info")) { - profile->keepalive = KA_INFO; - } else { - profile->keepalive = KA_MESSAGE; - } + } else if (!strcasecmp(var, "keepalive-method") && !zstr(val)) { + if (!strcasecmp(val, "info")) { + profile->keepalive = KA_INFO; + } else { + profile->keepalive = KA_MESSAGE; } } else if (!strcasecmp(var, "bind-attempts") && val) { int ba = atoi(val) - 1; @@ -4455,17 +4453,17 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { profile->mndlb &= ~SM_NDLB_NEVER_PATCH_REINVITE; } - } else if (!strcasecmp(var, "registration-thread-frequency")) { + } else if (!strcasecmp(var, "registration-thread-frequency") && !zstr(val)) { profile->ireg_seconds = atoi(val); if (profile->ireg_seconds < 0) { profile->ireg_seconds = IREG_SECONDS; } - } else if (!strcasecmp(var, "ping-mean-interval")) { + } else if (!strcasecmp(var, "ping-mean-interval") && !zstr(val)) { profile->iping_seconds = atoi(val); if (profile->iping_seconds < 0) { profile->iping_seconds = IPING_SECONDS; } - } else if (!strcasecmp(var, "ping-thread-frequency")) { + } else if (!strcasecmp(var, "ping-thread-frequency") && !zstr(val)) { profile->iping_freq = atoi(val); if (profile->iping_freq < 0) { profile->iping_freq = IPING_FREQUENCY; @@ -4540,7 +4538,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_LIBERAL_DTMF); } - } else if (!strcasecmp(var, "rtp-digit-delay")) { + } else if (!strcasecmp(var, "rtp-digit-delay") && !zstr(val)) { int delay = atoi(val); if (delay < 0) { delay = 0; @@ -4548,11 +4546,10 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->rtp_digit_delay = (uint32_t) delay; } else if (!strcasecmp(var, "watchdog-enabled")) { profile->watchdog_enabled = switch_true(val); - } else if (!strcasecmp(var, "watchdog-step-timeout")) { + } else if (!strcasecmp(var, "watchdog-step-timeout") && !zstr(val)) { profile->step_timeout = atoi(val); - } else if (!strcasecmp(var, "watchdog-event-timeout")) { + } else if (!strcasecmp(var, "watchdog-event-timeout") && !zstr(val)) { profile->event_timeout = atoi(val); - } else if (!strcasecmp(var, "in-dialog-chat")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_IN_DIALOG_CHAT); @@ -4608,9 +4605,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) sofia_clear_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER); } } else if (!strcasecmp(var, "send-presence-on-register")) { - if (switch_true(val) || !strcasecmp(val, "all")) { + if (val && (switch_true(val) || !strcasecmp(val, "all"))) { sofia_set_pflag(profile, PFLAG_PRESENCE_ON_REGISTER); - } else if (!strcasecmp(val, "first-only")) { + } else if (val && !strcasecmp(val, "first-only")) { sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER); sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER); } else { @@ -4623,22 +4620,21 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_CID_IN_1XX); } - } else if (!strcasecmp(var, "disable-hold")) { if (switch_true(val)) { sofia_set_media_flag(profile, SCMF_DISABLE_HOLD); } else { sofia_clear_media_flag(profile, SCMF_DISABLE_HOLD); } - } else if (!strcasecmp(var, "auto-jitterbuffer-msec")) { + } else if (!strcasecmp(var, "auto-jitterbuffer-msec") && !zstr(val)) { int msec = atoi(val); if (msec > 19) { profile->jb_msec = switch_core_strdup(profile->pool, val); } } else if (!strcasecmp(var, "dtmf-type")) { - if (!strcasecmp(val, "rfc2833")) { + if (val && !strcasecmp(val, "rfc2833")) { profile->dtmf_type = DTMF_2833; - } else if (!strcasecmp(val, "info")) { + } else if (val && !strcasecmp(val, "info")) { profile->dtmf_type = DTMF_INFO; } else { profile->dtmf_type = DTMF_NONE; @@ -4711,12 +4707,12 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { sofia_clear_flag(profile, TFLAG_ZRTP_PASSTHRU); } - } else if (!strcasecmp(var, "force-subscription-expires")) { + } else if (!strcasecmp(var, "force-subscription-expires") && !zstr(val)) { int tmp = atoi(val); if (tmp > 0) { profile->force_subscription_expires = tmp; } - } else if (!strcasecmp(var, "force-publish-expires")) { + } else if (!strcasecmp(var, "force-publish-expires") && !zstr(val)) { int tmp = atoi(val); if (tmp > 0) { profile->force_publish_expires = tmp; @@ -4724,7 +4720,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else if (!strcasecmp(var, "send-message-query-on-register")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER); - } else if (!strcasecmp(val, "first-only")) { + } else if (val && !strcasecmp(val, "first-only")) { sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER); sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER); } else { @@ -4779,20 +4775,20 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } } else if (!strcasecmp(var, "user-agent-filter")) { profile->user_agent_filter = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "max-registrations-per-extension")) { + } else if (!strcasecmp(var, "max-registrations-per-extension") && !zstr(val)) { profile->max_registrations_perext = atoi(val); - } else if (!strcasecmp(var, "rfc2833-pt")) { + } else if (!strcasecmp(var, "rfc2833-pt") && !zstr(val)) { profile->te = (switch_payload_t) atoi(val); - } else if (!strcasecmp(var, "cng-pt") && !sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG)) { + } else if (!strcasecmp(var, "cng-pt") && !sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG) && !zstr(val)) { profile->cng_pt = (switch_payload_t) atoi(val); - } else if (!strcasecmp(var, "sip-port")) { + } else if (!strcasecmp(var, "sip-port") && !zstr(val)) { if (!strcasecmp(val, "auto")) { sofia_set_pflag(profile, PFLAG_AUTO_ASSIGN_PORT); } else { profile->sip_port = (switch_port_t) atoi(val); if (!profile->extsipport) profile->extsipport = profile->sip_port; } - } else if (!strcasecmp(var, "vad")) { + } else if (!strcasecmp(var, "vad") && !zstr(val)) { if (!strcasecmp(val, "in")) { profile->vflags |= VAD_IN; } else if (!strcasecmp(val, "out")) { @@ -4829,7 +4825,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid ext-rtp-ip\n"); } - } else if (!strcasecmp(var, "rtp-ip")) { + } else if (!strcasecmp(var, "rtp-ip") && val) { char *ip = mod_sofia_globals.guess_ip; char buf[64]; @@ -4864,7 +4860,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Max IPs configured for profile %s.\n", profile->name); } } - } else if (!strcasecmp(var, "sip-ip")) { + } else if (!strcasecmp(var, "sip-ip") && val) { char *ip = mod_sofia_globals.guess_ip; char buf[64]; @@ -4922,7 +4918,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid ext-sip-ip\n"); } } else if (!strcasecmp(var, "local-network-acl")) { - if (!strcasecmp(var, "none")) { + if (val && !strcasecmp(val, "none")) { profile->local_network = NULL; } else { profile->local_network = switch_core_strdup(profile->pool, val); @@ -4941,7 +4937,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->timer_name = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "hold-music")) { profile->hold_music = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "outbound-proxy")) { + } else if (!strcasecmp(var, "outbound-proxy") && val) { if (strncasecmp(val, "sip:", 4) && strncasecmp(val, "sips:", 5)) { profile->outbound_proxy = switch_core_sprintf(profile->pool, "sip:%s", val); } else { @@ -4951,22 +4947,22 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->rtcp_audio_interval_msec = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "rtcp-video-interval-msec")) { profile->rtcp_video_interval_msec = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "session-timeout")) { + } else if (!strcasecmp(var, "session-timeout") && !zstr(val)) { int v_session_timeout = atoi(val); if (v_session_timeout >= 0) { profile->session_timeout = v_session_timeout; } - } else if (!strcasecmp(var, "max-proceeding")) { + } else if (!strcasecmp(var, "max-proceeding") && !zstr(val)) { int v_max_proceeding = atoi(val); if (v_max_proceeding >= 0) { profile->max_proceeding = v_max_proceeding; } - } else if (!strcasecmp(var, "rtp-timeout-sec")) { + } else if (!strcasecmp(var, "rtp-timeout-sec") && !zstr(val)) { int v = atoi(val); if (v >= 0) { profile->rtp_timeout_sec = v; } - } else if (!strcasecmp(var, "rtp-hold-timeout-sec")) { + } else if (!strcasecmp(var, "rtp-hold-timeout-sec") && !zstr(val)) { int v = atoi(val); if (v >= 0) { profile->rtp_hold_timeout_sec = v; @@ -4983,7 +4979,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { profile->mflags |= MFLAG_REGISTER; } - } else if (!strcasecmp(var, "media-option")) { + } else if (!strcasecmp(var, "media-option") && !zstr(val)) { if (!strcasecmp(val, "resume-media-on-hold")) { profile->media_options |= MEDIA_OPT_MEDIA_ON_HOLD; } else if (!strcasecmp(val, "bypass-media-after-att-xfer")) { @@ -5001,10 +4997,10 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else if (!strcasecmp(var, "pnp-provision-url")) { profile->pnp_prov_url = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "manage-presence")) { - if (!strcasecmp(val, "passive")) { + if (val && !strcasecmp(val, "passive")) { profile->pres_type = PRES_TYPE_PASSIVE; - } else if (!strcasecmp(val, "pnp")) { + } else if (val && !strcasecmp(val, "pnp")) { profile->pres_type = PRES_TYPE_PNP; } else if (switch_true(val)) { profile->pres_type = PRES_TYPE_FULL; @@ -5012,9 +5008,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->pres_type = 0; } } else if (!strcasecmp(var, "presence-hold-state")) { - if (!strcasecmp(val, "confirmed")) { + if (val && !strcasecmp(val, "confirmed")) { profile->pres_held_type = PRES_HELD_CONFIRMED; - } else if (!strcasecmp(val, "terminated")) { + } else if (val && !strcasecmp(val, "terminated")) { profile->pres_held_type = PRES_HELD_TERMINATED; } else { profile->pres_held_type = 0; @@ -5031,7 +5027,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->pres_type = PRES_TYPE_FULL; sofia_set_pflag(profile, PFLAG_MULTIREG); - } else if (!strcasecmp(val, "sylantro")) { + } else if (val && !strcasecmp(val, "sylantro")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Sylantro support has been removed.\n" "It was incomplete anyway, and we fully support the broadsoft SCA shared line spec."); @@ -5063,9 +5059,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL); } - } else if (!strcasecmp(var, "sip-user-ping-max")) { + } else if (!strcasecmp(var, "sip-user-ping-max") && !zstr(val)) { profile->sip_user_ping_max = atoi(val); - } else if (!strcasecmp(var, "sip-user-ping-min")) { + } else if (!strcasecmp(var, "sip-user-ping-min") && !zstr(val)) { profile->sip_user_ping_min = atoi(val); } else if (!strcasecmp(var, "require-secure-rtp")) { if (switch_true(val)) { @@ -5079,9 +5075,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) if (found) continue; if (!strcasecmp(var, "multiple-registrations")) { - if (!strcasecmp(val, "call-id")) { + if (val && !strcasecmp(val, "call-id")) { sofia_set_pflag(profile, PFLAG_MULTIREG); - } else if (!strcasecmp(val, "contact") || switch_true(val)) { + } else if (val && (!strcasecmp(val, "contact") || switch_true(val))) { sofia_set_pflag(profile, PFLAG_MULTIREG); sofia_set_pflag(profile, PFLAG_MULTIREG_CONTACT); } else if (!switch_true(val)) { @@ -5146,7 +5142,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else if (!strcasecmp(var, "contact-user")) { profile->contact_user = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "nat-options-ping")) { - if (!strcasecmp(val, "udp-only")) { + if (val && !strcasecmp(val, "udp-only")) { sofia_set_pflag(profile, PFLAG_UDP_NAT_OPTIONS_PING); } else if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_NAT_OPTIONS_PING); @@ -5161,9 +5157,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) sofia_clear_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING); } } else if (!strcasecmp(var, "inbound-codec-negotiation")) { - if (!strcasecmp(val, "greedy")) { + if (val && !strcasecmp(val, "greedy")) { sofia_set_media_flag(profile, SCMF_CODEC_GREEDY); - } else if (!strcasecmp(val, "scrooge")) { + } else if (val && !strcasecmp(val, "scrooge")) { sofia_set_media_flag(profile, SCMF_CODEC_GREEDY); sofia_set_media_flag(profile, SCMF_CODEC_SCROOGE); } else { @@ -5206,9 +5202,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_EXTENDED_INFO_PARSING); } - } else if (!strcasecmp(var, "nonce-ttl")) { + } else if (!strcasecmp(var, "nonce-ttl") && !zstr(val)) { profile->nonce_ttl = atoi(val); - } else if (!strcasecmp(var, "max-auth-validity")) { + } else if (!strcasecmp(var, "max-auth-validity") && !zstr(val)) { profile->max_auth_validity = atoi(val); } else if (!strcasecmp(var, "accept-blind-reg")) { if (switch_true(val)) { @@ -5264,7 +5260,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_ENABLE_RFC5626); } - } else if (!strcasecmp(var, "minimum-session-expires")) { + } else if (!strcasecmp(var, "minimum-session-expires") && !zstr(val)) { profile->minimum_session_expires = atoi(val); /* per RFC 4028: minimum_session_expires must be > 90 */ if (profile->minimum_session_expires < 90) { @@ -5301,7 +5297,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) sofia_clear_pflag(profile, PFLAG_PARSE_ALL_INVITE_HEADERS); } } else if (!strcasecmp(var, "bitpacking")) { - if (!strcasecmp(val, "aal2")) { + if (val && !strcasecmp(val, "aal2")) { profile->codec_flags = SWITCH_CODEC_FLAG_AAL2; } else { profile->codec_flags = 0; @@ -5310,7 +5306,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->sdp_username = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "context")) { profile->context = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "apply-nat-acl")) { + } else if (!strcasecmp(var, "apply-nat-acl") && !zstr(val)) { if (!strcasecmp(val,"none")) { profile->nat_acl_count = 0; } else if (profile->nat_acl_count < SOFIA_MAX_ACL) { @@ -5322,7 +5318,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL); } - } else if (!strcasecmp(var, "apply-inbound-acl")) { + } else if (!strcasecmp(var, "apply-inbound-acl") && !zstr(val)) { if (!strcasecmp(val,"none")) { profile->acl_count = 0; } else if (profile->acl_count < SOFIA_MAX_ACL) { @@ -5348,7 +5344,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL); } - } else if (!strcasecmp(var, "apply-proxy-acl")) { + } else if (!strcasecmp(var, "apply-proxy-acl") && !zstr(val)) { if (!strcasecmp(val,"none")) { profile->proxy_acl_count = 0; } else if (profile->proxy_acl_count < SOFIA_MAX_ACL) { @@ -5356,7 +5352,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL); } - } else if (!strcasecmp(var, "apply-register-acl")) { + } else if (!strcasecmp(var, "apply-register-acl") && !zstr(val)) { if (!strcasecmp(val,"none")) { profile->reg_acl_count = 0; } else if (profile->reg_acl_count < SOFIA_MAX_ACL) { @@ -5365,7 +5361,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL); } - } else if (!strcasecmp(var, "apply-candidate-acl")) { + } else if (!strcasecmp(var, "apply-candidate-acl") && !zstr(val)) { if (!strcasecmp(val,"none")) { profile->cand_acl_count = 0; } else if (profile->cand_acl_count < SWITCH_MAX_CAND_ACL) { @@ -5387,7 +5383,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } } else if (!strcasecmp(var, "dialplan")) { profile->dialplan = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "max-calls")) { + } else if (!strcasecmp(var, "max-calls") && !zstr(val)) { profile->max_calls = atoi(val); } else if (!strcasecmp(var, "codec-prefs")) { profile->inbound_codec_string = switch_core_strdup(profile->pool, val); @@ -5398,7 +5394,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->outbound_codec_string = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "challenge-realm")) { profile->challenge_realm = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "dtmf-duration")) { + } else if (!strcasecmp(var, "dtmf-duration") && !zstr(val)) { uint32_t dur = atoi(val); if (dur >= switch_core_min_dtmf_duration(0) && dur <= switch_core_max_dtmf_duration(0)) { profile->dtmf_duration = dur; @@ -5451,7 +5447,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) sofia_clear_pflag(profile, PFLAG_TLS); } } else if (!strcasecmp(var, "tls-bind-params")) { - if (switch_stristr("transport=tls", val)) { + if (val && switch_stristr("transport=tls", val)) { profile->tls_bind_params = switch_core_strdup(profile->pool, val); } else { profile->tls_bind_params = switch_core_sprintf(profile->pool, "%s;transport=tls", val); @@ -5460,11 +5456,11 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->tls_only = switch_true(val); } else if (!strcasecmp(var, "tls-verify-date")) { profile->tls_verify_date = switch_true(val); - } else if (!strcasecmp(var, "tls-verify-depth")) { + } else if (!strcasecmp(var, "tls-verify-depth") && !zstr(val)) { profile->tls_verify_depth = atoi(val); } else if (!strcasecmp(var, "tls-verify-policy")) { profile->tls_verify_policy = sofia_glue_str2tls_verify_policy(val); - } else if (!strcasecmp(var, "tls-sip-port")) { + } else if (!strcasecmp(var, "tls-sip-port") && !zstr(val)) { if (!strcasecmp(val, "auto")) { sofia_set_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT); } else { @@ -5501,79 +5497,79 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_2; ps=pe+1; } - } else if (!strcasecmp(var, "tls-timeout")) { + } else if (!strcasecmp(var, "tls-timeout") && !zstr(val)) { int v = atoi(val); profile->tls_timeout = v > 0 ? (unsigned int)v : 300; - } else if (!strcasecmp(var, "timer-T1")) { + } else if (!strcasecmp(var, "timer-T1") && !zstr(val)) { int v = atoi(val); if (v > 0) { profile->timer_t1 = v; } else { profile->timer_t1 = 500; } - } else if (!strcasecmp(var, "timer-T1X64")) { + } else if (!strcasecmp(var, "timer-T1X64") && !zstr(val)) { int v = atoi(val); if (v > 0) { profile->timer_t1x64 = v; } else { profile->timer_t1x64 = 32000; } - } else if (!strcasecmp(var, "timer-T2")) { + } else if (!strcasecmp(var, "timer-T2") && !zstr(val)) { int v = atoi(val); if (v > 0) { profile->timer_t2 = v; } else { profile->timer_t2 = 4000; } - } else if (!strcasecmp(var, "timer-T4")) { + } else if (!strcasecmp(var, "timer-T4") && !zstr(val)) { int v = atoi(val); if (v > 0) { profile->timer_t4 = v; } else { profile->timer_t4 = 4000; } - } else if (!strcasecmp(var, "sip-options-respond-503-on-busy")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY); - } else { - sofia_clear_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY); - } - } else if (!strcasecmp(var, "sip-expires-late-margin")) { + } else if (!strcasecmp(var, "sip-options-respond-503-on-busy")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY); + } else { + sofia_clear_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY); + } + } else if (!strcasecmp(var, "sip-expires-late-margin") && !zstr(val)) { int32_t sip_expires_late_margin = atoi(val); if (sip_expires_late_margin >= 0) { profile->sip_expires_late_margin = sip_expires_late_margin; } else { profile->sip_expires_late_margin = 60; } - } else if (!strcasecmp(var, "sip-force-expires-min")) { + } else if (!strcasecmp(var, "sip-force-expires-min") && !zstr(val)) { int32_t sip_force_expires_min = atoi(val); if (sip_force_expires_min >= 0) { profile->sip_force_expires_min = sip_force_expires_min; } else { profile->sip_force_expires_min = 0; } - } else if (!strcasecmp(var, "sip-force-expires-max")) { + } else if (!strcasecmp(var, "sip-force-expires-max") && !zstr(val)) { int32_t sip_force_expires_max = atoi(val); if (sip_force_expires_max >= 0) { profile->sip_force_expires_max = sip_force_expires_max; } else { profile->sip_force_expires_max = 0; } - } else if (!strcasecmp(var, "sip-force-expires")) { + } else if (!strcasecmp(var, "sip-force-expires") && !zstr(val)) { int32_t sip_force_expires = atoi(val); if (sip_force_expires >= 0) { profile->sip_force_expires = sip_force_expires; } else { profile->sip_force_expires = 0; } - } else if (!strcasecmp(var, "sip-expires-max-deviation")) { + } else if (!strcasecmp(var, "sip-expires-max-deviation") && !zstr(val)) { int32_t sip_expires_max_deviation = atoi(val); if (sip_expires_max_deviation >= 0) { profile->sip_expires_max_deviation = sip_expires_max_deviation; } else { profile->sip_expires_max_deviation = 0; } - } else if (!strcasecmp(var, "sip-subscription-max-deviation")) { + } else if (!strcasecmp(var, "sip-subscription-max-deviation") && !zstr(val)) { int32_t sip_subscription_max_deviation = atoi(val); if (sip_subscription_max_deviation >= 0) { profile->sip_subscription_max_deviation = sip_subscription_max_deviation; @@ -5588,7 +5584,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) sofia_clear_pflag(profile, PFLAG_NO_CONNECTION_REUSE); } } else if (!strcasecmp(var, "p-asserted-id-parse")) { - if (!strncasecmp(val, "default", 7)) { + if (!val) { + profile->paid_type = PAID_DEFAULT; + } else if (!strncasecmp(val, "default", 7)) { profile->paid_type = PAID_DEFAULT; } else if (!strncasecmp(val, "user-only", 9)) { profile->paid_type = PAID_USER; @@ -5611,18 +5609,18 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS); } - } else if (!strcasecmp(var, "enforce-blind-auth-result")) { - if(switch_true(val)) { - sofia_set_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT); - } else { - sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT); - } - } else if (!strcasecmp(var, "proxy-hold")) { - if(switch_true(val)) { - sofia_set_pflag(profile, PFLAG_PROXY_HOLD); - } else { - sofia_clear_pflag(profile, PFLAG_PROXY_HOLD); - } + } else if (!strcasecmp(var, "enforce-blind-auth-result")) { + if(switch_true(val)) { + sofia_set_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT); + } else { + sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT); + } + } else if (!strcasecmp(var, "proxy-hold")) { + if(switch_true(val)) { + sofia_set_pflag(profile, PFLAG_PROXY_HOLD); + } else { + sofia_clear_pflag(profile, PFLAG_PROXY_HOLD); + } } } From 79f5fbcbc0c2ec326679fed4742eebe6400e0c51 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 27 Jun 2016 09:14:09 -0500 Subject: [PATCH 018/128] fix typo in conference config --- conf/vanilla/autoload_configs/conference.conf.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/vanilla/autoload_configs/conference.conf.xml b/conf/vanilla/autoload_configs/conference.conf.xml index d289bb5712..2df467b6d7 100644 --- a/conf/vanilla/autoload_configs/conference.conf.xml +++ b/conf/vanilla/autoload_configs/conference.conf.xml @@ -238,7 +238,7 @@ - + From 21bfc317f118d1f7641d90a42dbb97446a08f6ef Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 27 Jun 2016 15:56:47 -0500 Subject: [PATCH 019/128] FS-9301: [mod_sofia] handle race condition on startup of mod_sofia in error conditons causing segfault --- src/mod/endpoints/mod_sofia/mod_sofia.c | 242 +++++++++++++----------- 1 file changed, 130 insertions(+), 112 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 5dfbfe87c8..6a41f87062 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -50,6 +50,7 @@ switch_endpoint_interface_t *sofia_endpoint_interface; #define STRLEN 15 +void mod_sofia_shutdown_cleanup(); static switch_status_t sofia_on_init(switch_core_session_t *session); static switch_status_t sofia_on_exchange_media(switch_core_session_t *session); @@ -5758,109 +5759,112 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) switch_management_interface_t *management_interface; switch_application_interface_t *app_interface; struct in_addr in; + switch_status_t status; - - if (switch_event_reserve_subclass(MY_EVENT_NOTIFY_REFER) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_NOTIFY_REFER); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_NOTIFY_WATCHED_HEADER) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_NOTIFY_WATCHED_HEADER); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_UNREGISTER) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_UNREGISTER); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_PROFILE_START) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_PROFILE_START); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_REINVITE) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REINVITE); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_REPLACED) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REPLACED); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_TRANSFEROR) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_TRANSFEROR); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_TRANSFEREE) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_TRANSFEREE); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_ERROR) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_ERROR); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_INTERCEPTED) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_INTERCEPTED); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_STATE) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_STATE); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_SIP_USER_STATE) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_SIP_USER_STATE); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_DEL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_DEL); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_EXPIRE) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_EXPIRE); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_REGISTER_ATTEMPT) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER_ATTEMPT); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_REGISTER_FAILURE) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER_FAILURE); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_PRE_REGISTER) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_PRE_REGISTER); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_REGISTER) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER); - return SWITCH_STATUS_TERM; - } - - if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_ADD) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_ADD); - return SWITCH_STATUS_TERM; - } - memset(&mod_sofia_globals, 0, sizeof(mod_sofia_globals)); mod_sofia_globals.destroy_private.destroy_nh = 1; mod_sofia_globals.destroy_private.is_static = 1; mod_sofia_globals.keep_private.is_static = 1; mod_sofia_globals.pool = pool; switch_mutex_init(&mod_sofia_globals.mutex, SWITCH_MUTEX_NESTED, mod_sofia_globals.pool); + switch_core_hash_init(&mod_sofia_globals.profile_hash); + switch_core_hash_init(&mod_sofia_globals.gateway_hash); + switch_mutex_init(&mod_sofia_globals.hash_mutex, SWITCH_MUTEX_NESTED, mod_sofia_globals.pool); + + if (switch_event_reserve_subclass(MY_EVENT_NOTIFY_REFER) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_NOTIFY_REFER); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_NOTIFY_WATCHED_HEADER) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_NOTIFY_WATCHED_HEADER); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_UNREGISTER) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_UNREGISTER); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_PROFILE_START) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_PROFILE_START); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_REINVITE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REINVITE); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_REPLACED) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REPLACED); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_TRANSFEROR) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_TRANSFEROR); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_TRANSFEREE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_TRANSFEREE); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_ERROR) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_ERROR); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_INTERCEPTED) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_INTERCEPTED); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_STATE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_STATE); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_SIP_USER_STATE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_SIP_USER_STATE); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_DEL) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_DEL); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_EXPIRE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_EXPIRE); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_REGISTER_ATTEMPT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER_ATTEMPT); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_REGISTER_FAILURE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER_FAILURE); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_PRE_REGISTER) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_PRE_REGISTER); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_REGISTER) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER); + switch_goto_status(SWITCH_STATUS_TERM, err); + } + + if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_ADD) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_ADD); + switch_goto_status(SWITCH_STATUS_TERM, err); + } switch_find_local_ip(mod_sofia_globals.guess_ip, sizeof(mod_sofia_globals.guess_ip), &mod_sofia_globals.guess_mask, AF_INET); in.s_addr = mod_sofia_globals.guess_mask; @@ -5868,11 +5872,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) strcpy(mod_sofia_globals.hostname, switch_core_get_switchname()); - - switch_core_hash_init(&mod_sofia_globals.profile_hash); - switch_core_hash_init(&mod_sofia_globals.gateway_hash); - switch_mutex_init(&mod_sofia_globals.hash_mutex, SWITCH_MUTEX_NESTED, mod_sofia_globals.pool); - switch_mutex_lock(mod_sofia_globals.mutex); mod_sofia_globals.running = 1; switch_mutex_unlock(mod_sofia_globals.mutex); @@ -5896,83 +5895,95 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) /* start one message thread */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Starting initial message thread.\n"); - sofia_msg_thread_start(0); if (sofia_init() != SWITCH_STATUS_SUCCESS) { + switch_goto_status(SWITCH_STATUS_GENERR, err); return SWITCH_STATUS_GENERR; } if (config_sofia(SOFIA_CONFIG_LOAD, NULL) != SWITCH_STATUS_SUCCESS) { mod_sofia_globals.running = 0; + switch_goto_status(SWITCH_STATUS_GENERR, err); return SWITCH_STATUS_GENERR; } + sofia_msg_thread_start(0); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for profiles to start\n"); switch_yield(1500000); if (switch_event_bind(modname, SWITCH_EVENT_CUSTOM, MULTICAST_EVENT, event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); - return SWITCH_STATUS_TERM; + switch_goto_status(SWITCH_STATUS_TERM, err); } if (switch_event_bind(modname, SWITCH_EVENT_CONFERENCE_DATA, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); + switch_goto_status(SWITCH_STATUS_GENERR, err); return SWITCH_STATUS_GENERR; } if (switch_event_bind(modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); + switch_goto_status(SWITCH_STATUS_GENERR, err); return SWITCH_STATUS_GENERR; } if (switch_event_bind(modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); + switch_goto_status(SWITCH_STATUS_GENERR, err); return SWITCH_STATUS_GENERR; } if (switch_event_bind(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); + switch_goto_status(SWITCH_STATUS_GENERR, err); return SWITCH_STATUS_GENERR; } if (switch_event_bind(modname, SWITCH_EVENT_ROSTER, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); + switch_goto_status(SWITCH_STATUS_GENERR, err); return SWITCH_STATUS_GENERR; } if (switch_event_bind(modname, SWITCH_EVENT_MESSAGE_WAITING, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); + switch_goto_status(SWITCH_STATUS_GENERR, err); return SWITCH_STATUS_GENERR; } if (switch_event_bind(modname, SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); + switch_goto_status(SWITCH_STATUS_GENERR, err); return SWITCH_STATUS_GENERR; } if (switch_event_bind(modname, SWITCH_EVENT_NOTIFY, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); + switch_goto_status(SWITCH_STATUS_GENERR, err); return SWITCH_STATUS_GENERR; } if (switch_event_bind(modname, SWITCH_EVENT_PHONE_FEATURE, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); + switch_goto_status(SWITCH_STATUS_GENERR, err); return SWITCH_STATUS_GENERR; } if (switch_event_bind(modname, SWITCH_EVENT_SEND_MESSAGE, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); + switch_goto_status(SWITCH_STATUS_GENERR, err); return SWITCH_STATUS_GENERR; } if (switch_event_bind(modname, SWITCH_EVENT_SEND_INFO, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); + switch_goto_status(SWITCH_STATUS_GENERR, err); return SWITCH_STATUS_GENERR; } @@ -6035,10 +6046,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; + + err: + + mod_sofia_shutdown_cleanup(); + return status; } -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown) -{ +void mod_sofia_shutdown_cleanup() { int sanity = 0; int i; switch_status_t st; @@ -6077,8 +6092,10 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown) switch_event_unbind_callback(general_queue_event_handler); switch_event_unbind_callback(event_handler); - switch_queue_push(mod_sofia_globals.presence_queue, NULL); - switch_queue_interrupt_all(mod_sofia_globals.presence_queue); + if (mod_sofia_globals.presence_queue) { + switch_queue_push(mod_sofia_globals.presence_queue, NULL); + switch_queue_interrupt_all(mod_sofia_globals.presence_queue); + } while (mod_sofia_globals.threads) { switch_cond_next(); @@ -6087,13 +6104,11 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown) } } - for (i = 0; mod_sofia_globals.msg_queue_thread[i]; i++) { switch_queue_push(mod_sofia_globals.msg_queue, NULL); switch_queue_interrupt_all(mod_sofia_globals.msg_queue); } - for (i = 0; mod_sofia_globals.msg_queue_thread[i]; i++) { switch_thread_join(&st, mod_sofia_globals.msg_queue_thread[i]); } @@ -6102,14 +6117,17 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown) switch_thread_join(&st, mod_sofia_globals.presence_thread); } - //switch_yield(1000000); su_deinit(); switch_mutex_lock(mod_sofia_globals.hash_mutex); switch_core_hash_destroy(&mod_sofia_globals.profile_hash); switch_core_hash_destroy(&mod_sofia_globals.gateway_hash); switch_mutex_unlock(mod_sofia_globals.hash_mutex); +} +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown) +{ + mod_sofia_shutdown_cleanup(); return SWITCH_STATUS_SUCCESS; } From 4f2c4124d150bb4de50d21fa468c2d1417984d67 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Mon, 27 Jun 2016 17:23:40 -0400 Subject: [PATCH 020/128] FS-9302 [mod_mongo] mongo_find_one and mongo_find_n corrected to return -ERR when connection to database fails. --- src/mod/applications/mod_mongo/mod_mongo.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/mod/applications/mod_mongo/mod_mongo.c b/src/mod/applications/mod_mongo/mod_mongo.c index a614d1f79a..aac3221fe7 100644 --- a/src/mod/applications/mod_mongo/mod_mongo.c +++ b/src/mod/applications/mod_mongo/mod_mongo.c @@ -251,23 +251,30 @@ SWITCH_STANDARD_API(mod_mongo_find_n_function) mongoc_cursor_t *cursor = mongoc_collection_find(col, query_options, 0, n, 0, query, fields, NULL); if (cursor && !mongoc_cursor_error(cursor, &error)) { /* get results from cursor */ + switch_stream_handle_t result_stream = { 0 }; const bson_t *result; - stream->write_function(stream, "-OK\n["); + SWITCH_STANDARD_STREAM(result_stream); + if (mongoc_cursor_more(cursor) && mongoc_cursor_next(cursor, &result)) { char *json_result; json_result = bson_as_json(result, NULL); - stream->write_function(stream, "%s", json_result); + result_stream.write_function(&result_stream, "%s", json_result); bson_free(json_result); } while (mongoc_cursor_more(cursor) && mongoc_cursor_next(cursor, &result)) { char *json_result; json_result = bson_as_json(result, NULL); - stream->write_function(stream, ",%s", json_result); + result_stream.write_function(&result_stream, ",%s", json_result); bson_free(json_result); } - stream->write_function(stream, "]\n"); + if (!mongoc_cursor_error(cursor, &error)) { + stream->write_function(stream, "-OK\n[%s]", zstr((char *)result_stream.data) ? "" :(char *)result_stream.data); + } else { + stream->write_function(stream, "-ERR\nquery failed: %s", error.message); + } + switch_safe_free(result_stream.data); } else { - stream->write_function(stream, "-ERR\nquery failed!\n"); + stream->write_function(stream, "-ERR\nquery failed: %s", error.message); } if (cursor) { mongoc_cursor_destroy(cursor); @@ -342,6 +349,8 @@ SWITCH_STANDARD_API(mod_mongo_find_one_function) json_result = bson_as_json(result, NULL); stream->write_function(stream, "-OK\n%s\n", json_result); bson_free(json_result); + } else if (mongoc_cursor_error(cursor, &error)) { + stream->write_function(stream, "-ERR\nquery failed: %s\n", error.message); } else { /* empty set */ stream->write_function(stream, "-OK\n{}\n"); From bf34d0346966860a1b96fa852de6ef415b39ee19 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 10 Jun 2016 16:27:31 -0500 Subject: [PATCH 021/128] FS-9221 Add inactive support --- .../mod_conference/conference_video.c | 48 ++++++++++++------- src/switch_core_media.c | 29 +++++++---- 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 1e5d1cc10d..7fccb51fa6 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -926,7 +926,7 @@ switch_status_t conference_video_attach_video_layer(conference_member_t *member, return SWITCH_STATUS_FALSE; } - if (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY && !member->avatar_png_img) { + if ((switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) && !member->avatar_png_img) { return SWITCH_STATUS_FALSE; } @@ -1317,7 +1317,7 @@ void conference_video_write_canvas_image_to_codec_group(conference_obj_t *confer switch_core_session_request_video_refresh(imember->session); } - if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY) { + if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { switch_core_session_rwunlock(imember->session); continue; } @@ -1643,7 +1643,10 @@ void conference_video_check_avatar(conference_member_t *member, switch_bool_t fo canvas = conference_video_get_canvas_locked(member); if (conference_utils_test_flag(member->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS) && - (!switch_channel_test_flag(member->channel, CF_VIDEO_READY) || switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY)) { + (!switch_channel_test_flag(member->channel, CF_VIDEO_READY) || + (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || + switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE))) { + if (canvas) { conference_video_release_canvas(&canvas); } @@ -1656,7 +1659,8 @@ void conference_video_check_avatar(conference_member_t *member, switch_bool_t fo member->avatar_patched = 0; - if (!force && switch_channel_test_flag(member->channel, CF_VIDEO_READY) && switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { + if (!force && switch_channel_test_flag(member->channel, CF_VIDEO_READY) && + switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY && switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_INACTIVE) { conference_utils_member_set_flag_locked(member, MFLAG_ACK_VIDEO); } else { if (member->conference->no_video_avatar) { @@ -1795,7 +1799,8 @@ switch_status_t conference_video_find_layer(conference_obj_t *conference, mcu_ca if (!layer && (canvas->layers_used < canvas->total_layers || (avatar_layers && !member->avatar_png_img) || conference_utils_member_test_flag(member, MFLAG_MOD)) && - (member->avatar_png_img || switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY)) { + (member->avatar_png_img || (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY && + switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_INACTIVE))) { /* find an empty layer */ for (i = 0; i < canvas->total_layers; i++) { mcu_layer_t *xlayer = &canvas->layers[i]; @@ -1868,7 +1873,11 @@ void conference_video_pop_next_image(conference_member_t *member, switch_image_t size = switch_queue_size(member->video_queue); } while(size > 0); - if (conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) && member->video_layer_id > -1 && switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { + if (conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) && + member->video_layer_id > -1 && + switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY && + switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_INACTIVE + ) { if (img) { member->good_img++; if ((member->good_img % (int)(member->conference->video_fps.fps * 10)) == 0) { @@ -2227,7 +2236,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (imember->channel && switch_channel_ready(imember->channel) && switch_channel_test_flag(imember->channel, CF_VIDEO_READY) && !conference_utils_member_test_flag(imember, MFLAG_SECOND_SCREEN) && conference_utils_member_test_flag(imember, MFLAG_RUNNING) && (!no_muted || seen) && (!no_av || (no_av && !imember->avatar_png_img)) - && imember->canvas_id == canvas->canvas_id && imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY) { + && imember->canvas_id == canvas->canvas_id && imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY && imember->video_media_flow != SWITCH_MEDIA_FLOW_INACTIVE) { video_count++; } @@ -2470,7 +2479,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_img_free(&img); } - if (!layer && (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS) || ((switch_channel_test_flag(imember->channel, CF_VIDEO_READY) && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY)))) { + if (!layer && (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS) || ((switch_channel_test_flag(imember->channel, CF_VIDEO_READY) && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_INACTIVE)))) { if (conference_video_find_layer(conference, canvas, imember, &layer) == SWITCH_STATUS_SUCCESS) { imember->layer_timeout = 0; } else { @@ -2492,7 +2501,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr // switch_img_free(&layer->cur_img); //} - if (conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN) || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS)) { + if (conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN) || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE || conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS)) { layer->mute_patched = 0; } else { switch_image_t *tmp; @@ -2613,7 +2622,9 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (total > 0 && (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) || conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN)) && - imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { + imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY && + imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_INACTIVE) { + total--; } @@ -2637,7 +2648,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } } - if (imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { + if (imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_INACTIVE) { conference_video_pop_next_image(imember, &imember->pcanvas_img); } @@ -2683,7 +2694,8 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (!imember->rec && (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) || !imember->canvas || - (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) || + (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || + switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) || (switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS))) { continue; } @@ -2717,7 +2729,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_image_t *use_img = NULL; if (!omember->session || !switch_channel_test_flag(omember->channel, CF_VIDEO_READY) || - switch_core_session_media_flow(omember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) { + switch_core_session_media_flow(omember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(omember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { continue; } @@ -3016,7 +3028,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_core_session_request_video_refresh(imember->session); } - if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY) { + if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { switch_core_session_rwunlock(imember->session); continue; } @@ -3365,7 +3377,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ switch_core_session_request_video_refresh(imember->session); } - if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY) { + if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { switch_core_session_rwunlock(imember->session); continue; } @@ -3450,7 +3462,7 @@ void conference_video_find_floor(conference_member_t *member, switch_bool_t ente continue; } - if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY && !imember->avatar_png_img) { + if ((switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) && !imember->avatar_png_img) { continue; } @@ -3515,7 +3527,7 @@ void conference_video_set_floor_holder(conference_obj_t *conference, conference_ return; } - if (member && switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY && !member->avatar_png_img) { + if (member && (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) && !member->avatar_png_img) { return; } @@ -3740,7 +3752,7 @@ switch_status_t conference_video_thread_callback(switch_core_session_t *session, return SWITCH_STATUS_SUCCESS; } - if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) { + if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 3f5249afb4..ff71e3668e 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3780,7 +3780,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s sdp_media_t *m; sdp_attribute_t *attr; int ptime = 0, dptime = 0, maxptime = 0, dmaxptime = 0; - int sendonly = 0, recvonly = 0; + int sendonly = 0, recvonly = 0, inactive = 0; int greedy = 0, x = 0, skip = 0; switch_channel_t *channel = switch_core_session_get_channel(session); const char *val; @@ -4093,6 +4093,10 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_set_variable(smh->session->channel, "audio_media_flow", "recvonly"); a_engine->smode = SWITCH_MEDIA_FLOW_RECVONLY; break; + case SWITCH_MEDIA_FLOW_INACTIVE: + switch_channel_set_variable(smh->session->channel, "audio_media_flow", "inactive"); + a_engine->smode = SWITCH_MEDIA_FLOW_INACTIVE; + break; default: switch_channel_set_variable(smh->session->channel, "audio_media_flow", "sendrecv"); a_engine->smode = SWITCH_MEDIA_FLOW_SENDRECV; @@ -4112,7 +4116,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s sendonly = 1; switch_channel_set_variable(session->channel, "media_audio_mode", "recvonly"); } else if (sendonly < 2 && !strcasecmp(attr->a_name, "inactive")) { - sendonly = 1; switch_channel_set_variable(session->channel, "media_audio_mode", "inactive"); } else if (!strcasecmp(attr->a_name, "recvonly")) { switch_channel_set_variable(session->channel, "media_audio_mode", "sendonly"); @@ -4140,7 +4143,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s } - if (sendonly != 1 && recvonly != 1) { + if (sendonly != 1 && recvonly != 1 && inactive != 1) { switch_channel_set_variable(session->channel, "media_audio_mode", NULL); } @@ -4149,6 +4152,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s a_engine->smode = sdp_media_flow(sdp_sendonly); } else if (recvonly) { a_engine->smode = sdp_media_flow(sdp_recvonly); + } else if (inactive) { + a_engine->smode = sdp_media_flow(sdp_inactive); } } @@ -4759,6 +4764,10 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_set_variable(smh->session->channel, "video_media_flow", "recvonly"); v_engine->smode = SWITCH_MEDIA_FLOW_RECVONLY; break; + case SWITCH_MEDIA_FLOW_INACTIVE: + switch_channel_set_variable(smh->session->channel, "video_media_flow", "inactive"); + v_engine->smode = SWITCH_MEDIA_FLOW_INACTIVE; + break; default: switch_channel_set_variable(smh->session->channel, "video_media_flow", "sendrecv"); v_engine->smode = SWITCH_MEDIA_FLOW_SENDRECV; @@ -7940,12 +7949,14 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess sr = "sendonly"; } else if (a_engine->smode == SWITCH_MEDIA_FLOW_RECVONLY) { sr = "recvonly"; + } else if (a_engine->smode == SWITCH_MEDIA_FLOW_INACTIVE) { + sr = "inactive"; } else { sr = "sendrecv"; } if ((var_val = switch_channel_get_variable(session->channel, "origination_audio_mode"))) { - if (!strcasecmp(sr, "sendonly") || !strcasecmp(sr, "recvonly") || !strcasecmp(sr, "sendrecv")) { + if (!strcasecmp(sr, "sendonly") || !strcasecmp(sr, "recvonly") || !strcasecmp(sr, "sendrecv") || !strcasecmp(sr, "inactive")) { sr = var_val; } switch_channel_set_variable(session->channel, "origination_audio_mode", NULL); @@ -8452,6 +8463,8 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=sendonly\r\n"); } else if (v_engine->smode == SWITCH_MEDIA_FLOW_RECVONLY) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=recvonly\r\n"); + } else if (v_engine->smode == SWITCH_MEDIA_FLOW_INACTIVE) { + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=inactive\r\n"); } } else if (smh->mparams->num_codecs) { @@ -11222,8 +11235,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_encoded_video_frame(sw switch_io_event_hook_video_write_frame_t *ptr; switch_status_t status = SWITCH_STATUS_FALSE; - if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY session\n"); + if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY/INACTIVE session\n"); return SWITCH_STATUS_SUCCESS; } @@ -11293,8 +11306,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor return SWITCH_STATUS_FALSE; } - if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY session\n"); + if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY/INACTIVE session\n"); return SWITCH_STATUS_SUCCESS; } From 7150cede347fcbd4f8eb6283e6e10719dc9e9907 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 28 Jun 2016 10:59:24 -0500 Subject: [PATCH 022/128] FS-9303 add CONF_VIDEO_MODE_NONE so we don't default to CONF_VIDEO_MODE_PASSTHROUGH --- src/mod/applications/mod_conference/mod_conference.c | 2 +- src/mod/applications/mod_conference/mod_conference.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 36bd064536..9b61946f95 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -2401,7 +2401,7 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co char *video_letterbox_bgcolor = NULL; char *video_codec_bandwidth = NULL; char *no_video_avatar = NULL; - conference_video_mode_t conference_video_mode = CONF_VIDEO_MODE_PASSTHROUGH; + conference_video_mode_t conference_video_mode = CONF_VIDEO_MODE_NONE; int conference_video_quality = 1; int auto_kps_debounce = 30000; float fps = 30.0f; diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h index 43fbec8c09..b024d68d17 100644 --- a/src/mod/applications/mod_conference/mod_conference.h +++ b/src/mod/applications/mod_conference/mod_conference.h @@ -522,7 +522,8 @@ typedef struct conference_record { typedef enum { CONF_VIDEO_MODE_PASSTHROUGH, CONF_VIDEO_MODE_TRANSCODE, - CONF_VIDEO_MODE_MUX + CONF_VIDEO_MODE_MUX, + CONF_VIDEO_MODE_NONE } conference_video_mode_t; /* Conference Object */ From 9508370de85b98cc6783f477f0452732db55468a Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 28 Jun 2016 11:04:24 -0500 Subject: [PATCH 023/128] Revert "FS-9303 add CONF_VIDEO_MODE_NONE so we don't default to CONF_VIDEO_MODE_PASSTHROUGH" This reverts commit 7150cede347fcbd4f8eb6283e6e10719dc9e9907. --- src/mod/applications/mod_conference/mod_conference.c | 2 +- src/mod/applications/mod_conference/mod_conference.h | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 9b61946f95..36bd064536 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -2401,7 +2401,7 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co char *video_letterbox_bgcolor = NULL; char *video_codec_bandwidth = NULL; char *no_video_avatar = NULL; - conference_video_mode_t conference_video_mode = CONF_VIDEO_MODE_NONE; + conference_video_mode_t conference_video_mode = CONF_VIDEO_MODE_PASSTHROUGH; int conference_video_quality = 1; int auto_kps_debounce = 30000; float fps = 30.0f; diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h index b024d68d17..43fbec8c09 100644 --- a/src/mod/applications/mod_conference/mod_conference.h +++ b/src/mod/applications/mod_conference/mod_conference.h @@ -522,8 +522,7 @@ typedef struct conference_record { typedef enum { CONF_VIDEO_MODE_PASSTHROUGH, CONF_VIDEO_MODE_TRANSCODE, - CONF_VIDEO_MODE_MUX, - CONF_VIDEO_MODE_NONE + CONF_VIDEO_MODE_MUX } conference_video_mode_t; /* Conference Object */ From a954550c82d520515ffbd4b180394e2bdcad6345 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 28 Jun 2016 11:28:53 -0500 Subject: [PATCH 024/128] FS-9303 these checks are no longer needed as the video flag is not sent to file open unless we are in transcode mode, you can record mp4 but it will only contain the audio if in passthru mode. --- src/mod/applications/mod_conference/conference_api.c | 5 ----- src/mod/applications/mod_conference/conference_record.c | 5 ----- 2 files changed, 10 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index 1cfa8dbb48..8bad7f14ff 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -2506,11 +2506,6 @@ switch_status_t conference_api_sub_record(conference_obj_t *conference, switch_s return SWITCH_STATUS_GENERR; } - if (conference->conference_video_mode == CONF_VIDEO_MODE_PASSTHROUGH) { - stream->write_function(stream, "-ERR Video Passthru enabled, recording not permitted.\n"); - return SWITCH_STATUS_SUCCESS; - } - if (argv[3]) { if (argv[3]) { diff --git a/src/mod/applications/mod_conference/conference_record.c b/src/mod/applications/mod_conference/conference_record.c index 89afeab14b..218a057e00 100644 --- a/src/mod/applications/mod_conference/conference_record.c +++ b/src/mod/applications/mod_conference/conference_record.c @@ -60,11 +60,6 @@ void conference_record_launch_thread(conference_obj_t *conference, char *path, i return; } - if (conference->conference_video_mode == CONF_VIDEO_MODE_PASSTHROUGH) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Video Passthru enabled, recording not permitted.\n"); - return; - } - rec->conference = conference; rec->path = switch_core_strdup(pool, path); rec->pool = pool; From 78ebfff8e3f4eff748915a67176c65eed7159620 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Tue, 28 Jun 2016 12:10:47 -0500 Subject: [PATCH 025/128] FS-9305: [mod_conference] return the logo image path from video-logo-img api and handle passing no image path --- .../mod_conference/conference_api.c | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index 8bad7f14ff..29ec532075 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -1624,20 +1624,22 @@ switch_status_t conference_api_sub_vid_logo_img(conference_member_t *member, swi goto end; } - if (!strcasecmp(text, "allclear")) { - switch_channel_set_variable(member->channel, "video_logo_path", NULL); - member->video_logo = NULL; - } else if (!strcasecmp(text, "clear")) { - member->video_logo = NULL; - } else { - member->video_logo = switch_core_strdup(member->pool, text); - } + if (!zstr(text)) { + if (!strcasecmp(text, "allclear")) { + switch_channel_set_variable(member->channel, "video_logo_path", NULL); + member->video_logo = NULL; + } else if (!strcasecmp(text, "clear")) { + member->video_logo = NULL; + } else { + member->video_logo = switch_core_strdup(member->pool, text); + } - conference_video_layer_set_logo(member, layer, text); + conference_video_layer_set_logo(member, layer, text); + } end: - stream->write_function(stream, "+OK\n"); + stream->write_function(stream, "%s\n", member->video_logo ? member->video_logo : "_undef_"); conference_video_release_layer(&layer); From 1448ada505d7455e6bc16415f64794be0619e3a5 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Tue, 28 Jun 2016 14:02:02 -0500 Subject: [PATCH 026/128] FS-9307: [mod_conference] don't close files until after video threads are done to avoid race condition trying to use closed file handle when playing a video file --- .../mod_conference/mod_conference.c | 58 +++++++++---------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 36bd064536..21b1077766 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -691,35 +691,6 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob } } - - /* Close Unused Handles */ - if (conference->fnode) { - conference_file_node_t *fnode, *cur; - switch_memory_pool_t *pool; - - fnode = conference->fnode; - while (fnode) { - cur = fnode; - fnode = fnode->next; - - if (cur->type != NODE_TYPE_SPEECH) { - conference_file_close(conference, cur); - } - - pool = cur->pool; - switch_core_destroy_memory_pool(&pool); - } - conference->fnode = NULL; - } - - if (conference->async_fnode) { - switch_memory_pool_t *pool; - conference_file_close(conference, conference->async_fnode); - pool = conference->async_fnode->pool; - conference->async_fnode = NULL; - switch_core_destroy_memory_pool(&pool); - } - switch_mutex_lock(conference->member_mutex); for (imember = conference->members; imember; imember = imember->next) { switch_channel_t *channel; @@ -768,7 +739,6 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob } switch_mutex_unlock(conference_globals.hash_mutex); - conference_utils_clear_flag(conference, CFLAG_VIDEO_MUXING); for (x = 0; x <= conference->canvas_count; x++) { @@ -779,6 +749,34 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob } } + /* Close Unused Handles */ + if (conference->fnode) { + conference_file_node_t *fnode, *cur; + switch_memory_pool_t *pool; + + fnode = conference->fnode; + while (fnode) { + cur = fnode; + fnode = fnode->next; + + if (cur->type != NODE_TYPE_SPEECH) { + conference_file_close(conference, cur); + } + + pool = cur->pool; + switch_core_destroy_memory_pool(&pool); + } + conference->fnode = NULL; + } + + if (conference->async_fnode) { + switch_memory_pool_t *pool; + conference_file_close(conference, conference->async_fnode); + pool = conference->async_fnode->pool; + conference->async_fnode = NULL; + switch_core_destroy_memory_pool(&pool); + } + /* Wait till everybody is out */ conference_utils_clear_flag_locked(conference, CFLAG_RUNNING); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write Lock ON\n"); From cf6107963ca997f5ef25527d16f98626213047a9 Mon Sep 17 00:00:00 2001 From: Christian Hoene Date: Thu, 30 Jun 2016 14:04:25 +0200 Subject: [PATCH 027/128] Fix for FS-9313 --- src/mod/codecs/mod_opus/mod_opus.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index 959311b58b..e5ff41e6b4 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -244,11 +244,14 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt if (!strcasecmp(data, "stereo")) { codec_settings->stereo = atoi(arg); - codec_fmtp->stereo = codec_settings->stereo; + if(codec_settings->stereo) + codec_fmtp->stereo = 1; } if (!strcasecmp(data, "sprop-stereo")) { codec_settings->sprop_stereo = atoi(arg); + if(codec_settings->sprop_stereo) + codec_fmtp->stereo = 1; } if (!strcasecmp(data, "maxaveragebitrate")) { @@ -629,7 +632,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag } } - context->decoder_object = opus_decoder_create(dec_samplerate, (!context->codec_settings.sprop_stereo ? codec->implementation->number_of_channels : 2), &err); + context->decoder_object = opus_decoder_create(dec_samplerate, codec->implementation->number_of_channels, &err); switch_set_flag(codec, SWITCH_CODEC_FLAG_HAS_PLC); @@ -727,7 +730,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, return SWITCH_STATUS_FALSE; } - frame_samples = *decoded_data_len / 2 / (!context->codec_settings.sprop_stereo ? codec->implementation->number_of_channels : 2); + frame_samples = *decoded_data_len / 2 / codec->implementation->number_of_channels); frame_size = frame_samples - (frame_samples % (codec->implementation->actual_samples_per_second / 400)); if (*flag & SFF_PLC) { @@ -828,7 +831,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, return SWITCH_STATUS_GENERR; } - *decoded_data_len = samples * 2 * (!context->codec_settings.sprop_stereo ? codec->implementation->number_of_channels : 2); + *decoded_data_len = samples * 2 * codec->implementation->number_of_channels; return SWITCH_STATUS_SUCCESS; } From e3d3daef6a57a8870da228b7b4ebd30ed84cfa29 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 30 Jun 2016 10:50:57 -0500 Subject: [PATCH 028/128] FS-9312 #resolve [unreachable code block in switch_core_media] --- src/switch_core_media.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index ff71e3668e..437f0dd4b9 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -1827,6 +1827,8 @@ SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *ses return; } + ocodec = switch_channel_get_variable(session->channel, SWITCH_ORIGINATOR_CODEC_VARIABLE); + smh->payload_space = 0; switch_assert(smh->session != NULL); @@ -1837,11 +1839,10 @@ SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *ses } val = switch_channel_get_variable_dup(session->channel, "media_mix_inbound_outbound_codecs", SWITCH_FALSE, -1); - if (!val || !switch_true(val)) { - if ((ocodec = switch_channel_get_variable(session->channel, SWITCH_ORIGINATOR_CODEC_VARIABLE))) { - codec_string = ocodec; - goto ready; - } + + if ((!val || !switch_true(val) || smh->media_flags[SCMF_DISABLE_TRANSCODING]) && ocodec) { + codec_string = ocodec; + goto ready; } if (!(codec_string = switch_channel_get_variable(session->channel, "codec_string"))) { @@ -1854,13 +1855,7 @@ SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *ses } if (ocodec) { - if (!codec_string || (smh->media_flags[SCMF_DISABLE_TRANSCODING])) { - codec_string = ocodec; - } else { - if (!(codec_string = switch_core_session_sprintf(smh->session, "%s,%s", ocodec, codec_string))) { - codec_string = ocodec; - } - } + codec_string = switch_core_session_sprintf(smh->session, "%s,%s", ocodec, codec_string); } ready: From a6b4934ea8b6f3e56abe48384d51cc43e4ca8422 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Thu, 30 Jun 2016 12:27:43 -0500 Subject: [PATCH 029/128] FS-9314: [mod_conference] fix crash when starting conference in mux mode while specifying or defaulting to a layout group that does not exist. We will now fall back to transcode mode in this case. --- src/mod/applications/mod_conference/conference_video.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 7fccb51fa6..13f15a2af7 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -1354,6 +1354,10 @@ video_layout_t *conference_video_find_best_layout(conference_obj_t *conference, } } + if (!lg) { + return NULL; + } + for (vlnode = lg->layouts; vlnode; vlnode = vlnode->next) { if (vlnode->vlayout->layers >= (int)count) { break; From aad403656c988d0e25d83616b982de45663c101e Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 30 Jun 2016 15:38:25 -0500 Subject: [PATCH 030/128] FS-9317 add screen share examples --- conf/vanilla/dialplan/default.xml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/conf/vanilla/dialplan/default.xml b/conf/vanilla/dialplan/default.xml index 3ffe2871ca..d4ae8e711a 100644 --- a/conf/vanilla/dialplan/default.xml +++ b/conf/vanilla/dialplan/default.xml @@ -382,6 +382,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + From fb49d73e1c7e717ceb9345f03a7cd86aada2d2b1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 1 Jul 2016 09:14:19 -0500 Subject: [PATCH 031/128] FS-9320 #resolve [Adjust buffering based on frame rate differential] --- .../mod_local_stream/mod_local_stream.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.c b/src/mod/formats/mod_local_stream/mod_local_stream.c index b314132f95..87be23842a 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -125,6 +125,7 @@ struct local_stream_source { switch_img_position_t logo_pos; uint8_t logo_opacity; uint8_t text_opacity; + switch_mm_t mm; }; typedef struct local_stream_source local_stream_source_t; @@ -479,6 +480,10 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void retry: + if (switch_core_file_has_video(use_fh, SWITCH_TRUE)) { + source->mm = use_fh->mm; + } + source->has_video = switch_core_file_has_video(use_fh, SWITCH_TRUE) || source->cover_art || source->banner_txt; is_open = switch_test_flag(use_fh, SWITCH_FILE_OPEN); @@ -934,8 +939,9 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle switch_status_t status; switch_time_t now; unsigned int fps = (unsigned int)ceil(handle->mm.fps); - unsigned int min_qsize = fps; - + unsigned int min_qsize = fps / 2; + unsigned int buf_qsize = 5; + if (!(context->ready && context->source->ready)) { return SWITCH_STATUS_FALSE; } @@ -973,7 +979,12 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle return SWITCH_STATUS_BREAK; } - while(context->ready && context->source->ready && (flags & SVR_FLUSH) && switch_queue_size(context->video_q) > min_qsize / 2) { + if (handle->mm.fps >= context->source->mm.source_fps) { + min_qsize = 1; + buf_qsize = 1; + } + + while(context->ready && context->source->ready && (flags & SVR_FLUSH) && switch_queue_size(context->video_q) > min_qsize) { if (switch_queue_trypop(context->video_q, &pop) == SWITCH_STATUS_SUCCESS) { switch_image_t *img = (switch_image_t *) pop; switch_img_free(&img); @@ -984,7 +995,7 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle return SWITCH_STATUS_FALSE; } - while (!(flags & SVR_BLOCK) && switch_queue_size(context->video_q) < 5) { + while (!(flags & SVR_BLOCK) && switch_queue_size(context->video_q) < buf_qsize) { return SWITCH_STATUS_BREAK; } From 9988d8d9059c65194d536824db95546081d292b2 Mon Sep 17 00:00:00 2001 From: Muhammad Zaka Date: Fri, 1 Jul 2016 16:35:30 +0100 Subject: [PATCH 032/128] FS-9278: sending sendonly instead of sendrecv media attribute in SDP when unholding call when Zoiper softphone had responded with inactive --- src/switch_core_media.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 437f0dd4b9..591fab229a 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -4069,6 +4069,9 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (!sendonly && (m->m_mode == sdp_sendonly || m->m_mode == sdp_inactive)) { sendonly = 1; + if (m->m_mode == sdp_inactive) { + inactive = 1; + } } if (!sendonly && m->m_connections && m->m_connections->c_address && !strcmp(m->m_connections->c_address, "0.0.0.0")) { @@ -4143,12 +4146,17 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s } if (sdp_type == SDP_TYPE_RESPONSE) { - if (sendonly) { + if (inactive) { + // When freeswitch had previously sent inactive in sip request. it should remain inactive otherwise smode should be sendrecv + if (a_engine->smode==SWITCH_MEDIA_FLOW_INACTIVE) { + a_engine->smode = sdp_media_flow(sdp_inactive); + } else { + a_engine->smode = sdp_media_flow(sdp_sendrecv); + } + } else if (sendonly) { a_engine->smode = sdp_media_flow(sdp_sendonly); } else if (recvonly) { a_engine->smode = sdp_media_flow(sdp_recvonly); - } else if (inactive) { - a_engine->smode = sdp_media_flow(sdp_inactive); } } From f0a36960c75d870bd75ec463f6e002186a13bbe9 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Fri, 1 Jul 2016 13:09:51 -0400 Subject: [PATCH 033/128] FS-9315 [mod_http_cache] add support for video file formats --- .../mod_http_cache/mod_http_cache.c | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/mod/applications/mod_http_cache/mod_http_cache.c b/src/mod/applications/mod_http_cache/mod_http_cache.c index ca47505d59..b06b9c4029 100644 --- a/src/mod/applications/mod_http_cache/mod_http_cache.c +++ b/src/mod/applications/mod_http_cache/mod_http_cache.c @@ -1740,6 +1740,12 @@ static switch_status_t http_cache_file_open(switch_file_handle_t *handle, const switch_clear_flag_locked(handle, SWITCH_FILE_NATIVE); } + if (switch_test_flag(&context->fh, SWITCH_FILE_FLAG_VIDEO)) { + switch_set_flag_locked(handle, SWITCH_FILE_FLAG_VIDEO); + } else { + switch_clear_flag_locked(handle, SWITCH_FILE_FLAG_VIDEO); + } + return status; } @@ -1791,6 +1797,30 @@ static switch_status_t http_file_write(switch_file_handle_t *handle, void *data, return switch_core_file_write(&context->fh, data, len); } +/** + * Read from HTTP video file + * @param handle + * @param frame + * @return + */ +static switch_status_t http_file_read_video(switch_file_handle_t *handle, switch_frame_t *frame, switch_video_read_flag_t flags) +{ + struct http_context *context = (struct http_context *)handle->private_info; + return switch_core_file_read_video(&context->fh, frame, flags); +} + +/** + * Write to HTTP video file + * @param handle + * @param frame + * @return + */ +static switch_status_t http_file_write_video(switch_file_handle_t *handle, switch_frame_t *frame) +{ + struct http_context *context = (struct http_context *)handle->private_info; + return switch_core_file_write_video(&context->fh, frame); +} + /** * Close HTTP file * @param handle @@ -1851,6 +1881,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_http_cache_load) file_interface->file_close = http_file_close; file_interface->file_read = http_file_read; file_interface->file_write = http_file_write; + file_interface->file_read_video = http_file_read_video; + file_interface->file_write_video = http_file_write_video; if (gcache.enable_file_formats) { file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE); @@ -1860,6 +1892,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_http_cache_load) file_interface->file_close = http_file_close; file_interface->file_read = http_file_read; file_interface->file_write = http_file_write; + file_interface->file_read_video = http_file_read_video; + file_interface->file_write_video = http_file_write_video; file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE); file_interface->interface_name = modname; @@ -1868,6 +1902,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_http_cache_load) file_interface->file_close = http_file_close; file_interface->file_read = http_file_read; file_interface->file_write = http_file_write; + file_interface->file_read_video = http_file_read_video; + file_interface->file_write_video = http_file_write_video; } /* create the queue from configuration */ From a77387456d9a4fe7334ab9c7ff4c9f5f66686d3b Mon Sep 17 00:00:00 2001 From: Piotr Gregor Date: Mon, 4 Jul 2016 16:26:08 +0100 Subject: [PATCH 034/128] FS-9009 [mod_avmd] Amplitude estimation Add DESA-2 estimation of signal amplitude --- .../applications/mod_avmd/avmd_amplitude.c | 11 +-- .../applications/mod_avmd/avmd_amplitude.h | 9 +- src/mod/applications/mod_avmd/avmd_desa2.c | 20 +++-- src/mod/applications/mod_avmd/avmd_desa2.h | 11 ++- .../mod_avmd/avmd_desa2_tweaked.c | 21 +++-- .../mod_avmd/avmd_desa2_tweaked.h | 5 +- src/mod/applications/mod_avmd/avmd_psi.h | 4 +- src/mod/applications/mod_avmd/mod_avmd.c | 90 +++++++++++++------ 8 files changed, 114 insertions(+), 57 deletions(-) diff --git a/src/mod/applications/mod_avmd/avmd_amplitude.c b/src/mod/applications/mod_avmd/avmd_amplitude.c index a54caef4fa..16f1312d04 100644 --- a/src/mod/applications/mod_avmd/avmd_amplitude.c +++ b/src/mod/applications/mod_avmd/avmd_amplitude.c @@ -5,15 +5,8 @@ #include "avmd_amplitude.h" #include "avmd_psi.h" -/*! \brief - * @author Eric des Courtis - * @param b A circular audio sample buffer - * @param i Position in the buffer - * @param f Frequency estimate - * @return The amplitude at position i - */ -extern double avmd_amplitude(circ_buffer_t *b, size_t i, double f) -{ + +double avmd_amplitude(circ_buffer_t *b, size_t i, double f) { double result; result = sqrt(PSI(b, i) / sin(f * f)); return result; diff --git a/src/mod/applications/mod_avmd/avmd_amplitude.h b/src/mod/applications/mod_avmd/avmd_amplitude.h index b059dfffba..13e5edadeb 100644 --- a/src/mod/applications/mod_avmd/avmd_amplitude.h +++ b/src/mod/applications/mod_avmd/avmd_amplitude.h @@ -1,7 +1,10 @@ /* * @brief Estimation of amplitude using DESA-2 algorithm. - * @author Eric des Courtis - * @par Modifications: Piotr Gregor < piotrek.gregor gmail.com > + * + * Contributor(s): + * + * Eric des Courtis + * Piotr Gregor : */ @@ -12,7 +15,7 @@ #include "avmd_buffer.h" -extern double avmd_amplitude(circ_buffer_t *, size_t i, double f); +double avmd_amplitude(circ_buffer_t *, size_t i, double f) __attribute__ ((nonnull(1))); #endif /* __AVMD_AMPLITUDE_H__ */ diff --git a/src/mod/applications/mod_avmd/avmd_desa2.c b/src/mod/applications/mod_avmd/avmd_desa2.c index b1d19eb8ae..2f35d3beb5 100644 --- a/src/mod/applications/mod_avmd/avmd_desa2.c +++ b/src/mod/applications/mod_avmd/avmd_desa2.c @@ -19,8 +19,8 @@ int __isnan(double); #include "avmd_fast_acosf.h" #endif -extern double avmd_desa2(circ_buffer_t *b, size_t i) -{ + +double avmd_desa2(circ_buffer_t *b, size_t i, double *amplitude) { double d; double n; double x0; @@ -30,6 +30,7 @@ extern double avmd_desa2(circ_buffer_t *b, size_t i) double x4; double x2sq; double result; + double PSI_Xn, PSI_Yn, NEEDED; x0 = GET_SAMPLE((b), (i)); x1 = GET_SAMPLE((b), ((i) + 1)); @@ -39,8 +40,14 @@ extern double avmd_desa2(circ_buffer_t *b, size_t i) x2sq = x2 * x2; d = 2.0 * ((x2sq) - (x1 * x3)); - if (d == 0.0) return 0.0; - n = ((x2sq) - (x0 * x4)) - ((x1 * x1) - (x0 * x2)) - ((x3 * x3) - (x2 * x4)); + if (d == 0.0) { + *amplitude = 0.0; + return 0.0; + } + PSI_Xn = ((x2sq) - (x0 * x4)); + NEEDED = ((x1 * x1) - (x0 * x2)) + ((x3 * x3) - (x2 * x4)); + n = ((x2sq) - (x0 * x4)) - NEEDED; + PSI_Yn = NEEDED + PSI_Xn; #ifdef AVMD_FAST_MATH result = 0.5 * (double)fast_acosf((float)n/d); @@ -48,7 +55,10 @@ extern double avmd_desa2(circ_buffer_t *b, size_t i) result = 0.5 * acos(n/d); #endif - if (ISNAN(result)) result = 0.0; + if (ISNAN(result)) { + result = 0.0; + } + *amplitude = 2.0 * PSI_Xn / sqrt(PSI_Yn); return result; diff --git a/src/mod/applications/mod_avmd/avmd_desa2.h b/src/mod/applications/mod_avmd/avmd_desa2.h index f6488e2ad8..1da9ef346e 100644 --- a/src/mod/applications/mod_avmd/avmd_desa2.h +++ b/src/mod/applications/mod_avmd/avmd_desa2.h @@ -1,7 +1,10 @@ /* * @brief DESA-2 algorithm implementation. - * @author Eric des Courtis - * @par Modifications: Piotr Gregor < piotrek.gregor gmail.com > + * + * Contributor(s): + * + * Eric des Courtis + * Piotr Gregor : */ @@ -12,8 +15,8 @@ #include #include "avmd_buffer.h" -/* Returns digital frequency estimation. */ -extern double avmd_desa2(circ_buffer_t *b, size_t i); +/* Returns digital frequency estimation and amplitude estimation. */ +extern double avmd_desa2(circ_buffer_t *b, size_t i, double *amplitude) __attribute__ ((nonnull(1,3))); #endif /* __AVMD_DESA2_H__ */ diff --git a/src/mod/applications/mod_avmd/avmd_desa2_tweaked.c b/src/mod/applications/mod_avmd/avmd_desa2_tweaked.c index 8eae1753f3..f1ad5243d6 100644 --- a/src/mod/applications/mod_avmd/avmd_desa2_tweaked.c +++ b/src/mod/applications/mod_avmd/avmd_desa2_tweaked.c @@ -19,11 +19,10 @@ int __isnan(double); #include "avmd_fast_acosf.h" #endif + double -avmd_desa2_tweaked(circ_buffer_t *b, size_t i) -{ - double d; - double n; +avmd_desa2_tweaked(circ_buffer_t *b, size_t i, double *amplitude) { + double n, d; double x0; double x1; double x2; @@ -31,6 +30,7 @@ avmd_desa2_tweaked(circ_buffer_t *b, size_t i) double x4; double x2sq; double result; + double PSI_Xn, PSI_Yn, NEEDED; x0 = GET_SAMPLE((b), (i)); x1 = GET_SAMPLE((b), ((i) + 1)); @@ -39,8 +39,10 @@ avmd_desa2_tweaked(circ_buffer_t *b, size_t i) x4 = GET_SAMPLE((b), ((i) + 4)); x2sq = x2 * x2; d = 2.0 * ((x2sq) - (x1 * x3)); - n = ((x2sq) - (x0 * x4)) - ((x1 * x1) - - (x0 * x2)) - ((x3 * x3) - (x2 * x4)); + PSI_Xn = ((x2sq) - (x0 * x4)); + NEEDED = ((x1 * x1) - (x0 * x2)) + ((x3 * x3) - (x2 * x4)); + n = ((x2sq) - (x0 * x4)) - NEEDED; + PSI_Yn = NEEDED + PSI_Xn; /* instead of #ifdef FASTMATH @@ -52,11 +54,14 @@ avmd_desa2_tweaked(circ_buffer_t *b, size_t i) result = n/d; if (ISINF(result)) { - if (n < 0.0) + *amplitude = 0.0; + if (n < 0.0) { return -10.0; - else + } else { return 10.0; + } } + *amplitude = 2.0 * PSI_Xn / sqrt(PSI_Yn); return result; } diff --git a/src/mod/applications/mod_avmd/avmd_desa2_tweaked.h b/src/mod/applications/mod_avmd/avmd_desa2_tweaked.h index 167e241c9d..997abbb84d 100644 --- a/src/mod/applications/mod_avmd/avmd_desa2_tweaked.h +++ b/src/mod/applications/mod_avmd/avmd_desa2_tweaked.h @@ -33,9 +33,10 @@ * to corresponding frequencies is nonlinear. * The actual frequency estimation can be retrieved later * from this partial result using - * 0.5 * acos(n/d) + * 0.5 * acos(returned_value) + * Amplitude estimation is returned by address. */ -double avmd_desa2_tweaked(circ_buffer_t *b, size_t i); +double avmd_desa2_tweaked(circ_buffer_t *b, size_t i, double *amplitude) __attribute__ ((nonnull(1,3))); #endif /* __AVMD_DESA2_TWEAKED_H__ */ diff --git a/src/mod/applications/mod_avmd/avmd_psi.h b/src/mod/applications/mod_avmd/avmd_psi.h index 1764897d65..db6d83a60e 100644 --- a/src/mod/applications/mod_avmd/avmd_psi.h +++ b/src/mod/applications/mod_avmd/avmd_psi.h @@ -4,6 +4,8 @@ #include "avmd_buffer.h" -#define PSI(b, i) (GET_SAMPLE((b), ((i) + 1))*GET_SAMPLE((b), ((i) + 1))-GET_SAMPLE((b), ((i) + 2))*GET_SAMPLE((b), ((i) + 0))) + +#define PSI(b, i) (GET_SAMPLE((b), ((i) + 1)) * GET_SAMPLE((b), ((i) + 1)) - GET_SAMPLE((b), ((i) + 2)) * GET_SAMPLE((b), ((i) + 0))) + #endif /* __AVMD_PSI_H__ */ diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index 19f0ed71b0..5fa0bb474f 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -175,6 +175,8 @@ typedef struct { circ_buffer_t b; sma_buffer_t sma_b; sma_buffer_t sqa_b; + sma_buffer_t sma_amp_b; + sma_buffer_t sqa_amp_b; size_t pos; double f; /* freq_table_t ft; */ @@ -199,7 +201,7 @@ static switch_status_t avmd_register_all_events(void); static void avmd_unregister_all_events(void); static void -avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, double v, avmd_beep_state_t beep_status, uint8_t info); +avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, double v_freq, double amp, double v_amp, avmd_beep_state_t beep_status, uint8_t info); /* API [set default], reset to factory settings */ static void avmd_set_xml_default_configuration(switch_mutex_t *mutex); @@ -276,6 +278,20 @@ init_avmd_session_data(avmd_session_t *avmd_session, switch_core_session_t *fs_s goto end; } memset(avmd_session->sqa_b.data, 0, sizeof(BUFF_TYPE) * buf_sz); + + INIT_SMA_BUFFER(&avmd_session->sma_amp_b, buf_sz, fs_session); + if (avmd_session->sma_amp_b.data == NULL) { + status = SWITCH_STATUS_FALSE; + goto end; + } + memset(avmd_session->sma_amp_b.data, 0, sizeof(BUFF_TYPE) * buf_sz); + + INIT_SMA_BUFFER(&avmd_session->sqa_amp_b, buf_sz, fs_session); + if (avmd_session->sqa_amp_b.data == NULL) { + status = SWITCH_STATUS_FALSE; + goto end; + } + memset(avmd_session->sqa_amp_b.data, 0, sizeof(BUFF_TYPE) * buf_sz); end: if (mutex != NULL) { @@ -407,8 +423,7 @@ avmd_unregister_all_events(void) } static void -avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, double v, avmd_beep_state_t beep_status, uint8_t info) -{ +avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, double v_freq, double amp, double v_amp, avmd_beep_state_t beep_status, uint8_t info) { int res; switch_event_t *event; switch_status_t status; @@ -421,23 +436,36 @@ avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, } switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(fs_s)); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "avmd"); - switch (type) - { + switch (type) { case AVMD_EVENT_BEEP: switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Beep-Status", "DETECTED"); res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%f", freq); if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Frequency truncated [%s], [%d] attempted!\n", buf, res); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "frequency", "ERROR (TRUNCATED)"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Frequency", "ERROR (TRUNCATED)"); } - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "frequency", buf); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Frequency", buf); - res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%f", v); + res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%f", v_freq); if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Error, truncated [%s], [%d] attempeted!\n", buf, res); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "variance", "ERROR (TRUNCATED)"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Frequency-variance", "ERROR (TRUNCATED)"); } - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "variance", buf); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Frequency-variance", buf); + + res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%f", amp); + if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Amplitude truncated [%s], [%d] attempted!\n", buf, res); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Amplitude", "ERROR (TRUNCATED)"); + } + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Amplitude", buf); + + res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%f", v_amp); + if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Error, truncated [%s], [%d] attempeted!\n", buf, res); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Amplitude-variance", "ERROR (TRUNCATED)"); + } + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Amplitude-variance", buf); break; case AVMD_EVENT_SESSION_START: @@ -1055,7 +1083,7 @@ SWITCH_STANDARD_APP(avmd_start_app) goto end; } switch_channel_set_private(channel, "_avmd_", bug); /* Set the avmd tag to detect an existing avmd media bug */ - avmd_fire_event(AVMD_EVENT_SESSION_START, session, 0, 0, 0, 0); + avmd_fire_event(AVMD_EVENT_SESSION_START, session, 0, 0, 0, 0, 0, 0); if (avmd_session->settings.report_status == 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Avmd on channel [%s] started!\n", switch_channel_get_name(channel)); } @@ -1113,9 +1141,9 @@ SWITCH_STANDARD_APP(avmd_stop_app) switch_channel_set_private(channel, "_avmd_", NULL); switch_core_media_bug_remove(session, &bug); if (avmd_found == 1) { - avmd_fire_event(AVMD_EVENT_SESSION_STOP, session, 0, 0, beep_status, 1); + avmd_fire_event(AVMD_EVENT_SESSION_STOP, session, 0, 0, 0, 0, beep_status, 1); } else { - avmd_fire_event(AVMD_EVENT_SESSION_STOP, session, 0, 0, beep_status, 0); + avmd_fire_event(AVMD_EVENT_SESSION_STOP, session, 0, 0, 0, 0, beep_status, 0); } if (report_status == 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Avmd on channel [%s] stopped, beep status: [%s]\n", @@ -1379,7 +1407,7 @@ SWITCH_STANDARD_API(avmd_api_main) uuid_dup = switch_core_strdup(switch_core_session_get_pool(fs_session), uuid); switch_channel_set_private(channel, "_avmd_", NULL); switch_core_media_bug_remove(fs_session, &bug); - avmd_fire_event(AVMD_EVENT_SESSION_STOP, fs_session, 0, 0, 0, 0); + avmd_fire_event(AVMD_EVENT_SESSION_STOP, fs_session, 0, 0, 0, 0, 0, 0); if (avmd_globals.settings.report_status == 1) { stream->write_function(stream, "+OK\n [%s] [%s] stopped\n\n", uuid_dup, switch_channel_get_name(channel)); @@ -1500,7 +1528,7 @@ SWITCH_STANDARD_API(avmd_api_main) switch_channel_set_private(channel, "_avmd_", bug); /* Set the vmd tag to detect an existing vmd media bug */ - avmd_fire_event(AVMD_EVENT_SESSION_START, fs_session, 0, 0, 0, 0); + avmd_fire_event(AVMD_EVENT_SESSION_START, fs_session, 0, 0, 0, 0, 0, 0); if (avmd_globals.settings.report_status == 1) { stream->write_function(stream, "+OK\n [%s] [%s] started!\n\n", uuid, switch_channel_get_name(channel)); @@ -1529,9 +1557,9 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) { switch_channel_t *channel; circ_buffer_t *b; size_t pos; - double omega; + double omega, amplitude; double f; - double v; + double v, v_amp; double sma_digital_freq; uint32_t sine_len_i; int sample_to_skip_n = s->settings.sample_n_to_skip; @@ -1559,7 +1587,7 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) { /*for (pos = session->pos; pos < (GET_CURRENT_POS(b) - P); pos++) { */ if ((sample_n % sine_len_i) == 0) { /* Get a desa2 frequency estimate every sine len */ - omega = avmd_desa2_tweaked(b, pos + sample_n); + omega = avmd_desa2_tweaked(b, pos + sample_n, &litude); if (omega < -0.999999 || omega > 0.999999) { if (s->settings.debug == 1) { @@ -1569,6 +1597,8 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) { if (s->settings.require_continuous_streak == 1) { RESET_SMA_BUFFER(&s->sma_b); RESET_SMA_BUFFER(&s->sqa_b); + RESET_SMA_BUFFER(&s->sma_amp_b); + RESET_SMA_BUFFER(&s->sqa_amp_b); s->samples_streak = s->settings.sample_n_continuous_streak; sample_to_skip_n = s->settings.sample_n_to_skip; } @@ -1603,12 +1633,15 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) { APPEND_SMA_VAL(&s->sma_b, omega); /* append */ APPEND_SMA_VAL(&s->sqa_b, omega * omega); + APPEND_SMA_VAL(&s->sma_amp_b, amplitude); /* append */ + APPEND_SMA_VAL(&s->sqa_amp_b, amplitude * amplitude); if (s->settings.require_continuous_streak == 1) { if (s->samples_streak > 0) { --s->samples_streak; } } - v = s->sqa_b.sma - (s->sma_b.sma * s->sma_b.sma); /* calculate variance (biased estimator) */ + v = s->sqa_b.sma - (s->sma_b.sma * s->sma_b.sma); /* calculate variance of omega(biased estimator) */ + v_amp = s->sqa_amp_b.sma - (s->sma_amp_b.sma * s->sma_amp_b.sma); /* calculate variance of amplitude (biased estimator) */ if (s->settings.debug == 1) { #if !defined(WIN32) && defined(AVMD_FAST_MATH) f = 0.5 * (double) fast_acosf((float)omega); @@ -1619,11 +1652,16 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) { #endif /* !WIN32 && AVMD_FAST_MATH */ if (s->settings.require_continuous_streak == 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_DEBUG, "<<< AVMD v[%.10f]\tomega[%f]\tf[%f] [%f]Hz\t\tsma[%f][%f]Hz\t\tsqa[%f]\t" - "streak[%zu] pos[%zu] sample_n[%zu] lpos[%zu] s[%zu]>>>\n", v, omega, f, TO_HZ(s->rate, f), s->sma_b.sma, TO_HZ(s->rate, sma_digital_freq), s->sqa_b.sma, s->samples_streak, - s->sma_b.pos, sample_n, s->sma_b.lpos, pos); + "amplitude[%f]\tv_amp[%f]\t" + "streak[%zu] pos[%zu] sample_n[%zu] lpos[%zu] s[%zu]>>>\n", v, omega, f, TO_HZ(s->rate, f), s->sma_b.sma, TO_HZ(s->rate, sma_digital_freq), s->sqa_b.sma, + amplitude, v_amp, + s->samples_streak, s->sma_b.pos, sample_n, s->sma_b.lpos, pos); } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_DEBUG, "<<< AVMD v[%.10f]\tomega[%f]\tf[%f] [%f]Hz\t\tsma[%f][%f]Hz\t\tsqa[%f]\tpos[%zu]" - " sample_n[%zu] lpos[%zu] s[%zu]>>>\n", v, omega, f, TO_HZ(s->rate, f), s->sma_b.sma, TO_HZ(s->rate, sma_digital_freq), s->sqa_b.sma, s->sma_b.pos, sample_n, s->sma_b.lpos, pos); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_DEBUG, "<<< AVMD v[%.10f]\tomega[%f]\tf[%f] [%f]Hz\t\tsma[%f][%f]Hz\t\tsqa[%f]\t" + "amplitude[%f]\tv_amp[%f]\t" + "pos[%zu] sample_n[%zu] lpos[%zu] s[%zu]>>>\n", v, omega, f, TO_HZ(s->rate, f), s->sma_b.sma, TO_HZ(s->rate, sma_digital_freq), s->sqa_b.sma, + amplitude, v_amp, + s->sma_b.pos, sample_n, s->sma_b.lpos, pos); } } } @@ -1641,13 +1679,15 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) { switch_channel_set_variable_printf(channel, "avmd_total_time", "[%d]", (int)(switch_micro_time_now() - s->start_time) / 1000); switch_channel_execute_on(channel, "execute_on_avmd_beep"); - avmd_fire_event(AVMD_EVENT_BEEP, s->session, TO_HZ(s->rate, sma_digital_freq), v, 0, 0); + avmd_fire_event(AVMD_EVENT_BEEP, s->session, TO_HZ(s->rate, sma_digital_freq), v, s->sma_amp_b.sma, v_amp, 0, 0); if (s->settings.report_status == 1) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_INFO, "<<< AVMD - Beep Detected: f = [%f], variance = [%f] >>>\n", TO_HZ(s->rate, sma_digital_freq), v); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_INFO, "<<< AVMD - Beep Detected: f = [%f] variance = [%f], amplitude = [%f] variance = [%f] >>>\n", TO_HZ(s->rate, sma_digital_freq), v, s->sma_amp_b.sma, v_amp); } switch_channel_set_variable(channel, "avmd_detect", "TRUE"); RESET_SMA_BUFFER(&s->sma_b); RESET_SMA_BUFFER(&s->sqa_b); + RESET_SMA_BUFFER(&s->sma_amp_b); + RESET_SMA_BUFFER(&s->sqa_amp_b); s->state.beep_state = BEEP_DETECTED; goto done; } From 78c2ed0526e25c10241ceb918e73aef02446ffd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Wed, 8 Jun 2016 19:01:31 +0200 Subject: [PATCH 035/128] FS-9241 Use tls_public_url instead of tls_url in INVITE Contact when NAT is detected --- src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia.c | 10 ++----- src/mod/endpoints/mod_sofia/sofia_glue.c | 37 ++++++++++++++++++------ 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 512f239eb4..70ef0dd241 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -1028,6 +1028,7 @@ void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip); switch_status_t sofia_on_hangup(switch_core_session_t *session); char *sofia_glue_get_url_from_contact(char *buf, uint8_t to_dup); char *sofia_glue_get_path_from_contact(char *buf); +char *sofia_glue_get_profile_url(sofia_profile_t *profile, char *remote_ip, const sofia_transport_t transport); void sofia_presence_set_hash_key(char *hash_key, int32_t len, sip_t const *sip); void sofia_glue_sql_close(sofia_profile_t *profile, time_t prune); int sofia_glue_init_sql(sofia_profile_t *profile); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 811a45d753..49eb3eff8e 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -10046,11 +10046,9 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia user, ipv6 ? "[" : "", host, ipv6 ? "]" : "", port, sofia_glue_transport2str(transport)); if (sofia_glue_check_nat(profile, tech_pvt->mparams.remote_ip)) { - url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_public_url : profile->public_url; check_nat = 1; - } else { - url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_url : profile->url; } + url = sofia_glue_get_profile_url(profile, tech_pvt->mparams.remote_ip, transport); if (!url) { if (check_nat) { @@ -10085,11 +10083,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia } else { const char *url = NULL; - if (sofia_glue_check_nat(profile, tech_pvt->mparams.remote_ip)) { - url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_public_url : profile->public_url; - } else { - url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_url : profile->url; - } + url = sofia_glue_get_profile_url(profile, tech_pvt->mparams.remote_ip, transport); if (url) { const char *brackets = NULL; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index eaad00a2a1..9fc7a60a70 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -931,15 +931,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) ipv6 ? "[" : "", ip_addr, ipv6 ? "]" : "", tech_pvt->profile->extsipport); } } else { - if (sofia_glue_transport_has_tls(tech_pvt->transport)) { - tech_pvt->invite_contact = tech_pvt->profile->tls_url; - } else { - if (!zstr(tech_pvt->mparams.remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams.remote_ip)) { - tech_pvt->invite_contact = tech_pvt->profile->public_url; - } else { - tech_pvt->invite_contact = tech_pvt->profile->url; - } - } + sofia_glue_get_profile_url(tech_pvt->profile, tech_pvt->mparams.remote_ip, tech_pvt->transport); } } @@ -3105,6 +3097,33 @@ void sofia_glue_clear_soa(switch_core_session_t *session, switch_bool_t partner) } +char *sofia_glue_get_profile_url(sofia_profile_t *profile, char *remote_ip, const sofia_transport_t transport) +{ + char *url = NULL; + int check_nat = 0; + + if (!zstr(remote_ip) && sofia_glue_check_nat(profile, remote_ip)) { + check_nat = 1; + } + + if (sofia_glue_transport_has_tls(transport)) { + if (check_nat && profile->tls_public_url) { + url = profile->tls_public_url; + } else { + url = profile->tls_url; + } + } else { + if (check_nat && profile->public_url) { + url = profile->public_url; + } else { + url = profile->url; + } + } + + if (!url) url = profile->url; + + return url; +} /* For Emacs: * Local Variables: From 0ab9f5156e810f52eabb0e7a32eee380dfb53549 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 5 Jul 2016 13:27:36 -0500 Subject: [PATCH 036/128] FS-9267 fix regression --- src/switch_core_media.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 591fab229a..91492d194c 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -11727,10 +11727,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core } } - if (patchers) { - switch_set_flag((*frame)->codec, SWITCH_CODEC_FLAG_VIDEO_PATCHING); - } else { - switch_clear_flag((*frame)->codec, SWITCH_CODEC_FLAG_VIDEO_PATCHING); + if ((*frame)->codec) { + if (patchers) { + switch_set_flag((*frame)->codec, SWITCH_CODEC_FLAG_VIDEO_PATCHING); + } else { + switch_clear_flag((*frame)->codec, SWITCH_CODEC_FLAG_VIDEO_PATCHING); + } } if (status == SWITCH_STATUS_SUCCESS) { From f6192c7949b17dd3f5dd075b2a7656eac748bc10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Wed, 6 Jul 2016 17:29:15 +0200 Subject: [PATCH 037/128] FS-9241: follow-up patch to fix a mistake in fetching profile url --- src/mod/endpoints/mod_sofia/sofia_glue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 9fc7a60a70..cef4c61429 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -931,7 +931,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) ipv6 ? "[" : "", ip_addr, ipv6 ? "]" : "", tech_pvt->profile->extsipport); } } else { - sofia_glue_get_profile_url(tech_pvt->profile, tech_pvt->mparams.remote_ip, tech_pvt->transport); + tech_pvt->invite_contact = sofia_glue_get_profile_url(tech_pvt->profile, tech_pvt->mparams.remote_ip, tech_pvt->transport); } } From 3a3f456e88d033a5a6c326a241563ccfdef44f72 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 6 Jul 2016 11:36:38 -0500 Subject: [PATCH 038/128] FS-9316 #resolve [INVITE with empty SDP from Cisco VCS cannot setup video] --- src/mod/endpoints/mod_sofia/sofia.c | 1 + src/switch_core_media.c | 23 +++++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 49eb3eff8e..303330c0e0 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -7402,6 +7402,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } else { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP"); switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); + switch_core_media_prepare_codecs(session, 1); switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); sofia_set_flag_locked(tech_pvt, TFLAG_3PCC); switch_channel_set_state(channel, CS_HIBERNATE); diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 91492d194c..c16f37a6ad 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -7716,7 +7716,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess int is_outbound = switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND; const char *vbw; int bw = 256; - uint8_t fir = 0, nack = 0, pli = 0, tmmbr = 0; + uint8_t fir = 0, nack = 0, pli = 0, tmmbr = 0, has_vid = 0; switch_assert(session); @@ -8306,7 +8306,26 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess video: - if (!switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE)) { + + if (!switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE) && sdp_type == SDP_TYPE_REQUEST) { + has_vid = 0; + } else { + int i; + + for (i = 0; i < smh->mparams->num_codecs; i++) { + const switch_codec_implementation_t *imp = smh->codecs[i]; + + + if (imp->codec_type == SWITCH_CODEC_TYPE_VIDEO) { + has_vid = 1; + break; + } + } + + } + + + if (!has_vid) { if (switch_channel_test_flag(session->channel, CF_VIDEO_SDP_RECVD)) { switch_channel_clear_flag(session->channel, CF_VIDEO_SDP_RECVD); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=video 0 %s 19\r\n", From 8c6b2657bf389fd013affcc8e24bca39c2156c5f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 6 Jul 2016 13:19:46 -0500 Subject: [PATCH 039/128] FS-9328 #resolve [switch_jb_peek_frame uses wrong len] --- src/switch_jitterbuffer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/switch_jitterbuffer.c b/src/switch_jitterbuffer.c index 4bfca88821..427498a5d2 100644 --- a/src/switch_jitterbuffer.c +++ b/src/switch_jitterbuffer.c @@ -902,10 +902,10 @@ SWITCH_DECLARE(switch_status_t) switch_jb_peek_frame(switch_jb_t *jb, uint32_t t frame->seq = ntohs(node->packet.header.seq); frame->timestamp = ntohl(node->packet.header.ts); frame->m = node->packet.header.m; - frame->datalen = node->len; + frame->datalen = node->len - 12; - if (frame->data && frame->buflen > node->len) { - memcpy(frame->data, node->packet.body, node->len); + if (frame->data && frame->buflen > node->len - 12) { + memcpy(frame->data, node->packet.body, node->len - 12); } return SWITCH_STATUS_SUCCESS; } From f893f2486a67b9ff2cc47c9c697c957c449e2973 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 7 Jul 2016 13:39:02 -0500 Subject: [PATCH 040/128] FS-9333 #resolve [Disable video refresh by sip INFO by default] --- src/mod/endpoints/mod_sofia/mod_sofia.c | 30 +++++++++++-------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 6a41f87062..b43be77da4 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1379,25 +1379,21 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi break; case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ: - if (!switch_channel_test_flag(channel, CF_AVPF)) { - //const char *ua = switch_channel_get_variable(tech_pvt->channel, "sip_user_agent"); - //if (ua && switch_stristr("polycom", ua)) { - - //const char *pl = "\n\n\n\n\n\n\n\n"; - const char *pl = "\n\n"; - switch_time_t now = switch_micro_time_now(); + if (!switch_channel_test_flag(channel, CF_AVPF) && switch_true(switch_core_get_variable("sofia_send_info_vid_refresh"))) { + const char *pl = "\n\n"; + switch_time_t now = switch_micro_time_now(); + + if (!tech_pvt->last_vid_info || (now - tech_pvt->last_vid_info) > 500000) { - if (!tech_pvt->last_vid_info || (now - tech_pvt->last_vid_info) > 500000) { - - tech_pvt->last_vid_info = now; - - if (!zstr(msg->string_arg)) { - pl = msg->string_arg; - } - - nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/media_control+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END()); + tech_pvt->last_vid_info = now; + + if (!zstr(msg->string_arg)) { + pl = msg->string_arg; } - //} + + nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/media_control+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END()); + } + } break; case SWITCH_MESSAGE_INDICATE_BROADCAST: From 35b816bb2758d0b73661b8e12091bdbe0165efc5 Mon Sep 17 00:00:00 2001 From: William King Date: Sun, 21 Feb 2016 16:36:43 -0800 Subject: [PATCH 041/128] FS-9310 Native support for Flowroute SMS API over HTTP(S) --- build/modules.conf.in | 1 + .../vanilla/autoload_configs/modules.conf.xml | 1 + .../autoload_configs/sms_flowroute.conf.xml | 13 + conf/vanilla/chatplan/default.xml | 2 +- configure.ac | 13 + .../mod_sms_flowroute/Makefile.am | 17 + .../applications/mod_sms_flowroute/TODO.txt | 30 + .../mod_sms_flowroute/mod_sms_flowroute.c | 667 ++++++++++++++++++ .../mod_sms_flowroute/mod_sms_flowroute.h | 93 +++ 9 files changed, 836 insertions(+), 1 deletion(-) create mode 100644 conf/vanilla/autoload_configs/sms_flowroute.conf.xml create mode 100644 src/mod/applications/mod_sms_flowroute/Makefile.am create mode 100644 src/mod/applications/mod_sms_flowroute/TODO.txt create mode 100644 src/mod/applications/mod_sms_flowroute/mod_sms_flowroute.c create mode 100644 src/mod/applications/mod_sms_flowroute/mod_sms_flowroute.h diff --git a/build/modules.conf.in b/build/modules.conf.in index 9c1a6d4ac0..a3ee343f05 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -40,6 +40,7 @@ applications/mod_httapi #applications/mod_redis #applications/mod_rss applications/mod_sms +#applications/mod_sms_flowroute #applications/mod_snapshot #applications/mod_snom #applications/mod_sonar diff --git a/conf/vanilla/autoload_configs/modules.conf.xml b/conf/vanilla/autoload_configs/modules.conf.xml index c850d7365f..ded3f54557 100644 --- a/conf/vanilla/autoload_configs/modules.conf.xml +++ b/conf/vanilla/autoload_configs/modules.conf.xml @@ -71,6 +71,7 @@ + diff --git a/conf/vanilla/autoload_configs/sms_flowroute.conf.xml b/conf/vanilla/autoload_configs/sms_flowroute.conf.xml new file mode 100644 index 0000000000..43d1c3eb06 --- /dev/null +++ b/conf/vanilla/autoload_configs/sms_flowroute.conf.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/conf/vanilla/chatplan/default.xml b/conf/vanilla/chatplan/default.xml index b67bb638fa..22d34da552 100644 --- a/conf/vanilla/chatplan/default.xml +++ b/conf/vanilla/chatplan/default.xml @@ -6,7 +6,7 @@ - + diff --git a/configure.ac b/configure.ac index 0a3702cb46..44857cbde4 100644 --- a/configure.ac +++ b/configure.ac @@ -1413,6 +1413,18 @@ PKG_CHECK_MODULES([AMQP], [librabbitmq >= 0.5.2],[ AM_CONDITIONAL([HAVE_AMQP],[true])],[ AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_AMQP],[false])]) +PKG_CHECK_MODULES([H2O], [libh2o-evloop >= 0.11.0],[ + AM_CONDITIONAL([HAVE_H2O],[true])],[ + AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_H2O],[false])]) + +PKG_CHECK_MODULES([BROTLIENC], [libbrotlienc >= 0.1.0],[ + AM_CONDITIONAL([HAVE_BROTLIENC],[true])],[ + AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_BROTLIENC],[false])]) + +PKG_CHECK_MODULES([BROTLIDEC], [libbrotlidec >= 0.1.0],[ + AM_CONDITIONAL([HAVE_BROTLIDEC],[true])],[ + AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_BROTLIDEC],[false])]) + PKG_CHECK_MODULES([TAP], [tap >= 0.1.0],[ AM_CONDITIONAL([HAVE_TAP],[true])],[ AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_TAP],[false])]) @@ -1746,6 +1758,7 @@ AC_CONFIG_FILES([Makefile src/mod/applications/mod_rss/Makefile src/mod/applications/mod_skel/Makefile src/mod/applications/mod_sms/Makefile + src/mod/applications/mod_sms_flowroute/Makefile src/mod/applications/mod_snapshot/Makefile src/mod/applications/mod_snom/Makefile src/mod/applications/mod_sonar/Makefile diff --git a/src/mod/applications/mod_sms_flowroute/Makefile.am b/src/mod/applications/mod_sms_flowroute/Makefile.am new file mode 100644 index 0000000000..ed5eb0f506 --- /dev/null +++ b/src/mod/applications/mod_sms_flowroute/Makefile.am @@ -0,0 +1,17 @@ +include $(top_srcdir)/build/modmake.rulesam +MODNAME=mod_sms_flowroute + +if HAVE_H2O + +mod_LTLIBRARIES = mod_sms_flowroute.la +mod_sms_flowroute_la_SOURCES = mod_sms_flowroute.c +mod_sms_flowroute_la_CFLAGS = $(AM_CFLAGS) $(H2O_CFLAGS) $(BROTLIENC_CFLAGS) $(BROTLIDEC_CFLAGS) +mod_sms_flowroute_la_LIBADD = $(switch_builddir)/libfreeswitch.la +mod_sms_flowroute_la_LDFLAGS = -avoid-version -module -no-undefined -shared $(H2O_LIBS) $(BROTLIENC_LIBS) $(BROTLIDEC_LIBS) $(SWITCH_AM_LDFLAGS) + +else +install: error +all: error +error: + $(error You must install libh2o and libh2o-dev to build this module) +endif diff --git a/src/mod/applications/mod_sms_flowroute/TODO.txt b/src/mod/applications/mod_sms_flowroute/TODO.txt new file mode 100644 index 0000000000..123737e10e --- /dev/null +++ b/src/mod/applications/mod_sms_flowroute/TODO.txt @@ -0,0 +1,30 @@ + + + + + +For inbound, these are known leaks on per module load(not per message). These will likely require additions to libh2o to add a destroy function. + +================================================================= +==4164==ERROR: LeakSanitizer: detected memory leaks + +Direct leak of 1104 byte(s) in 26 object(s) allocated from: + #0 0x4c1e28 in __interceptor_malloc (/usr/local/freeswitch_sms_flowroute/bin/freeswitch+0x4c1e28) + #1 0x7f868d71acbd in wcsdup /build/glibc-h_iKOs/glibc-2.19/wcsmbs/wcsdup.c:30 + +Direct leak of 184 byte(s) in 1 object(s) allocated from: + #0 0x4c1e28 in __interceptor_malloc (/usr/local/freeswitch_sms_flowroute/bin/freeswitch+0x4c1e28) + #1 0x7f867cdcbaee in h2o_mem_alloc /usr/src/h2o/include/h2o/memory.h:298 + #2 0x7f867cdcbaee in create_socket /usr/src/h2o/lib/common/socket/evloop.c.h:361 + +Indirect leak of 184 byte(s) in 1 object(s) allocated from: + #0 0x4c1e28 in __interceptor_malloc (/usr/local/freeswitch_sms_flowroute/bin/freeswitch+0x4c1e28) + #1 0x7f867cdcbaee in h2o_mem_alloc /usr/src/h2o/include/h2o/memory.h:298 + #2 0x7f867cdcbaee in create_socket /usr/src/h2o/lib/common/socket/evloop.c.h:361 + +Indirect leak of 88 byte(s) in 1 object(s) allocated from: + #0 0x4c1e28 in __interceptor_malloc (/usr/local/freeswitch_sms_flowroute/bin/freeswitch+0x4c1e28) + #1 0x7f867cdc9e12 in h2o_mem_alloc /usr/src/h2o/include/h2o/memory.h:298 + #2 0x7f867cdc9e12 in h2o_multithread_create_queue /usr/src/h2o/lib/common/multithread.c:106 + +SUMMARY: AddressSanitizer: 1560 byte(s) leaked in 29 allocation(s). diff --git a/src/mod/applications/mod_sms_flowroute/mod_sms_flowroute.c b/src/mod/applications/mod_sms_flowroute/mod_sms_flowroute.c new file mode 100644 index 0000000000..19dbfe8b02 --- /dev/null +++ b/src/mod/applications/mod_sms_flowroute/mod_sms_flowroute.c @@ -0,0 +1,667 @@ +/* +* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application +* Copyright (C) 2005-2015, 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): +* +* William King +* +* mod_sms_flowroute.c SMS support for Flowroute SMS +* +*/ + +#include "mod_sms_flowroute.h" + +SWITCH_MODULE_LOAD_FUNCTION(mod_sms_flowroute_load); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sms_flowroute_shutdown); +SWITCH_MODULE_DEFINITION(mod_sms_flowroute, mod_sms_flowroute_load, mod_sms_flowroute_shutdown, NULL); + +mod_sms_flowroute_globals_t mod_sms_flowroute_globals; + +static void on_accept(h2o_socket_t *listener, const char *error) +{ + mod_sms_flowroute_profile_t *profile = listener->data; + h2o_socket_t *sock = NULL; + + if ( error != NULL ){ + return; + } + + if ((sock = h2o_evloop_socket_accept(listener)) == NULL) { + return; + } + + h2o_accept(profile->h2o_accept_context, sock); +} + +static void mod_sms_flowroute_profile_event_thread_on_timeout(h2o_timeout_entry_t *entry) +{ + /* required to have this callback, to enable any per interval checks or cleanup. */ +} + +static void *SWITCH_THREAD_FUNC mod_sms_flowroute_profile_event_thread(switch_thread_t *thread, void *obj) +{ + mod_sms_flowroute_profile_t *profile = obj; + struct sockaddr_in addr; + int fd, reuseaddr_flag = 1, err = 0; + h2o_socket_t *sock; + h2o_timeout_t timeout = {0}; + h2o_timeout_entry_t timeout_entry = {0}; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(profile->port); + + err = (fd = socket(AF_INET, SOCK_STREAM, 0)); + if (err == -1 ) { + fprintf(stderr, "unable to open socket [%d]\n", err); + return 0; + } + + err = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_flag, sizeof(reuseaddr_flag)); + if (err != 0) { + fprintf(stderr, "Unable to set socket options [%d]\n", err); + return 0; + } + + err = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (err != 0 ) { + fprintf(stderr, "Unable to bind to socket [%d]\n", err); + perror("bind"); + return 0; + } + + err = listen(fd, SOMAXCONN); + if ( err != 0) { + fprintf(stderr, "Unable to listen on socket [%d]\n", err); + return 0; + } + + sock = h2o_evloop_socket_create(profile->h2o_context.loop, fd, H2O_SOCKET_FLAG_DONT_READ); + sock->data = (void *) profile; + h2o_socket_read_start(sock, on_accept); + + while ( profile->running ) { + // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Profile[%s] event thread loop\n", profile->name); + h2o_timeout_init(profile->h2o_context.loop, &timeout, 1000); /* 1 second loop */ + timeout_entry.cb = mod_sms_flowroute_profile_event_thread_on_timeout; + h2o_timeout_link(profile->h2o_context.loop, &timeout, &timeout_entry); + + h2o_evloop_run(profile->h2o_context.loop); + + h2o_timeout_unlink(&timeout_entry); + h2o_timeout_dispose(profile->h2o_context.loop, &timeout); + } + h2o_socket_close(sock); + return 0; +} + +switch_status_t mod_sms_flowroute_profile_destroy(mod_sms_flowroute_profile_t **old_profile) +{ + mod_sms_flowroute_profile_t *profile = NULL; + switch_status_t status; + + if ( !old_profile || !*old_profile ) { + return SWITCH_STATUS_SUCCESS; + } + + profile = *old_profile; + + switch_core_hash_delete(mod_sms_flowroute_globals.profile_hash, profile->name); + + profile->running = 0; + + if (profile->profile_thread) { + switch_thread_join(&status, profile->profile_thread); + } + + switch_safe_free(profile->h2o_accept_context); + switch_safe_free(profile->h2o_context.loop); + h2o_context_dispose(&(profile->h2o_context)); + h2o_config_dispose(&(profile->h2o_globalconf)); + + switch_core_destroy_memory_pool(&(profile->pool)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Profile[%s] destroyed\n", profile->name); + + *old_profile = NULL; + return SWITCH_STATUS_SUCCESS; +} + +static int mod_sms_flowroute_profile_request_handler(h2o_handler_t *handler, h2o_req_t *request) +{ + static h2o_generator_t generator = {NULL, NULL}; + h2o_iovec_t body = h2o_strdup(&request->pool, "ACCEPTED\n", SIZE_MAX); + char *content = strndup(request->entity.base, request->entity.len); + cJSON *parsed = NULL; + switch_event_t *evt = NULL; + + /* If there were a better way to cJSON_Parse, but with a str and len, this could remove a strndup */ + parsed = cJSON_Parse(content); + + if ( !parsed ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Invalid request received[%.*s]", (int) request->entity.len, request->entity.base); + goto done; + } + + switch_event_create(&evt, SWITCH_EVENT_MESSAGE); + switch_event_add_header_string(evt, SWITCH_STACK_BOTTOM, "to", cJSON_GetObjectCstr(parsed, "to")); + switch_event_add_header_string(evt, SWITCH_STACK_BOTTOM, "body", cJSON_GetObjectCstr(parsed, "body")); + switch_event_add_header_string(evt, SWITCH_STACK_BOTTOM, "from", cJSON_GetObjectCstr(parsed, "from")); + switch_event_add_header_string(evt, SWITCH_STACK_BOTTOM, "record_id", cJSON_GetObjectCstr(parsed, "id")); + switch_event_add_header_string(evt, SWITCH_STACK_BOTTOM, "context", "default"); + switch_event_add_header_string(evt, SWITCH_STACK_BOTTOM, "proto", "sms_flowroute"); + + switch_core_chat_send("GLOBAL_SMS", evt); + switch_event_destroy(&evt); + + request->res.status = 200; + request->res.reason = "OK"; + h2o_add_header(&request->pool, &request->res.headers, H2O_TOKEN_CONTENT_TYPE, H2O_STRLIT("text/plain; charset=utf-8")); + h2o_start_response(request, &generator); + h2o_send(request, &body, 1, 1); + + done: + + cJSON_Delete(parsed); + switch_safe_free(content); + return 0; +} + +switch_status_t mod_sms_flowroute_profile_create(mod_sms_flowroute_profile_t **new_profile, char *name, int debug, int port, + char *access_key, char *secret_key, char *host) +{ + mod_sms_flowroute_profile_t *profile = NULL; + switch_memory_pool_t *pool = NULL; + switch_threadattr_t *thd_attr; + char auth[256] = {0}; + unsigned int auth_size = 0; + + switch_core_new_memory_pool(&pool); + + profile = switch_core_alloc(pool, sizeof(mod_sms_flowroute_profile_t)); + + profile->pool = pool; + profile->debug = debug; + profile->running = 1; + profile->name = name ? switch_core_strdup(profile->pool, name) : "default"; + profile->access_key = access_key ? switch_core_strdup(profile->pool, access_key) : "access_key"; + profile->secret_key = secret_key ? switch_core_strdup(profile->pool, secret_key) : "secret_key"; + profile->host = host ? switch_core_strdup(profile->pool, host) : "https://api.flowroute.com/v2/messages"; + profile->port = port ? port : 8000; + + auth_size = snprintf(auth, 256, "%s:%s", profile->access_key, profile->secret_key); + switch_b64_encode((unsigned char *)auth, auth_size, profile->auth_b64, 512); + profile->auth_b64_size = strlen((const char *)profile->auth_b64); + + if ( h2o_url_parse(profile->host, SIZE_MAX, &profile->url_parsed) != 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Profile[%s] error processing url[%s]\n", profile->name, profile->host); + goto err; + } + + h2o_config_init(&(profile->h2o_globalconf)); + profile->h2o_hostconf = h2o_config_register_host(&(profile->h2o_globalconf), h2o_iovec_init(H2O_STRLIT("mod_sms_flowroute")), 2048); + + /* Register h2o handlers here */ + profile->h2o_pathconf = h2o_config_register_path(profile->h2o_hostconf, "/", 0); + profile->h2o_handler = h2o_create_handler(profile->h2o_pathconf, sizeof(h2o_handler_t)); + profile->h2o_handler->on_req = mod_sms_flowroute_profile_request_handler; + + h2o_context_init(&(profile->h2o_context), h2o_evloop_create(), &(profile->h2o_globalconf)); + + profile->queue = h2o_multithread_create_queue(profile->h2o_context.loop); + + profile->h2o_accept_context = calloc(1, sizeof(h2o_accept_ctx_t)); + profile->h2o_accept_context->ctx = &(profile->h2o_context); + profile->h2o_accept_context->hosts = profile->h2o_globalconf.hosts; + + switch_threadattr_create(&thd_attr, pool); + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_thread_create(&(profile->profile_thread), thd_attr, mod_sms_flowroute_profile_event_thread, (void *) profile, pool); + + switch_core_hash_insert(mod_sms_flowroute_globals.profile_hash, name, (void *) profile); + *new_profile = profile; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Profile[%s] created\n", profile->name); + + return SWITCH_STATUS_SUCCESS; + + err: + return SWITCH_STATUS_GENERR; +} + + +static int on_body(h2o_http1client_t *client, const char *errstr) +{ + h2o_http1client_ctx_t *ctx = client->ctx; + mod_sms_flowroute_message_t *msg = H2O_STRUCT_FROM_MEMBER(mod_sms_flowroute_message_t, ctx, ctx); + + if (errstr != NULL && errstr != h2o_http1client_error_is_eos) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SMS Send error on_body[%s]\n", errstr); + goto err; + } + + fwrite(client->sock->input->bytes, 1, client->sock->input->size, stdout); + h2o_buffer_consume(&client->sock->input, client->sock->input->size); + + if (errstr == h2o_http1client_error_is_eos) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "SMS Send EOS\n"); + } + + msg->status = 0; + switch_mutex_unlock(msg->mutex); + return 0; + + err: + msg->status = 3; + switch_mutex_unlock(msg->mutex); + return -1; +} + +static h2o_http1client_body_cb on_head(h2o_http1client_t *client, const char *errstr, int minor_version, int status, h2o_iovec_t msg_iovec, + h2o_http1client_header_t *headers, size_t num_headers) +{ + size_t i; + switch_log_level_t loglevel = SWITCH_LOG_DEBUG; + h2o_http1client_ctx_t *ctx = client->ctx; + mod_sms_flowroute_message_t *msg = H2O_STRUCT_FROM_MEMBER(mod_sms_flowroute_message_t, ctx, ctx); + + if (errstr != NULL && errstr != h2o_http1client_error_is_eos) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SMS Send error on_head[%s]\n", errstr); + goto err; + } + + if ( status != 200 ) { + loglevel = SWITCH_LOG_ERROR; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, loglevel, "HTTP/1.%d %d %.*s\n", minor_version, status, (int)msg_iovec.len, msg_iovec.base); + for (i = 0; i != num_headers; ++i) { + switch_log_printf(SWITCH_CHANNEL_LOG, loglevel, "%.*s: %.*s\n", + (int)headers[i].name_len, headers[i].name, (int)headers[i].value_len, headers[i].value); + } + + if (errstr == h2o_http1client_error_is_eos) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SMS Send error on_head no body received[%s]\n", errstr); + goto err; + } + + return on_body; + + err: + msg->status = 2; + switch_mutex_unlock(msg->mutex); + return NULL; +} + +static h2o_http1client_head_cb on_connect(h2o_http1client_t *client, const char *errstr, h2o_iovec_t **reqbufs, size_t *reqbufcnt, + int *method_is_head) +{ + h2o_http1client_ctx_t *ctx = client->ctx; + mod_sms_flowroute_message_t *msg = H2O_STRUCT_FROM_MEMBER(mod_sms_flowroute_message_t, ctx, ctx); + + if (errstr != NULL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SMS Send error on_connect[%s]\n", errstr); + goto err; + } + + *reqbufs = (h2o_iovec_t *)client->data; + *reqbufcnt = 1; + *method_is_head = 0; + + return on_head; + + err: + msg->status = 1; + switch_mutex_unlock(msg->mutex); + return NULL; +} + +switch_status_t mod_sms_flowroute_profile_send_message(mod_sms_flowroute_profile_t *profile, switch_event_t *event) +{ + mod_sms_flowroute_message_t *msg = NULL; + char *to = NULL, *from = NULL, *text = NULL; + switch_status_t status = SWITCH_STATUS_GENERR; + int wait_loops = 10; /* 10 seconds */ + cJSON *body = NULL; + + msg = calloc(1, sizeof(mod_sms_flowroute_message_t)); + msg->req.base = calloc(1, 2048); + msg->ctx.getaddr_receiver = &msg->getaddr_receiver; + msg->ctx.io_timeout = &msg->io_timeout; + msg->ctx.loop = profile->h2o_context.loop; + msg->profile = profile; + msg->status = -1; + h2o_timeout_init(msg->ctx.loop, &msg->io_timeout, 5000); /* 5 seconds */ + h2o_multithread_register_receiver(profile->queue, msg->ctx.getaddr_receiver, h2o_hostinfo_getaddr_receiver); + + msg->ctx.ssl_ctx = SSL_CTX_new(TLSv1_2_client_method()); + SSL_CTX_load_verify_locations(msg->ctx.ssl_ctx, NULL, "/etc/ssl/certs/"); + SSL_CTX_set_verify(msg->ctx.ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); + + switch_mutex_init(&msg->mutex, SWITCH_MUTEX_UNNESTED, profile->pool); + switch_mutex_lock(msg->mutex); + + body = cJSON_CreateObject(); + + to = switch_event_get_header(event, "to"); + if ( !to ) { + to = switch_event_get_header(event, "destination_addr"); + } + + from = switch_event_get_header(event, "from"); + if ( !from ) { + from = switch_event_get_header(event, "source_addr"); + } + + cJSON_AddItemToObject(body, "to", cJSON_CreateString(to)); + cJSON_AddItemToObject(body, "from", cJSON_CreateString(from)); + cJSON_AddItemToObject(body, "body", cJSON_CreateString((const char *) switch_event_get_body(event))); + + text = cJSON_Print(body); + cJSON_Delete(body); + + msg->req.len = snprintf(msg->req.base, 2048, "POST %.*s HTTP/1.1\r\n" + "Authorization: Basic %.*s\r\n" + "Host: %.*s\r\n" + "Accept: */*\r\n" + "Content-Type: application/json\r\n" + "Content-Length: %d\r\n" + "\r\n%s", + (int) profile->url_parsed.path.len, profile->url_parsed.path.base, + profile->auth_b64_size, profile->auth_b64, + (int) profile->url_parsed.authority.len, profile->url_parsed.authority.base, + (int)strlen(text), text); + + if ( profile->debug ) { + char *msg_txt = NULL; + switch_event_serialize(event, &msg_txt, SWITCH_FALSE); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Profile[%s] sending message from event\n%s\n", profile->name, msg_txt); + switch_safe_free(msg_txt); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Profile[%s] sending message json:\n%s\n", profile->name, text); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "REQUEST\n\n%.*s\n\n", (int) msg->req.len, msg->req.base); + } + + h2o_http1client_connect(NULL, &msg->req, &(msg->ctx), profile->url_parsed.host, h2o_url_get_port(&profile->url_parsed), 1, on_connect); + + do { + switch_yield(1000000); + wait_loops--; + status = switch_mutex_trylock(msg->mutex); + } while ( wait_loops > 0 && status != SWITCH_STATUS_SUCCESS); + + if ( status != SWITCH_STATUS_SUCCESS ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile[%s] send_message thread timed out on send\n", profile->name); + goto err; + } + + if ( msg->status > 0 ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile[%s] send_message resulted in failure status %d\n", profile->name, msg->status); + goto err; + } + + switch_mutex_destroy(msg->mutex); + switch_safe_free(msg->req.base); + switch_safe_free(msg); + return SWITCH_STATUS_SUCCESS; + + err: + if ( msg && msg->mutex ) { + switch_mutex_destroy(msg->mutex); + } + switch_safe_free(msg->req.base); + switch_safe_free(msg); + return SWITCH_STATUS_GENERR; +} + +switch_status_t mod_sms_flowroute_interface_chat_send(switch_event_t *event) +{ + mod_sms_flowroute_profile_t *profile = NULL; + char *profile_name = switch_event_get_header(event, "sms_flowroute_profile"); + + if (zstr(profile_name)) { + profile_name = "default"; + } + + profile = switch_core_hash_find(mod_sms_flowroute_globals.profile_hash, profile_name); + + if (!profile) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "NO SUCH SMS_FLOWROUTE PROFILE[%s].", profile_name); + return SWITCH_STATUS_GENERR; + } + + mod_sms_flowroute_profile_send_message(profile, event); + + return SWITCH_STATUS_SUCCESS; +} + +/* static switch_status_t name (switch_event_t *message, const char *data) */ +SWITCH_STANDARD_CHAT_APP(mod_sms_flowroute_chat_send_function) +{ + mod_sms_flowroute_profile_t *profile = NULL; + + profile = switch_core_hash_find(mod_sms_flowroute_globals.profile_hash, data); + + if ( !profile ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "NO SUCH SMS_FLOWROUTE PROFILE[%s].", data); + return SWITCH_STATUS_GENERR; + } + + mod_sms_flowroute_profile_send_message(profile, message); + return SWITCH_STATUS_SUCCESS; +} + +/* static void name (switch_core_session_t *session, const char *data) */ +SWITCH_STANDARD_APP(mod_sms_flowroute_app_send_function) +{ + switch_event_header_t *chan_var = NULL; + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_event_t *message = NULL; + + if (switch_event_create(&message, SWITCH_EVENT_MESSAGE) != SWITCH_STATUS_SUCCESS) { + return; + } + + /* Copy over recognized channel vars. Then call the chat send function */ + /* Cycle through all of the channel headers, and ones with 'sms_flowroute_' prefix copy over without the prefix */ + for ( chan_var = switch_channel_variable_first(channel); chan_var; chan_var = chan_var->next) { + if ( !strncmp(chan_var->name, "sms_flowroute_", 14) ) { + switch_event_add_header_string(message, SWITCH_STACK_BOTTOM, chan_var->name + 14, chan_var->value); + } + } + + /* Unlock the channel variables */ + switch_channel_variable_last(channel); + mod_sms_flowroute_chat_send_function(message, data); + return; +} + +/* static switch_status_t name (_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream) */ +SWITCH_STANDARD_API(mod_sms_flowroute_debug_api) +{ + mod_sms_flowroute_globals.debug = switch_true(cmd); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "debug is %s\n", (mod_sms_flowroute_globals.debug ? "on" : "off") ); + return SWITCH_STATUS_SUCCESS; +} + +/* static switch_status_t name (_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream) */ +SWITCH_STANDARD_API(mod_sms_flowroute_send_api) +{ + mod_sms_flowroute_profile_t *profile = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_event_t *message = NULL; + char *argv[1024] = { 0 }; + int argc = 0; + char *cmd_dup = strdup(cmd); + + if (!(argc = switch_separate_string(cmd_dup, '|', argv, (sizeof(argv) / sizeof(argv[0])))) || argc != 4 ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid format. Must be | separated like: profile|destination|source|message\n"); + switch_goto_status(SWITCH_STATUS_GENERR, done); + } + + profile = switch_core_hash_find(mod_sms_flowroute_globals.profile_hash, argv[0]); + + if ( !profile ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "NO SUCH SMS_FLOWROUTE PROFILE[%s].", argv[0]); + switch_goto_status(SWITCH_STATUS_GENERR, done); + } + + if (switch_event_create(&message, SWITCH_EVENT_MESSAGE) != SWITCH_STATUS_SUCCESS) { + switch_goto_status(SWITCH_STATUS_GENERR, done); + } + + switch_event_add_header_string(message, SWITCH_STACK_BOTTOM, "destination_addr", argv[1]); + switch_event_add_header_string(message, SWITCH_STACK_BOTTOM, "source_addr", argv[2]); + switch_event_set_body(message, argv[3]); + + if (mod_sms_flowroute_profile_send_message(profile, message) != SWITCH_STATUS_SUCCESS) { + switch_goto_status(SWITCH_STATUS_GENERR, done); + } + + done: + switch_safe_free(cmd_dup); + return status; + +} + +switch_status_t mod_sms_flowroute_do_config() +{ + char *conf = "sms_flowroute.conf"; + switch_xml_t xml, cfg, profiles, profile, params, param; + + if (!(xml = switch_xml_open_cfg(conf, &cfg, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", conf); + goto err; + } + + if ( (profiles = switch_xml_child(cfg, "profiles")) != NULL) { + for (profile = switch_xml_child(profiles, "profile"); profile; profile = profile->next) { + mod_sms_flowroute_profile_t *new_profile = NULL; + int debug = 0, port = 0; + char *access_key = NULL, *secret_key = NULL, *host = NULL; + char *name = (char *)switch_xml_attr_soft(profile, "name"); + + // Load params + if ( (params = switch_xml_child(profile, "params")) != NULL) { + for (param = switch_xml_child(params, "param"); param; param = param->next) { + char *var = (char *) switch_xml_attr_soft(param, "name"); + + if ( ! strncmp(var, "debug", 5) ) { + debug = atoi(switch_xml_attr_soft(param, "value")); + } else if ( ! strncmp(var, "port", 4) ) { + port = atoi(switch_xml_attr_soft(param, "value")); + } else if ( ! strncmp(var, "access-key", 10) ) { + access_key = (char *) switch_xml_attr_soft(param, "value"); + } else if ( ! strncmp(var, "secret-key", 10) ) { + secret_key = (char *) switch_xml_attr_soft(param, "value"); + } else if ( ! strncmp(var, "host", 4) ) { + host = (char *) switch_xml_attr_soft(param, "value"); + } + } + } + + if ( mod_sms_flowroute_profile_create(&new_profile, name, debug, port, access_key, secret_key, host) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created profile[%s]\n", name); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create profile[%s]\n", name); + } + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profiles config is missing\n"); + goto err; + } + + switch_xml_free(xml); + return SWITCH_STATUS_SUCCESS; + + err: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Configuration failed\n"); + if(xml){ + switch_xml_free(xml); + } + return SWITCH_STATUS_GENERR; +} + +/* switch_status_t name (switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */ +SWITCH_MODULE_LOAD_FUNCTION(mod_sms_flowroute_load) +{ + switch_api_interface_t *mod_sms_flowroute_api_interface; + switch_chat_interface_t *mod_sms_flowroute_chat_interface; + switch_chat_application_interface_t *mod_sms_flowroute_chat_app_interface; + switch_application_interface_t *mod_sms_flowroute_app_interface; + + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + memset(&mod_sms_flowroute_globals, 0, sizeof(mod_sms_flowroute_globals_t)); + mod_sms_flowroute_globals.pool = pool; + mod_sms_flowroute_globals.debug = 0; + switch_core_hash_init(&(mod_sms_flowroute_globals.profile_hash)); + + if ( mod_sms_flowroute_do_config() != SWITCH_STATUS_SUCCESS ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load due to bad configs\n"); + return SWITCH_STATUS_TERM; + } + + /* SSL_load_error_strings(); + SSL_library_init(); + OpenSSL_add_all_algorithms();*/ + + + SWITCH_ADD_CHAT(mod_sms_flowroute_chat_interface, "sms_flowroute", mod_sms_flowroute_interface_chat_send); + SWITCH_ADD_API(mod_sms_flowroute_api_interface, "sms_flowroute_send", "mod_sms_flowroute send", mod_sms_flowroute_send_api, NULL); + SWITCH_ADD_API(mod_sms_flowroute_api_interface, "sms_flowroute_debug", "mod_sms_flowroute toggle debug", mod_sms_flowroute_debug_api, NULL); + SWITCH_ADD_CHAT_APP(mod_sms_flowroute_chat_app_interface, "sms_flowroute_send", "send message to profile", "send message to profile", + mod_sms_flowroute_chat_send_function, "", SCAF_NONE); + SWITCH_ADD_APP(mod_sms_flowroute_app_interface, "sms_flowroute_send", NULL, NULL, mod_sms_flowroute_app_send_function, + "sms_flowroute_send", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC); + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sms_flowroute_shutdown) +{ + switch_hash_index_t *hi; + mod_sms_flowroute_profile_t *profile = NULL; + + while ((hi = switch_core_hash_first(mod_sms_flowroute_globals.profile_hash))) { + switch_core_hash_this(hi, NULL, NULL, (void **)&profile); + mod_sms_flowroute_profile_destroy(&profile); + switch_safe_free(hi); + } + + switch_core_hash_destroy(&(mod_sms_flowroute_globals.profile_hash)); + + 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 noet: + */ diff --git a/src/mod/applications/mod_sms_flowroute/mod_sms_flowroute.h b/src/mod/applications/mod_sms_flowroute/mod_sms_flowroute.h new file mode 100644 index 0000000000..1816c7a8fb --- /dev/null +++ b/src/mod/applications/mod_sms_flowroute/mod_sms_flowroute.h @@ -0,0 +1,93 @@ +/* +* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application +* Copyright (C) 2005-2012, 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. +* +* Based on mod_skel by +* Anthony Minessale II +* +* Contributor(s): +* +* William King +* +* mod_sms_flowroute.c SMS support for Flowroute SMS +* +*/ + +#ifndef MOD_SMS_FLOWROUTE_H +#define MOD_SMS_FLOWROUTE_H + +#define H2O_USE_LIBUV 0 +#define H2O_USE_BROTLI 1 + +#include +#include "h2o.h" +#include "h2o/http1client.h" + +typedef struct { + char *name; + int port; + int debug; + int running; + char *host; + + char *access_key; + char *secret_key; + + unsigned char auth_b64[512]; + int auth_b64_size; + + h2o_url_t url_parsed; + h2o_socketpool_t *sockpool; + + h2o_globalconf_t h2o_globalconf; + h2o_hostconf_t *h2o_hostconf; + h2o_pathconf_t *h2o_pathconf; + h2o_handler_t *h2o_handler; + h2o_context_t h2o_context; + h2o_accept_ctx_t *h2o_accept_context; + h2o_multithread_queue_t *queue; + + switch_thread_t *profile_thread; + switch_memory_pool_t *pool; +} mod_sms_flowroute_profile_t; + +typedef struct { + h2o_http1client_ctx_t ctx; + mod_sms_flowroute_profile_t *profile; + switch_mutex_t *mutex; + h2o_iovec_t req; + int status; + h2o_multithread_receiver_t getaddr_receiver; + h2o_timeout_t io_timeout; +} mod_sms_flowroute_message_t; + +typedef struct mod_sms_flowroute_globals_s { + switch_memory_pool_t *pool; + switch_hash_t *profile_hash; + int debug; +} mod_sms_flowroute_globals_t; + +extern mod_sms_flowroute_globals_t mod_sms_flowroute_globals; + + +#endif /* MOD_SMS_FLOWROUTE_H */ + From 5d39170ccd1d002165402556f62182d5cd41f0fa Mon Sep 17 00:00:00 2001 From: William King Date: Thu, 7 Jul 2016 15:35:24 -0700 Subject: [PATCH 042/128] FS-9310 Part two. Properly destroy the timeout struct after the message has sent, or timed out. --- src/mod/applications/mod_sms_flowroute/mod_sms_flowroute.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/applications/mod_sms_flowroute/mod_sms_flowroute.c b/src/mod/applications/mod_sms_flowroute/mod_sms_flowroute.c index 19dbfe8b02..3d7d42484b 100644 --- a/src/mod/applications/mod_sms_flowroute/mod_sms_flowroute.c +++ b/src/mod/applications/mod_sms_flowroute/mod_sms_flowroute.c @@ -418,6 +418,7 @@ switch_status_t mod_sms_flowroute_profile_send_message(mod_sms_flowroute_profile goto err; } + h2o_timeout_dispose(msg->ctx.loop, msg->ctx.io_timeout); switch_mutex_destroy(msg->mutex); switch_safe_free(msg->req.base); switch_safe_free(msg); @@ -427,6 +428,7 @@ switch_status_t mod_sms_flowroute_profile_send_message(mod_sms_flowroute_profile if ( msg && msg->mutex ) { switch_mutex_destroy(msg->mutex); } + h2o_timeout_dispose(msg->ctx.loop, msg->ctx.io_timeout); switch_safe_free(msg->req.base); switch_safe_free(msg); return SWITCH_STATUS_GENERR; From a0b9b60dbcda1f15e5cd225d5493505bb3eb3dc9 Mon Sep 17 00:00:00 2001 From: William King Date: Thu, 7 Jul 2016 16:06:34 -0700 Subject: [PATCH 043/128] FS-9310 Fix RPM build due to new config file. Also add libvpx generated file to .gitignore --- freeswitch.spec | 1 + libs/libvpx/.gitignore | 1 + 2 files changed, 2 insertions(+) diff --git a/freeswitch.spec b/freeswitch.spec index 15a5d2d715..b436532214 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -1935,6 +1935,7 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/shout.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/skinny.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/smpp.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/sms_flowroute.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/sofia.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/spandsp.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/switch.conf.xml diff --git a/libs/libvpx/.gitignore b/libs/libvpx/.gitignore index 9fed8d5b67..96e97c06af 100644 --- a/libs/libvpx/.gitignore +++ b/libs/libvpx/.gitignore @@ -4,6 +4,7 @@ Makefile config.mk libs-*.mk +libs.doxy vp8_rtcd.h vp9_rtcd.h vpx_config.asm From 0379c2a60f7579070cb85926374c383e496ed972 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 7 Jul 2016 22:50:20 -0500 Subject: [PATCH 044/128] FS-9334 #resolve [Jitterbuffer mods] --- src/switch_jitterbuffer.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/switch_jitterbuffer.c b/src/switch_jitterbuffer.c index 427498a5d2..917dcf8964 100644 --- a/src/switch_jitterbuffer.c +++ b/src/switch_jitterbuffer.c @@ -614,18 +614,21 @@ static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch if (jb->type == SJB_VIDEO) { if (jb->write_init && ((htons(packet->header.seq) >= htons(jb->highest_wrote_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_wrote_ts))) || (ntohl(jb->highest_wrote_ts) > (UINT_MAX - 1000) && ntohl(node->packet.header.ts) < 1000))) { - jb->complete_frames++; - jb_debug(jb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); jb->highest_wrote_ts = packet->header.ts; //verify_oldest_frame(jb); } else if (!jb->write_init) { jb->highest_wrote_ts = packet->header.ts; } + + jb->complete_frames++; + jb_debug(jb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); + } else { - if (jb->write_init) { - jb_debug(jb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); - jb->complete_frames++; - } else { + + jb_debug(jb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); + jb->complete_frames++; + + if (!jb->write_init) { jb->highest_wrote_ts = packet->header.ts; } } @@ -1269,10 +1272,12 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp (ntohs(jb->highest_read_seq) > USHRT_MAX - 10 && ntohs(node->packet.header.seq) <= 10) ) { jb->highest_read_seq = node->packet.header.seq; } + + jb->complete_frames--; + jb_debug(jb, 2, "READ frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); + if (jb->read_init && htons(node->packet.header.seq) >= htons(jb->highest_read_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_read_ts))) { - jb->complete_frames--; - jb_debug(jb, 2, "READ frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); jb->highest_read_ts = node->packet.header.ts; } else if (!jb->read_init) { jb->highest_read_ts = node->packet.header.ts; From 6d614ac1a7a0102391e18567843d5f764c32655b Mon Sep 17 00:00:00 2001 From: Piotr Gregor Date: Fri, 8 Jul 2016 17:07:23 +0100 Subject: [PATCH 045/128] FS-9009 [mod_avmd] #fix build on Windows Windows VC doesn't accept function __attribute__(s) --- src/mod/applications/mod_avmd/avmd_amplitude.h | 5 +++++ src/mod/applications/mod_avmd/avmd_desa2.h | 6 ++++++ src/mod/applications/mod_avmd/avmd_desa2_tweaked.h | 5 +++++ src/mod/applications/mod_avmd/mod_avmd.c | 1 + 4 files changed, 17 insertions(+) diff --git a/src/mod/applications/mod_avmd/avmd_amplitude.h b/src/mod/applications/mod_avmd/avmd_amplitude.h index 13e5edadeb..0878390935 100644 --- a/src/mod/applications/mod_avmd/avmd_amplitude.h +++ b/src/mod/applications/mod_avmd/avmd_amplitude.h @@ -15,6 +15,11 @@ #include "avmd_buffer.h" +#ifdef WIN32 +#define __attribute__(x) +#endif + + double avmd_amplitude(circ_buffer_t *, size_t i, double f) __attribute__ ((nonnull(1))); diff --git a/src/mod/applications/mod_avmd/avmd_desa2.h b/src/mod/applications/mod_avmd/avmd_desa2.h index 1da9ef346e..d555df448e 100644 --- a/src/mod/applications/mod_avmd/avmd_desa2.h +++ b/src/mod/applications/mod_avmd/avmd_desa2.h @@ -15,6 +15,12 @@ #include #include "avmd_buffer.h" + +#ifdef WIN32 +#define __attribute__(x) +#endif + + /* Returns digital frequency estimation and amplitude estimation. */ extern double avmd_desa2(circ_buffer_t *b, size_t i, double *amplitude) __attribute__ ((nonnull(1,3))); diff --git a/src/mod/applications/mod_avmd/avmd_desa2_tweaked.h b/src/mod/applications/mod_avmd/avmd_desa2_tweaked.h index 997abbb84d..2d16ca2972 100644 --- a/src/mod/applications/mod_avmd/avmd_desa2_tweaked.h +++ b/src/mod/applications/mod_avmd/avmd_desa2_tweaked.h @@ -21,6 +21,11 @@ #include +#ifdef WIN32 +#define __attribute__(x) +#endif + + /* Instead of returning digital frequency estimation using * result = 0.5 * acos(n/d), * which involves expensive computation of arc cosine on diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index 5fa0bb474f..5f235260b5 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -35,6 +35,7 @@ #include #include #include + #ifdef WIN32 #include #define ISNAN(x) (!!(_isnan(x))) From d49b66c9225071693c95452f7af62fff5545c5de Mon Sep 17 00:00:00 2001 From: Piotr Gregor Date: Fri, 8 Jul 2016 17:07:23 +0100 Subject: [PATCH 046/128] FS-9009 [mod_avmd] #fix warning on Windows Initialize variance of amplitude - avoid (incorrect) warning --- src/mod/applications/mod_avmd/mod_avmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index 5f235260b5..6fb0471f90 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -1560,7 +1560,7 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) { size_t pos; double omega, amplitude; double f; - double v, v_amp; + double v, v_amp = 0.0; double sma_digital_freq; uint32_t sine_len_i; int sample_to_skip_n = s->settings.sample_n_to_skip; From aae7f06d7ac6b4e03ed605c80e8e5157a3e24963 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 8 Jul 2016 15:59:02 -0400 Subject: [PATCH 047/128] FS-9337: fix invalid sdp generated with soa disabled --- src/switch_core_media.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index c16f37a6ad..af5d3b8916 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -7422,7 +7422,7 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, } if (!zstr(a_engine->local_dtls_fingerprint.type) && secure) { - switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=fingerprint:%s %s\na=setup:%s\r\n", a_engine->local_dtls_fingerprint.type, + switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=fingerprint:%s %s\r\na=setup:%s\r\n", a_engine->local_dtls_fingerprint.type, a_engine->local_dtls_fingerprint.str, get_setup(a_engine, session, sdp_type)); } @@ -8087,7 +8087,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d telephone-event/%d\r\n", smh->mparams->te, smh->mparams->te_rate); } else { - switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d telephone-event/%d\na=fmtp:%d 0-16\r\n", + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d telephone-event/%d\r\na=fmtp:%d 0-16\r\n", smh->mparams->te, smh->mparams->te_rate, smh->mparams->te); } } @@ -8572,8 +8572,8 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (!zstr(v_engine->local_dtls_fingerprint.type)) { - switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fingerprint:%s %s\na=setup:%s\r\n", v_engine->local_dtls_fingerprint.type, - v_engine->local_dtls_fingerprint.str, get_setup(v_engine, session, sdp_type)); + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fingerprint:%s %s\r\na=setup:%s\r\n", + v_engine->local_dtls_fingerprint.type, v_engine->local_dtls_fingerprint.str, get_setup(v_engine, session, sdp_type)); } From 9e89639c4d65d38609d01e5429a1da19b2a4beb2 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 8 Jul 2016 17:00:22 -0400 Subject: [PATCH 048/128] Revert "Fix for FS-9313" This reverts commit cf6107963ca997f5ef25527d16f98626213047a9. --- src/mod/codecs/mod_opus/mod_opus.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index e5ff41e6b4..959311b58b 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -244,14 +244,11 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt if (!strcasecmp(data, "stereo")) { codec_settings->stereo = atoi(arg); - if(codec_settings->stereo) - codec_fmtp->stereo = 1; + codec_fmtp->stereo = codec_settings->stereo; } if (!strcasecmp(data, "sprop-stereo")) { codec_settings->sprop_stereo = atoi(arg); - if(codec_settings->sprop_stereo) - codec_fmtp->stereo = 1; } if (!strcasecmp(data, "maxaveragebitrate")) { @@ -632,7 +629,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag } } - context->decoder_object = opus_decoder_create(dec_samplerate, codec->implementation->number_of_channels, &err); + context->decoder_object = opus_decoder_create(dec_samplerate, (!context->codec_settings.sprop_stereo ? codec->implementation->number_of_channels : 2), &err); switch_set_flag(codec, SWITCH_CODEC_FLAG_HAS_PLC); @@ -730,7 +727,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, return SWITCH_STATUS_FALSE; } - frame_samples = *decoded_data_len / 2 / codec->implementation->number_of_channels); + frame_samples = *decoded_data_len / 2 / (!context->codec_settings.sprop_stereo ? codec->implementation->number_of_channels : 2); frame_size = frame_samples - (frame_samples % (codec->implementation->actual_samples_per_second / 400)); if (*flag & SFF_PLC) { @@ -831,7 +828,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, return SWITCH_STATUS_GENERR; } - *decoded_data_len = samples * 2 * codec->implementation->number_of_channels; + *decoded_data_len = samples * 2 * (!context->codec_settings.sprop_stereo ? codec->implementation->number_of_channels : 2); return SWITCH_STATUS_SUCCESS; } From 2a73820c34ea2ba724ad58377987ef558e0398f6 Mon Sep 17 00:00:00 2001 From: Italo Rossi Date: Mon, 11 Jul 2016 15:20:28 -0300 Subject: [PATCH 049/128] FS-9342 - [verto_communicator] Properly saving settings to localStorage when closing the settings panel. --- .../src/vertoControllers/controllers/MainController.js | 1 + 1 file changed, 1 insertion(+) diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js index 6f61816c82..a9605b56d5 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js @@ -293,6 +293,7 @@ $scope.closeSettings = function() { var settingsEl = angular.element(document.querySelector('#settings')); settingsEl.removeClass('toggled'); + $rootScope.$emit('toggledSettings', settingsEl.hasClass('toggled')); }; $scope.goFullscreen = function() { From 328146c2fdcf80dd824dccaace1cae5f5d38bdb3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 12 Jul 2016 10:54:08 -0500 Subject: [PATCH 050/128] FS-9345 #resolve [HTTAPI truncates string when response spans multiple packets] --- src/mod/applications/mod_httapi/mod_httapi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_httapi/mod_httapi.c b/src/mod/applications/mod_httapi/mod_httapi.c index 39f9051c1a..7fb8926315 100644 --- a/src/mod/applications/mod_httapi/mod_httapi.c +++ b/src/mod/applications/mod_httapi/mod_httapi.c @@ -1288,7 +1288,6 @@ static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data) { register unsigned int realsize = (unsigned int) (size * nmemb); client_t *client = data; - char *zero = "\0"; client->bytes += realsize; @@ -1299,7 +1298,6 @@ static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data) } switch_buffer_write(client->buffer, ptr, realsize); - switch_buffer_write(client->buffer, zero, 1); return realsize; } @@ -2313,6 +2311,9 @@ SWITCH_STANDARD_APP(httapi_function) const char *ct = switch_event_get_header(client->headers, "content-type"); if (switch_stristr("text/xml", ct)) { + char *zero = "\0"; + switch_buffer_write(client->buffer, zero, 1); + status = parse_xml(client); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received unsupported content-type %s\n", ct); From 0b3f776d7db2490d6dc8aee5b6db5127dfee5092 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 12 Jul 2016 15:47:08 -0500 Subject: [PATCH 051/128] FS-9343 #resolve [Sending a Message using the mod_smpp module via Nexmo Fails] --- .../mod_smpp/mod_smpp_gateway.c | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_smpp/mod_smpp_gateway.c b/src/mod/event_handlers/mod_smpp/mod_smpp_gateway.c index 1bf3771912..7125f04e0f 100644 --- a/src/mod/event_handlers/mod_smpp/mod_smpp_gateway.c +++ b/src/mod/event_handlers/mod_smpp/mod_smpp_gateway.c @@ -201,6 +201,7 @@ switch_status_t mod_smpp_gateway_connection_read(mod_smpp_gateway_t *gateway, sw switch_event_t *evt = NULL; generic_nack_t *gennack = NULL; char data[2048] = {0}; /* local buffer for unpacked PDU */ + int err = 0; /* Read from socket */ /* TODO: Add/Expand support for partial reads */ @@ -227,8 +228,7 @@ switch_status_t mod_smpp_gateway_connection_read(mod_smpp_gateway_t *gateway, sw } if ( smpp34_unpack2((void *)data, local_buffer, read_len + 4) ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "smpp: error decoding the receive buffer:%d:%s\n", smpp34_errno, smpp34_strerror); - switch_goto_status(SWITCH_STATUS_GENERR, done); + err++; } if ( mod_smpp_globals.debug || gateway->debug ) { @@ -237,6 +237,12 @@ switch_status_t mod_smpp_gateway_connection_read(mod_smpp_gateway_t *gateway, sw gennack = (generic_nack_t *) data; *command_id = gennack->command_id; + + if (err && *command_id != SUBMIT_SM_RESP) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "smpp: error decoding the receive buffer:%d:%s\n", smpp34_errno, smpp34_strerror); + switch_goto_status(SWITCH_STATUS_GENERR, done); + } + switch(*command_id) { case BIND_TRANSCEIVER_RESP: if ( gennack->command_status != ESME_ROK ) { @@ -256,6 +262,21 @@ switch_status_t mod_smpp_gateway_connection_read(mod_smpp_gateway_t *gateway, sw case ENQUIRE_LINK: case ENQUIRE_LINK_RESP: case SUBMIT_SM_RESP: + switch (gennack->command_status) { + case ESME_ROK: + //AOK + break; + case ESME_RINVSRCADR: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Source Addr ID: %u\n", *command_id); + break; + case ESME_RINVDSTADR: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Dest Addr ID: %u\n", *command_id); + break; + default: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Undocumented Error 0X%.8x ID: %u\n", gennack->command_status, *command_id); + break; + } + break; default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unrecognized Command ID: %u\n", *command_id); From 8b9cecaca2cd03dfc4b5bd349412561bdc7a9452 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Thu, 14 Jul 2016 15:38:15 -0400 Subject: [PATCH 052/128] FS-9350: add mod_av commented to modules.conf.xml --- conf/vanilla/autoload_configs/modules.conf.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/vanilla/autoload_configs/modules.conf.xml b/conf/vanilla/autoload_configs/modules.conf.xml index ded3f54557..2c465d1231 100644 --- a/conf/vanilla/autoload_configs/modules.conf.xml +++ b/conf/vanilla/autoload_configs/modules.conf.xml @@ -101,6 +101,7 @@ + From b3539224888071202c4ba9e4eed517f114ead661 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 14 Jul 2016 17:54:59 -0500 Subject: [PATCH 053/128] FS-9352 #resolve [ptime adjust issues on opus] --- src/include/switch_core_media.h | 1 + src/switch_core_media.c | 111 +++++++++----------------------- 2 files changed, 32 insertions(+), 80 deletions(-) diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 6f3b7244a0..27ab840e38 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -230,6 +230,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_choose_ports(switch_core_sessi SWITCH_DECLARE(void) switch_core_media_check_dtmf_type(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_media_absorb_sdp(switch_core_session_t *session); SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_session_t *session, const char *sdp_str); +SWITCH_DECLARE(void) switch_core_media_parse_media_flags(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_media_deactivate_rtp(switch_core_session_t *session); SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_session_t *session); SWITCH_DECLARE(switch_status_t) switch_core_media_ext_address_lookup(switch_core_session_t *session, char **ip, switch_port_t *port, const char *sourceip); diff --git a/src/switch_core_media.c b/src/switch_core_media.c index af5d3b8916..33de186fab 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -1871,82 +1871,6 @@ SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *ses } -static void adjust_jb(switch_core_session_t *session, int new_ptime_ms) -{ - const char *val; - switch_media_handle_t *smh; - switch_rtp_engine_t *a_engine = NULL; - int maxlen = 0; - int32_t jb_msec = 0 ; - int qlen, maxqlen = 50; - - switch_assert(session); - - if (!(smh = session->media_handle)) { - return; - } - - a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; - - if ((val = switch_channel_get_variable(session->channel, "jitterbuffer_msec")) || (val = smh->mparams->jb_msec)) { - char *p; - - if (!jb_msec) { - jb_msec = atoi(val); - - if (strchr(val, 'p') && jb_msec > 0) { - jb_msec *= -1; - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Will not adjust JB size, token 'p' not specified\n"); - return; - } - - if ((p = strchr(val, ':'))) { - p++; - maxlen = atoi(p); - - if (strchr(p, 'p') && maxlen > 0) { - maxlen *= -1; - } - } - } - - if (jb_msec < 0 && jb_msec > -1000) { - jb_msec = new_ptime_ms * abs(jb_msec); - } - - if (maxlen < 0 && maxlen > -1000) { - maxlen = new_ptime_ms * abs(maxlen); - } - - if (jb_msec < 10 || jb_msec > 10000) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, - "Invalid Jitterbuffer spec [%d] must be between 10 and 10000\n", jb_msec); - } else { - qlen = jb_msec / new_ptime_ms; - if (maxlen) { - maxqlen = maxlen / new_ptime_ms; - } - if (maxqlen < qlen) { - maxqlen = qlen * 5; - } - if (switch_rtp_activate_jitter_buffer(a_engine->rtp_session, qlen, maxqlen, - a_engine->read_impl.samples_per_packet, a_engine->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), - SWITCH_LOG_DEBUG, "Adjusting Jitterbuffer to %dms (%d frames) (%d max frames)\n", - jb_msec, qlen, maxqlen); - switch_channel_set_flag(session->channel, CF_JITTERBUFFER); - if (!switch_false(switch_channel_get_variable(session->channel, "rtp_jitter_buffer_plc"))) { - switch_channel_set_flag(session->channel, CF_JITTERBUFFER_PLC); - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), - SWITCH_LOG_DEBUG, "Error adjusting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen); - } - } - } -} - static void check_jb(switch_core_session_t *session, const char *input, int32_t jb_msec, int32_t maxlen, switch_bool_t silent) { const char *val; @@ -2493,6 +2417,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session if (engine->last_codec_ms && engine->last_codec_ms == codec_ms) { engine->mismatch_count++; + } else { + engine->mismatch_count = 0; } engine->last_codec_ms = codec_ms; @@ -2549,9 +2475,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session codec_ms = codec_ms / (int) (engine->read_frame.seq - engine->last_seq); } + if (codec_ms && codec_ms != engine->cur_payload_map->codec_ms) { + if (engine->last_codec_ms && engine->last_codec_ms == codec_ms) { + engine->mismatch_count++; + } + } else { + engine->mismatch_count = 0; + } + engine->last_codec_ms = codec_ms; - if (codec_ms != engine->cur_payload_map->codec_ms && codec_ms) { + if (engine->mismatch_count > MAX_MISMATCH_FRAMES) { if (codec_ms > 120) { /*will show too many times with packet loss*/ @@ -2566,14 +2500,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session if (codec_ms != engine->cur_payload_map->codec_ms) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, - "[%s]: Asynchronous PTIME supported, adjusting JB size. Remote PTIME changed from [%d] to [%d]\n", + "[%s]: Packet size change detected. Remote PTIME changed from [%d] to [%d]\n", is_vbr?"VBR":"CBR", (int) engine->cur_payload_map->codec_ms, (int) codec_ms ); engine->cur_payload_map->codec_ms = codec_ms; - /* adjust audio JB size, but do not substitute the codec */ - adjust_jb(session,codec_ms); engine->reset_codec = 2; if (switch_channel_test_flag(session->channel, CF_CONFERENCE)) { @@ -5770,6 +5702,24 @@ SWITCH_DECLARE(switch_bool_t) switch_core_session_in_video_thread(switch_core_se } +SWITCH_DECLARE(void) switch_core_media_parse_media_flags(switch_core_session_t *session) +{ + const char *var; + switch_media_handle_t *smh; + + if (!(smh = session->media_handle)) { + return; + } + + if ((var = switch_channel_get_variable(session->channel, "rtp_media_autofix_timing"))) { + if (switch_true(var)) { + switch_media_handle_set_media_flag(smh, SCMF_AUTOFIX_TIMING); + } else { + switch_media_handle_clear_media_flag(smh, SCMF_AUTOFIX_TIMING); + } + } +} + //? #define RA_PTR_LEN 512 SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_session_t *session, const char *sdp_str) @@ -6404,6 +6354,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi return SWITCH_STATUS_FALSE; } + switch_core_media_parse_media_flags(session); if (switch_rtp_ready(a_engine->rtp_session)) { switch_rtp_reset_media_timer(a_engine->rtp_session); From 0df7e787ce38bdd5c2e61fac37c1e92425bc5366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Mon, 18 Jul 2016 11:22:01 +0200 Subject: [PATCH 054/128] FS-9355: fix segfault in case of null frame --- src/switch_core_media.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 33de186fab..c73b73fa00 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -11697,7 +11697,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core } } - if ((*frame)->codec) { + if ((*frame) && (*frame)->codec) { if (patchers) { switch_set_flag((*frame)->codec, SWITCH_CODEC_FLAG_VIDEO_PATCHING); } else { From f43522877c2f0c6a426422797267c2b8fa6e56d5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 18 Jul 2016 11:11:32 -0500 Subject: [PATCH 055/128] FS-9356 #resolve [DTMF not recognized when coming from a Cisco SIP trunk] --- src/include/switch_core_media.h | 1 + src/mod/endpoints/mod_sofia/sofia.c | 5 +++-- src/switch_core_media.c | 6 ++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 27ab840e38..988ebbea42 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -75,6 +75,7 @@ typedef enum { SCMF_RTP_AUTOFLUSH_DURING_BRIDGE, SCMF_MULTI_ANSWER_AUDIO, SCMF_MULTI_ANSWER_VIDEO, + SCMF_RECV_SDP, SCMF_MAX } switch_core_media_flag_t; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 303330c0e0..bf7ae7b21f 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -7403,9 +7403,10 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP"); switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); switch_core_media_prepare_codecs(session, 1); - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); - sofia_set_flag_locked(tech_pvt, TFLAG_3PCC); switch_channel_set_state(channel, CS_HIBERNATE); + switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0); + sofia_set_flag_locked(tech_pvt, TFLAG_3PCC); + if (sofia_use_soa(tech_pvt)) { nua_respond(tech_pvt->nh, SIP_200_OK, SIPTAG_CONTACT_STR(tech_pvt->profile->url), diff --git a/src/switch_core_media.c b/src/switch_core_media.c index c73b73fa00..ab3918bc90 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3766,7 +3766,9 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s a_engine->new_dtls = 1; a_engine->new_ice = 1; a_engine->reject_avp = 0; - + + switch_media_handle_set_media_flag(smh, SCMF_RECV_SDP); + switch_core_session_parse_crypto_prefs(session); clear_pmaps(a_engine); @@ -8258,7 +8260,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess video: - if (!switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE) && sdp_type == SDP_TYPE_REQUEST) { + if (!switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE) && switch_media_handle_test_media_flag(smh, SCMF_RECV_SDP)) { has_vid = 0; } else { int i; From 6bc535fd65842bd9389aee322ee6846cc13171ca Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 18 Jul 2016 12:39:37 -0500 Subject: [PATCH 056/128] FS-9353 #resolve [clear-vid-floor produces error, while working] --- src/mod/applications/mod_conference/conference_api.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index 29ec532075..6fef270c31 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -1564,6 +1564,8 @@ switch_status_t conference_api_sub_clear_vid_floor(conference_obj_t *conference, //conference_video_set_floor_holder(conference, NULL); switch_mutex_unlock(conference->mutex); + stream->write_function(stream, "OK floor Cleared\n", SWITCH_VA_NONE); + return SWITCH_STATUS_SUCCESS; } From d9700b36a326c4da57c3608a98b7e7acb5510fd8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 18 Jul 2016 13:00:00 -0500 Subject: [PATCH 057/128] FS-9259 #resolve [Missing "m=image 0" when replying to INVITE with disable image line] --- src/include/switch_types.h | 1 + src/switch_core_media.c | 223 +++++++++++++++++++------------------ 2 files changed, 118 insertions(+), 106 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 527f6e597c..2bcf0414dd 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1509,6 +1509,7 @@ typedef enum { CF_3P_MEDIA_REQUESTED, CF_3P_NOMEDIA_REQUESTED, CF_3P_NOMEDIA_REQUESTED_BLEG, + CF_IMAGE_SDP, CF_VIDEO_SDP_RECVD, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ /* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */ diff --git a/src/switch_core_media.c b/src/switch_core_media.c index ab3918bc90..ba19175160 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3880,116 +3880,120 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s got_udptl++; } - if (got_udptl && m->m_type == sdp_media_image && m->m_port) { - switch_t38_options_t *t38_options = switch_core_media_process_udptl(session, sdp, m); + if (got_udptl && m->m_type == sdp_media_image) { + switch_channel_set_flag(session->channel, CF_IMAGE_SDP); - if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38_NEGOTIATED)) { + if (m->m_port) { + switch_t38_options_t *t38_options = switch_core_media_process_udptl(session, sdp, m); + + if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38_NEGOTIATED)) { + match = 1; + goto done; + } + + if (switch_true(switch_channel_get_variable(channel, "refuse_t38"))) { + switch_channel_clear_app_flag_key("T38", session->channel, CF_APP_T38); + match = 0; + goto done; + } else { + const char *var = switch_channel_get_variable(channel, "t38_passthru"); + int pass = switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU); + + + if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38)) { + if (proceed) *proceed = 0; + } + + if (var) { + if (!(pass = switch_true(var))) { + if (!strcasecmp(var, "once")) { + pass = 2; + } + } + } + + if ((pass == 2 && switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU)) + || !switch_channel_test_flag(session->channel, CF_REINVITE) || + + switch_channel_test_flag(session->channel, CF_PROXY_MODE) || + switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) || + !switch_rtp_ready(a_engine->rtp_session)) { + pass = 0; + } + + if (pass && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + switch_channel_t *other_channel = switch_core_session_get_channel(other_session); + switch_core_session_message_t *msg; + char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session); + switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session); + char tmp[32] = ""; + + + if (!switch_channel_test_flag(other_channel, CF_ANSWERED)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_WARNING, "%s Error Passing T.38 to unanswered channel %s\n", + switch_channel_get_name(session->channel), switch_channel_get_name(other_channel)); + switch_core_session_rwunlock(other_session); + + pass = 0; + match = 0; + goto done; + } + + + if (switch_true(switch_channel_get_variable(session->channel, "t38_broken_boolean")) && + switch_true(switch_channel_get_variable(session->channel, "t38_pass_broken_boolean"))) { + switch_channel_set_variable(other_channel, "t38_broken_boolean", "true"); + } + + a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, t38_options->remote_ip); + a_engine->cur_payload_map->remote_sdp_port = t38_options->remote_port; + + if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip) && remote_port == a_engine->cur_payload_map->remote_sdp_port) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n", + switch_channel_get_name(session->channel)); + } else { + const char *err = NULL; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n", + switch_channel_get_name(session->channel), + remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port); + + switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port); + switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip); + switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); + + if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip, + a_engine->cur_payload_map->remote_sdp_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err); + switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); + } + + switch_core_media_check_autoadj(session); + } + + + + switch_core_media_copy_t38_options(t38_options, other_session); + + switch_channel_set_flag(smh->session->channel, CF_T38_PASSTHRU); + switch_channel_set_flag(other_session->channel, CF_T38_PASSTHRU); + + msg = switch_core_session_alloc(other_session, sizeof(*msg)); + msg->message_id = SWITCH_MESSAGE_INDICATE_REQUEST_IMAGE_MEDIA; + msg->from = __FILE__; + msg->string_arg = switch_core_session_strdup(other_session, r_sdp); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing T38 req to other leg.\n%s\n", r_sdp); + switch_core_session_queue_message(other_session, msg); + switch_core_session_rwunlock(other_session); + } + } + + + /* do nothing here, mod_fax will trigger a response (if it's listening =/) */ match = 1; goto done; } - - if (switch_true(switch_channel_get_variable(channel, "refuse_t38"))) { - switch_channel_clear_app_flag_key("T38", session->channel, CF_APP_T38); - match = 0; - goto done; - } else { - const char *var = switch_channel_get_variable(channel, "t38_passthru"); - int pass = switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU); - - - if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38)) { - if (proceed) *proceed = 0; - } - - if (var) { - if (!(pass = switch_true(var))) { - if (!strcasecmp(var, "once")) { - pass = 2; - } - } - } - - if ((pass == 2 && switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU)) - || !switch_channel_test_flag(session->channel, CF_REINVITE) || - - switch_channel_test_flag(session->channel, CF_PROXY_MODE) || - switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) || - !switch_rtp_ready(a_engine->rtp_session)) { - pass = 0; - } - - if (pass && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { - switch_channel_t *other_channel = switch_core_session_get_channel(other_session); - switch_core_session_message_t *msg; - char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session); - switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session); - char tmp[32] = ""; - - - if (!switch_channel_test_flag(other_channel, CF_ANSWERED)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), - SWITCH_LOG_WARNING, "%s Error Passing T.38 to unanswered channel %s\n", - switch_channel_get_name(session->channel), switch_channel_get_name(other_channel)); - switch_core_session_rwunlock(other_session); - - pass = 0; - match = 0; - goto done; - } - - - if (switch_true(switch_channel_get_variable(session->channel, "t38_broken_boolean")) && - switch_true(switch_channel_get_variable(session->channel, "t38_pass_broken_boolean"))) { - switch_channel_set_variable(other_channel, "t38_broken_boolean", "true"); - } - - a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, t38_options->remote_ip); - a_engine->cur_payload_map->remote_sdp_port = t38_options->remote_port; - - if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip) && remote_port == a_engine->cur_payload_map->remote_sdp_port) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n", - switch_channel_get_name(session->channel)); - } else { - const char *err = NULL; - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n", - switch_channel_get_name(session->channel), - remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port); - - switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port); - switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip); - switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); - - if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip, - a_engine->cur_payload_map->remote_sdp_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err); - switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); - } - - switch_core_media_check_autoadj(session); - } - - - - switch_core_media_copy_t38_options(t38_options, other_session); - - switch_channel_set_flag(smh->session->channel, CF_T38_PASSTHRU); - switch_channel_set_flag(other_session->channel, CF_T38_PASSTHRU); - - msg = switch_core_session_alloc(other_session, sizeof(*msg)); - msg->message_id = SWITCH_MESSAGE_INDICATE_REQUEST_IMAGE_MEDIA; - msg->from = __FILE__; - msg->string_arg = switch_core_session_strdup(other_session, r_sdp); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing T38 req to other leg.\n%s\n", r_sdp); - switch_core_session_queue_message(other_session, msg); - switch_core_session_rwunlock(other_session); - } - } - - - /* do nothing here, mod_fax will trigger a response (if it's listening =/) */ - match = 1; - goto done; } else if (m->m_type == sdp_media_audio && m->m_port && got_audio && got_savp) { a_engine->reject_avp = 1; } else if (m->m_type == sdp_media_audio && m->m_port && !got_audio) { @@ -8257,6 +8261,12 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } + if (switch_channel_test_flag(session->channel, CF_IMAGE_SDP)) { + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=image 0 UDPTL T38\r\n", SWITCH_VA_NONE); + + } + + video: @@ -8814,6 +8824,7 @@ SWITCH_DECLARE(void) switch_core_media_set_udptl_image_sdp(switch_core_session_t a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; + switch_channel_clear_flag(session->channel, CF_IMAGE_SDP); switch_assert(t38_options); From 5cbe57841ed9e65a06c32cf93fdf8ffe08848064 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 18 Jul 2016 14:15:27 -0500 Subject: [PATCH 058/128] FS-9289 #resolve [MOH issue] --- src/switch_core_media.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index ba19175160..c982f0c11b 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -6494,9 +6494,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "AUDIO RTP CHANGING DEST TO: [%s:%d]\n", a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port); - if (switch_channel_test_flag(session->channel, CF_PROTO_HOLD) && strcmp(a_engine->cur_payload_map->remote_sdp_ip, "0.0.0.0")) { - switch_core_media_toggle_hold(session, 0); - } + //if (switch_channel_test_flag(session->channel, CF_PROTO_HOLD) && strcmp(a_engine->cur_payload_map->remote_sdp_ip, "0.0.0.0")) { + // switch_core_media_toggle_hold(session, 0); + //} if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && From 35ee4ee593e729dd0bc5d672fac5ef35928b68aa Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 18 Jul 2016 15:41:19 -0500 Subject: [PATCH 059/128] FS-9365 #resolve [SDP Format on reply to RE-INVITE does not appear to be RFC-4566 compliant] --- src/switch_core_media.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index c982f0c11b..e7aab352fb 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -8381,6 +8381,24 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "\r\n"); + + + if (!(vbw = switch_channel_get_variable(smh->session->channel, "rtp_video_max_bandwidth"))) { + vbw = switch_channel_get_variable(smh->session->channel, "rtp_video_max_bandwidth_in"); + } + + if (!vbw) { + vbw = "1mb"; + } + + bw = switch_parse_bandwidth_string(vbw); + + if (bw > 0) { + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=AS:%d\r\n", bw); + //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=TIAS:%d\r\n", bw); + } + + if (v_engine->codec_negotiated) { const char *of; @@ -8549,22 +8567,6 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } } - - if (!(vbw = switch_channel_get_variable(smh->session->channel, "rtp_video_max_bandwidth"))) { - vbw = switch_channel_get_variable(smh->session->channel, "rtp_video_max_bandwidth_in"); - } - - if (!vbw) { - vbw = "1mb"; - } - - bw = switch_parse_bandwidth_string(vbw); - - if (bw > 0) { - switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=AS:%d\r\n", bw); - //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=TIAS:%d\r\n", bw); - } - if (sdp_type == SDP_TYPE_REQUEST) { fir++; pli++; From 14f9b576f165a86957ec552b92bca42e6abc87e0 Mon Sep 17 00:00:00 2001 From: Chad Phillips Date: Fri, 15 Jul 2016 13:01:39 -0700 Subject: [PATCH 060/128] FS-9230: Customize video muted banner Allows customizing the banner displayed when video is muted, via conference param 'video-mute-banner' per conference, or channel var 'video_mute_banner' per user. Foreground/background colors, font face/size, and text can all be customized. --- .../mod_conference/conference_video.c | 76 ++++++++++++++++--- .../mod_conference/mod_conference.c | 7 ++ .../mod_conference/mod_conference.h | 1 + 3 files changed, 75 insertions(+), 9 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 13f15a2af7..060f769f66 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -1603,6 +1603,71 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_write_thread_run(switch_thread_ return NULL; } +void conference_video_member_video_mute_banner(mcu_canvas_t *canvas, mcu_layer_t *layer, conference_member_t *member) +{ + const char *text = "VIDEO MUTED"; + char *dup = NULL; + const char *var, *tmp = NULL; + const char *fg = ""; + const char *bg = ""; + const char *font_face = ""; + const char *font_scale = ""; + const char *font_scale_percentage = ""; + char *parsed = NULL; + switch_event_t *params = NULL; + switch_image_t *text_img; + char text_str[256] = ""; + + if ((var = switch_channel_get_variable_dup(member->channel, "video_mute_banner", SWITCH_FALSE, -1))) { + text = var; + } else if (member->conference->video_mute_banner) { + text = member->conference->video_mute_banner; + } + + if (*text == '{') { + dup = strdup(text); + text = dup; + + if (switch_event_create_brackets((char *)text, '{', '}', ',', ¶ms, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); + } else { + text = parsed; + } + } + + if ((tmp = strchr(text, '}'))) { + text = tmp + 1; + } + + if (params) { + if ((var = switch_event_get_header(params, "fg"))) { + fg = var; + } + + if ((var = switch_event_get_header(params, "bg"))) { + bg = var; + } + + if ((var = switch_event_get_header(params, "font_face"))) { + font_face = var; + } + + if ((var = switch_event_get_header(params, "font_scale"))) { + font_scale = var; + font_scale_percentage = "%"; + } + } + + switch_snprintf(text_str, sizeof(text_str), "%s:%s:%s:%s%s:%s", fg, bg, font_face, font_scale, font_scale_percentage, text); + text_img = switch_img_write_text_img(layer->screen_w, layer->screen_h, SWITCH_TRUE, text_str); + switch_img_patch(canvas->img, text_img, layer->x_pos, layer->y_pos); + switch_img_free(&text_img); + + if (params) switch_event_destroy(¶ms); + + switch_safe_free(dup); +} + void conference_video_check_recording(conference_obj_t *conference, mcu_canvas_t *canvas, switch_frame_t *frame) { conference_member_t *imember; @@ -2508,7 +2573,6 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN) || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE || conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS)) { layer->mute_patched = 0; } else { - switch_image_t *tmp; if (img && img != imember->avatar_png_img) { switch_img_free(&img); @@ -2536,10 +2600,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } - tmp = switch_img_write_text_img(layer->screen_w, layer->screen_h, SWITCH_TRUE, "VIDEO MUTED"); - switch_img_patch(canvas->img, tmp, layer->x_pos, layer->y_pos); - switch_img_free(&tmp); - + conference_video_member_video_mute_banner(canvas, layer, imember); layer->mute_patched = 1; } } @@ -2791,11 +2852,8 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr layer->mute_patched = 0; } else if (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS)) { if (!layer->mute_patched) { - switch_image_t *tmp; conference_video_scale_and_patch(layer, omember->video_mute_img ? omember->video_mute_img : omember->pcanvas_img, SWITCH_FALSE); - tmp = switch_img_write_text_img(layer->screen_w, layer->screen_h, SWITCH_TRUE, "VIDEO MUTED"); - switch_img_patch(imember->canvas->img, tmp, layer->x_pos, layer->y_pos); - switch_img_free(&tmp); + conference_video_member_video_mute_banner(imember->canvas, layer, imember); layer->mute_patched = 1; } diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 21b1077766..8f3b469517 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -2399,6 +2399,7 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co char *video_letterbox_bgcolor = NULL; char *video_codec_bandwidth = NULL; char *no_video_avatar = NULL; + char *video_mute_banner = NULL; conference_video_mode_t conference_video_mode = CONF_VIDEO_MODE_PASSTHROUGH; int conference_video_quality = 1; int auto_kps_debounce = 30000; @@ -2586,6 +2587,8 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co video_codec_bandwidth = val; } else if (!strcasecmp(var, "video-no-video-avatar") && !zstr(val)) { no_video_avatar = val; + } else if (!strcasecmp(var, "video-mute-banner") && !zstr(val)) { + video_mute_banner = val; } else if (!strcasecmp(var, "exit-sound") && !zstr(val)) { exit_sound = val; } else if (!strcasecmp(var, "alone-sound") && !zstr(val)) { @@ -2887,6 +2890,10 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co video_letterbox_bgcolor = "#000000"; } + if (video_mute_banner) { + conference->video_mute_banner = switch_core_strdup(conference->pool, video_mute_banner); + } + if (no_video_avatar) { conference->no_video_avatar = switch_core_strdup(conference->pool, no_video_avatar); } diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h index 43fbec8c09..05f12b8c48 100644 --- a/src/mod/applications/mod_conference/mod_conference.h +++ b/src/mod/applications/mod_conference/mod_conference.h @@ -564,6 +564,7 @@ typedef struct conference_obj { char *video_border_color; char *video_super_canvas_bgcolor; char *video_letterbox_bgcolor; + char *video_mute_banner; char *no_video_avatar; conference_video_mode_t conference_video_mode; int video_quality; From fdcb590a7f3c9d2091022596b31e1859581f11ea Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 19 Jul 2016 13:03:17 -0500 Subject: [PATCH 061/128] Simple fax test script --- scripts/perl/fax.cgi | 142 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 scripts/perl/fax.cgi diff --git a/scripts/perl/fax.cgi b/scripts/perl/fax.cgi new file mode 100644 index 0000000000..fecc26e684 --- /dev/null +++ b/scripts/perl/fax.cgi @@ -0,0 +1,142 @@ +#!/usr/bin/perl +# Simple Fax Test +# +# +# +use CGI qw(:standard); +use ESL; +use Data::Dumper; +use Data::UUID; +use XML::Simple; + +# Replace Your CID Here +my $cid_num = "1NXXNXXXXXX"; + +my $q = new CGI; +my $c = new ESL::ESLconnection("127.0.0.1", "8021", "ClueCon"); + +my $action = $q->param('action'); + +if($action eq 'log') { + my $uuid = $q->param('uuid'); + + if($uuid =~ m/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/) { + if(-e "/tmp/$uuid.log") { + print $q->header('text/plain'); + open(LOG, ") { print $_; } + close(LOG); + } else { + print $q->header(); + if(check_call($uuid)) { + my $pages = pages_sent($uuid); + print $q->start_html(-title=> 'FreeSWITCH Fax Results', + -head =>meta({-http_equiv => 'Refresh', + -content => "10;fax.cgi?uuid=$uuid&action=log"})), + font({-color=>'black', -face=>'Arial', -size=>'4'}), + "$pages pages(s) sent , Waiting on fax to complete. Please Wait! Page will reload again in 10 seconds.",br,br, + end_html; + } else { + print $q->start_html(-title=> 'FreeSWITCH Fax Failed'), + font({-color=>'black', -face=>'Arial', -size=>'4'}), + "Fax call appears to have failed.",br,br, + end_html; + } + } + } +} elsif ($action eq 'fax') { + print $q->header; + + my $file = '/var/www/fax.tif'; + my $fax = $q->param('fax'); + my $ecm = $q->param('ecm') || 'false'; + my $v17 = $q->param('v17') || 'false'; + my $t38 = $q->param('t38') || 'false'; + my $large = $q->param('large') || 'false'; + my $gateway = $q->param('gateway'); + my $refresh = 10; + my $ug = new Data::UUID; + my $buuid = $ug->create(); + my $uuid = $ug->to_string( $buuid ); + + $fax =~ s/\D+//g; + + if($fax =~ m/^(1[2-9]\d{2}[2-9]\d{6})$/) { + + if($large eq 'true') { + $file = '/var/www/fax_large.tif'; + $refresh = 60; + } + + my $e = $c->sendRecv("api bgapi originate {fax_ident='FreeSWITCH Test Fax',fax_header='FreeSWITCH Test Fax',api_hangup_hook='system /bin/grep $uuid /usr/local/freeswitch/log/freeswitch.log > /tmp/$uuid.log',origination_uuid=$uuid,fax_disable_v17=$v17,fax_use_ecm=$ecm,origination_caller_id_number=$cid_num,fax_verbose=true,fax_enable_t38=$t38,ignore_early_media=true,fax_enable_t38_request=$t38,t38_passthru=false,absolute_codec_string=PCMU}sofia/gateway/$gateway/$fax &txfax($file)"); + my $res = $e->getBody(); + print $q->start_html(-title=> 'FreeSWITCH Fax Results', + -head =>meta({ + -http_equiv => 'Refresh', + -content => "$refresh;fax.cgi?uuid=$uuid&action=log"})),br + font({-color=>'black', -face=>'Arial', -size=>'4'}), + "API Results: $res",br,br + "Send 10 Pages: $large",br, + "Enable T.38: $t38",br, + "Enable ECM: $ecm",br, + "Disable V17: $v17",br, + "Via Gateway: $gateway", br,br, + "Fax is queued to $fax immediately and will not retry on failure.",br,br + "Your log UUID is $uuid, wait here the page will reload showing you the results once complete",br,br, + end_html; + } else { + print "Invalid Number 1NXXNXXXXXX Only!"; + } +} else { + my @gateways = load_gateways(); + + print $q->header; + + print $q->start_html(-title=> 'FreeSWITCH Test Fax'), start_form, + img( {-src => "data:image/png;base64," . }),br,br,font({-color=>'black', -face=>'Arial', -size=>'4'}), + "Call will be coming from $cid_num",br,br, + "Customer Fax Number: ", textfield('fax'),br, + br,"Fax options:",br,hidden('action', 'fax'), + br,checkbox(-label => 'Send 10 Pages', -name => "large", -value => 'true', -selected => 0), br, + br,checkbox(-label => 'Enable T.38', -name => "t38", -value => 'true', -selected => 1), br, + br,checkbox(-label => 'Enable ECM', -name => "ecm", -value => 'true', -selected => 1), br, + br,checkbox(-label => 'Disable v.17', -name => "v17", -value => 'true', -selected => 0), br, + br,'Using Gateway:',popup_menu( -name=>'gateway', -values => \@gateways),br, + br,submit('SEND FAX'),end_form,end_html; +} + +sub check_call { + my $uuid = shift; + my $e = $c->api("uuid_getvar $uuid uuid"); + my $res = $e->getBody(); + if($res =~ m/No such channel/) { + return 0; + } + return 1; +} + +sub pages_sent { + my $uuid = shift; + my $e = $c->api("uuid_getvar $uuid fax_document_transferred_pages"); + my $res = $e->getBody(); + if ($res =~ /_undef_/) { return 0 }; + return $res; +} + +# Query FreeSWITCH for gateway list to populate the test rig. +sub load_gateways { + my $e = $c->api('sofia xmlstatus gateways'); + my $gwxml = $e->getBody(); + + my $ref = XMLin($gwxml); + my @gateways; + + foreach my $key (keys %{ $ref->{gateway} }) { + push @gateways, $key; + } + return @gateways; +} + + +__DATA__ +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 From 7e021af4d5d920dc25bd82765db369e33fe3b1b1 Mon Sep 17 00:00:00 2001 From: Mike Jerris Date: Tue, 19 Jul 2016 16:52:52 -0400 Subject: [PATCH 062/128] clean up noisy configure --- configure.ac | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/configure.ac b/configure.ac index 44857cbde4..db91f78a16 100644 --- a/configure.ac +++ b/configure.ac @@ -1975,22 +1975,6 @@ esac AC_OUTPUT -## -## Registering for ClueCon -## -if ! test -f noreg -o -f /noreg; then -echo "" -echo "" -echo $ECHO_N "Registering you for ClueCon http://www.cluecon.com $ECHO_C" 1>&6 -sleep 1 -echo $ECHO_N ".$ECHO_C" 1>&6 -sleep 1 -echo $ECHO_N ".$ECHO_C" 1>&6 -sleep 1 -AC_MSG_RESULT([ See you in August. ;-)]) -echo "" -fi - ## ## Configuration summary ## From 9ff1a506d0f38b5764178858aba8d1383b9001e3 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 19 Jul 2016 16:25:22 -0500 Subject: [PATCH 063/128] FS-9357 #resolve [VP9 codec screenshare on mod_conference (mux/transcode) does not work] --- html5/verto/verto_communicator/src/index.html | 2 +- src/switch_vpx.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/html5/verto/verto_communicator/src/index.html b/html5/verto/verto_communicator/src/index.html index e886875756..2f4e2af1f5 100644 --- a/html5/verto/verto_communicator/src/index.html +++ b/html5/verto/verto_communicator/src/index.html @@ -88,7 +88,7 @@ - + diff --git a/src/switch_vpx.c b/src/switch_vpx.c index a6a475f577..4427e3f934 100644 --- a/src/switch_vpx.c +++ b/src/switch_vpx.c @@ -1072,12 +1072,12 @@ static switch_status_t buffer_vp9_packets(vpx_context_t *context, switch_frame_t goto end; } - if (switch_buffer_inuse(context->vpx_packet_buffer)) { // middle packet - if (desc->start) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "got invalid vp9 packet, packet loss? resetting buffer\n"); - switch_buffer_zero(context->vpx_packet_buffer); - } - } else { // start packet + if (!switch_buffer_inuse(context->vpx_packet_buffer)) { // middle packet + //if (desc->start) { + // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "got invalid vp9 packet, packet loss? resetting buffer\n"); + // switch_buffer_zero(context->vpx_packet_buffer); + //} + //} else { // start packet if (!desc->start) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "got invalid vp9 packet, packet loss? waiting for a start packet\n"); goto end; From 31fee66cda2a75203256959fae7f8c682609873c Mon Sep 17 00:00:00 2001 From: Italo Rossi Date: Tue, 19 Jul 2016 18:23:55 -0300 Subject: [PATCH 064/128] FS-9342 [verto_communicator] Only copy data to storage when closing the settings --- .../src/vertoControllers/controllers/MainController.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js index a9605b56d5..c1a528784a 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js @@ -292,8 +292,10 @@ $scope.closeSettings = function() { var settingsEl = angular.element(document.querySelector('#settings')); - settingsEl.removeClass('toggled'); - $rootScope.$emit('toggledSettings', settingsEl.hasClass('toggled')); + if (settingsEl.hasClass('toggled')) { + settingsEl.removeClass('toggled'); + $rootScope.$emit('toggledSettings', settingsEl.hasClass('toggled')); + } }; $scope.goFullscreen = function() { From ec2734c10c867a3d390394cb1c3c333d11ec3a2b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 21 Jul 2016 03:22:37 -0500 Subject: [PATCH 065/128] FS-9334 revert --- src/switch_jitterbuffer.c | 21 ++++++++------------- src/switch_rtp.c | 4 ++-- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/switch_jitterbuffer.c b/src/switch_jitterbuffer.c index 917dcf8964..427498a5d2 100644 --- a/src/switch_jitterbuffer.c +++ b/src/switch_jitterbuffer.c @@ -614,21 +614,18 @@ static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch if (jb->type == SJB_VIDEO) { if (jb->write_init && ((htons(packet->header.seq) >= htons(jb->highest_wrote_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_wrote_ts))) || (ntohl(jb->highest_wrote_ts) > (UINT_MAX - 1000) && ntohl(node->packet.header.ts) < 1000))) { + jb->complete_frames++; + jb_debug(jb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); jb->highest_wrote_ts = packet->header.ts; //verify_oldest_frame(jb); } else if (!jb->write_init) { jb->highest_wrote_ts = packet->header.ts; } - - jb->complete_frames++; - jb_debug(jb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); - } else { - - jb_debug(jb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); - jb->complete_frames++; - - if (!jb->write_init) { + if (jb->write_init) { + jb_debug(jb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); + jb->complete_frames++; + } else { jb->highest_wrote_ts = packet->header.ts; } } @@ -1272,12 +1269,10 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp (ntohs(jb->highest_read_seq) > USHRT_MAX - 10 && ntohs(node->packet.header.seq) <= 10) ) { jb->highest_read_seq = node->packet.header.seq; } - - jb->complete_frames--; - jb_debug(jb, 2, "READ frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); - if (jb->read_init && htons(node->packet.header.seq) >= htons(jb->highest_read_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_read_ts))) { + jb->complete_frames--; + jb_debug(jb, 2, "READ frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); jb->highest_read_ts = node->packet.header.ts; } else if (!jb->read_init) { jb->highest_read_ts = node->packet.header.ts; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 0649be6c2d..bf485f4c3e 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -5802,7 +5802,7 @@ static void handle_nack(switch_rtp_t *rtp_session, uint32_t nack) send_msg->header.pt, ntohl(send_msg->header.ts), ntohs(send_msg->header.seq), send_msg->header.m); } - //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "RE----SEND %u\n", ntohs(send_msg->header.seq)); + //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RE----SEND %u\n", ntohs(send_msg->header.seq)); switch_rtp_write_raw(rtp_session, (void *) send_msg, &bytes, SWITCH_FALSE); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Cannot send NACK for seq %u\n", ntohs(seq)); @@ -5826,7 +5826,7 @@ static void handle_nack(switch_rtp_t *rtp_session, uint32_t nack) send_msg->header.pt, ntohl(send_msg->header.ts), ntohs(send_msg->header.seq), send_msg->header.m); } - //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "RE----SEND %u\n", ntohs(send_msg->header.seq)); + //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RE----SEND %u\n", ntohs(send_msg->header.seq)); switch_rtp_write_raw(rtp_session, (void *) &send_msg, &bytes, SWITCH_FALSE); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Cannot send NACK for seq %u\n", ntohs(seq) + i); From 497b8926d7fee45ecf01e97b19739175d8401c72 Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Thu, 21 Jul 2016 09:22:31 -0500 Subject: [PATCH 066/128] FS-9373 #resolve make add mod-verto and mod-rtc to freeswitch-meta-all debian package --- debian/bootstrap.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index a8ccae6570..383466308a 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -634,10 +634,12 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-dingaling (= \${binary:Version}), freeswitch-mod-loopback (= \${binary:Version}), freeswitch-mod-portaudio (= \${binary:Version}), + freeswitch-mod-rtc (= \${binary:Version}), freeswitch-mod-rtmp (= \${binary:Version}), freeswitch-mod-skinny (= \${binary:Version}), freeswitch-mod-skypopen (= \${binary:Version}), freeswitch-mod-sofia (= \${binary:Version}), + freeswitch-mod-verto (= \${binary:Version}), freeswitch-mod-cdr-csv (= \${binary:Version}), freeswitch-mod-cdr-mongodb (= \${binary:Version}), freeswitch-mod-cdr-sqlite (= \${binary:Version}), From c556e5269b2f81e1d386165361f141c08c7f335a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 21 Jul 2016 14:31:56 -0500 Subject: [PATCH 067/128] FS-9368 --- src/mod/endpoints/mod_sofia/sofia.c | 9 +---- src/switch_core_media.c | 56 +++++++++++++++++++++++------ src/switch_ivr_bridge.c | 1 + src/switch_rtp.c | 21 ++++++----- 4 files changed, 59 insertions(+), 28 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index bf7ae7b21f..fb46114071 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -9159,16 +9159,9 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype && sip->sip_payload && sip->sip_payload->pl_data) { if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "media_control+xml")) { - switch_core_session_t *other_session; - if (switch_channel_test_flag(channel, CF_VIDEO)) { switch_core_media_gen_key_frame(session); - if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { - sofia_glue_build_vid_refresh_message(other_session, sip->sip_payload->pl_data); - switch_core_session_rwunlock(other_session); - } else { - switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ); - } + switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ); } } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && diff --git a/src/switch_core_media.c b/src/switch_core_media.c index e7aab352fb..3a024a059c 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -1926,6 +1926,15 @@ static void check_jb(switch_core_session_t *session, const char *input, int32_t switch_rtp_set_video_buffer_size(v_engine->rtp_session, frames, max_frames); } return; + } else if (!strcasecmp(input, "vpause")) { + switch_rtp_pause_jitter_buffer(v_engine->rtp_session, SWITCH_TRUE); + return; + } else if (!strcasecmp(input, "vresume")) { + switch_rtp_pause_jitter_buffer(v_engine->rtp_session, SWITCH_FALSE); + return; + } else if (!strcasecmp(input, "vstop")) { + switch_rtp_deactivate_jitter_buffer(v_engine->rtp_session); + return; } else if (!strncasecmp(input, "vdebug:", 7)) { s = input + 7; @@ -2050,6 +2059,11 @@ static void check_jb_sync(switch_core_session_t *session) } fps = switch_core_media_get_video_fps(session); + + + if (switch_test_flag(smh, SMF_JB_PAUSED)) { + return; + } switch_rtp_get_video_buffer_size(v_engine->rtp_session, &min_frames, &max_frames, &cur_frames, NULL); @@ -2637,7 +2651,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_write_frame(switch_core_sessio return SWITCH_STATUS_GENERR; } - if (!switch_test_flag(frame, SFF_CNG) && !switch_test_flag(frame, SFF_PROXY_PACKET)) { + if (type == SWITCH_MEDIA_TYPE_AUDIO && !switch_test_flag(frame, SFF_CNG) && !switch_test_flag(frame, SFF_PROXY_PACKET)) { if (engine->read_impl.encoded_bytes_per_packet) { bytes = engine->read_impl.encoded_bytes_per_packet; frames = ((int) frame->datalen / bytes); @@ -9630,19 +9644,29 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se case SWITCH_MESSAGE_INDICATE_BRIDGE: { - if (switch_rtp_ready(a_engine->rtp_session)) { + if (switch_rtp_ready(a_engine->rtp_session) || switch_rtp_ready(v_engine->rtp_session)) { const char *val; - int ok = 0; - - if (!switch_channel_test_flag(session->channel, CF_VIDEO) && + + if ( (!(val = switch_channel_get_variable(session->channel, "rtp_jitter_buffer_during_bridge")) || switch_false(val))) { if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && switch_channel_test_cap_partner(session->channel, CC_FS_RTP)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s PAUSE Jitterbuffer\n", switch_channel_get_name(session->channel)); - switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_TRUE); + if (a_engine->rtp_session) { + switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_TRUE); + } + + if (v_engine->rtp_session) { + switch_rtp_pause_jitter_buffer(v_engine->rtp_session, SWITCH_TRUE); + } switch_set_flag(smh, SMF_JB_PAUSED); } } + } + + if (switch_rtp_ready(a_engine->rtp_session)) { + const char *val; + int ok = 0; if (switch_channel_test_flag(session->channel, CF_PASS_RFC2833) && switch_channel_test_flag_partner(session->channel, CF_FS_RTP)) { switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833); @@ -9689,18 +9713,26 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se } goto end; case SWITCH_MESSAGE_INDICATE_UNBRIDGE: - if (switch_rtp_ready(a_engine->rtp_session)) { - + + if (switch_rtp_ready(a_engine->rtp_session) || switch_rtp_ready(v_engine->rtp_session)) { if (switch_test_flag(smh, SMF_JB_PAUSED)) { switch_clear_flag(smh, SMF_JB_PAUSED); if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s RESUME Jitterbuffer\n", switch_channel_get_name(session->channel)); - switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_FALSE); + if (a_engine->rtp_session) { + switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_FALSE); + } + + if (v_engine->rtp_session) { + switch_rtp_pause_jitter_buffer(v_engine->rtp_session, SWITCH_FALSE); + } } } - + } + if (switch_rtp_ready(a_engine->rtp_session)) { + if (switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s deactivate passthru 2833 mode.\n", switch_channel_get_name(session->channel)); @@ -11272,7 +11304,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor switch_status_t status = SWITCH_STATUS_FALSE; switch_time_t now = switch_micro_time_now(); switch_codec_t *codec = switch_core_session_get_video_write_codec(session); - switch_timer_t *timer; + //switch_timer_t *timer; switch_media_handle_t *smh; switch_image_t *dup_img = NULL, *img = frame->img; switch_status_t encode_status; @@ -11422,6 +11454,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor frame = &write_frame; frame->img = img; +#if 0 if (!switch_test_flag(frame, SFF_USE_VIDEO_TIMESTAMP)) { if (!(timer = switch_core_media_get_timer(session, SWITCH_MEDIA_TYPE_VIDEO))) { @@ -11435,6 +11468,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor frame->timestamp = timer->samplecount; } +#endif switch_clear_flag(frame, SFF_SAME_IMAGE); frame->m = 0; diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 62d5daf600..2cadf833d4 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -195,6 +195,7 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj) if (switch_channel_media_up(b_channel)) { + switch_set_flag(read_frame, SFF_PROXY_PACKET); if (switch_core_session_write_video_frame(vh->session_b, read_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { switch_cond_next(); continue; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index bf485f4c3e..0fefeaee54 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4060,7 +4060,7 @@ SWITCH_DECLARE(switch_jb_t *) switch_rtp_get_jitter_buffer(switch_rtp_t *rtp_ses SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause) { - if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) { + if (!switch_rtp_ready(rtp_session) || (!rtp_session->jb && !rtp_session->vb)) { return SWITCH_STATUS_FALSE; } @@ -4069,7 +4069,11 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp } if (rtp_session->pause_jb && !pause) { - switch_jb_reset(rtp_session->jb); + if (rtp_session->vb) { + switch_jb_reset(rtp_session->vb); + } else { + switch_jb_reset(rtp_session->jb); + } } rtp_session->pause_jb = pause ? 1 : 0; @@ -5639,7 +5643,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (rtp_session->has_rtp && *bytes) { uint32_t read_ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc); - if (rtp_session->vb && jb_valid(rtp_session)) { + if (rtp_session->vb && jb_valid(rtp_session) && !rtp_session->pause_jb) { status = switch_jb_put_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, *bytes); if (status == SWITCH_STATUS_TOO_LATE) { @@ -5734,7 +5738,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t } } - if (rtp_session->vb && jb_valid(rtp_session)) { + if (rtp_session->vb && jb_valid(rtp_session) && !rtp_session->pause_jb) { switch_status_t vstatus = switch_jb_get_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, bytes); status = vstatus; @@ -6324,7 +6328,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ pt = 200000; } - if (rtp_session->vb) { + if (rtp_session->vb && !rtp_session->pause_jb) { if (switch_jb_poll(rtp_session->vb)) { pt = 0; } @@ -6333,12 +6337,12 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ if ((io_flags & SWITCH_IO_FLAG_NOBLOCK)) { pt = 0; } - + poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt); //if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) { - // switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "WTF Poll %d\n", poll_status); + // switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "WTF Poll %d %d\n", pt, poll_status); //} if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && rtp_session->dtmf_data.out_digit_dur > 0) { @@ -6355,7 +6359,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } - if (poll_status == SWITCH_STATUS_SUCCESS || (rtp_session->vb && switch_jb_poll(rtp_session->vb))) { + if (poll_status == SWITCH_STATUS_SUCCESS || (rtp_session->vb && !rtp_session->pause_jb && switch_jb_poll(rtp_session->vb))) { got_rtp_poll = 1; @@ -7290,7 +7294,6 @@ static int rtp_common_write(switch_rtp_t *rtp_session, } } - if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA) || switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { /* Normalize the timestamps to our own base by generating a made up starting point then adding the measured deltas to that base so if the timestamps and ssrc of the source change, it will not break the other end's jitter bufffer / decoder etc *cough* CHROME *cough* From 9879731f8ff96e2c33d2b17d7ef18e19a94cf2e8 Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 21 Jul 2016 22:11:29 -0500 Subject: [PATCH 068/128] FS-9334 --- src/switch_rtp.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 0fefeaee54..9834045ec2 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -452,6 +452,7 @@ struct switch_rtp { uint8_t has_ice; uint8_t punts; uint8_t clean; + uint32_t last_max_vb_frames; #ifdef ENABLE_ZRTP zrtp_session_t *zrtp_session; zrtp_profile_t *zrtp_profile; @@ -4110,9 +4111,15 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_video_buffer_size(switch_rtp_t *r } if (!max_frames) { - max_frames = 50; + max_frames = rtp_session->last_max_vb_frames; + } + + if (!max_frames || frames >= max_frames) { + max_frames = frames + 8; } + rtp_session->last_max_vb_frames = max_frames; + if (!rtp_session->vb) { switch_jb_create(&rtp_session->vb, SJB_VIDEO, frames, max_frames, rtp_session->pool); switch_jb_set_session(rtp_session->vb, rtp_session->session); From c08809e29009d5f51bdc2276530e9ec40f211eaf Mon Sep 17 00:00:00 2001 From: Spencer Thomason Date: Fri, 22 Jul 2016 07:37:21 -0700 Subject: [PATCH 069/128] FS-8783: [libsrtp] Fix alignment issue Backport upstream alignment fix to correct bus error on platforms that require strict memory alignment such as SPARC FS-8783 #resolve From upstream: commit 4d8430a504137509f23b5a19f8a06b6df0f651cc Author: Jaap Keuter Date: Fri Nov 7 00:13:10 2014 +0100 While setting the IV for AES ICM the nonce is simply typecast from a void * to a v128_t *. This breaches alignment requirements for v128_t objects on platforms that require it. Instead make a copy of the nonce to assure proper alignment. --- libs/srtp/crypto/cipher/aes_icm.c | 9 ++++++--- libs/srtp/crypto/cipher/aes_icm_ossl.c | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/libs/srtp/crypto/cipher/aes_icm.c b/libs/srtp/crypto/cipher/aes_icm.c index ef7545f283..cda56a8ddc 100644 --- a/libs/srtp/crypto/cipher/aes_icm.c +++ b/libs/srtp/crypto/cipher/aes_icm.c @@ -284,12 +284,15 @@ aes_icm_set_octet(aes_icm_ctx_t *c, err_status_t aes_icm_set_iv(aes_icm_ctx_t *c, void *iv, int direction) { - v128_t *nonce = (v128_t *) iv; + v128_t nonce; + + /* set nonce (for alignment) */ + v128_copy_octet_string(&nonce, iv); debug_print(mod_aes_icm, - "setting iv: %s", v128_hex_string(nonce)); + "setting iv: %s", v128_hex_string(&nonce)); - v128_xor(&c->counter, &c->offset, nonce); + v128_xor(&c->counter, &c->offset, &nonce); debug_print(mod_aes_icm, "set_counter: %s", v128_hex_string(&c->counter)); diff --git a/libs/srtp/crypto/cipher/aes_icm_ossl.c b/libs/srtp/crypto/cipher/aes_icm_ossl.c index 12054a2cc9..1e1860d093 100644 --- a/libs/srtp/crypto/cipher/aes_icm_ossl.c +++ b/libs/srtp/crypto/cipher/aes_icm_ossl.c @@ -263,11 +263,14 @@ err_status_t aes_icm_openssl_context_init (aes_icm_ctx_t *c, const uint8_t *key) err_status_t aes_icm_openssl_set_iv (aes_icm_ctx_t *c, void *iv, int dir) { const EVP_CIPHER *evp; - v128_t *nonce = (v128_t*)iv; + v128_t nonce; - debug_print(mod_aes_icm, "setting iv: %s", v128_hex_string(nonce)); + /* set nonce (for alignment) */ + v128_copy_octet_string(&nonce, iv); - v128_xor(&c->counter, &c->offset, nonce); + debug_print(mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce)); + + v128_xor(&c->counter, &c->offset, &nonce); debug_print(mod_aes_icm, "set_counter: %s", v128_hex_string(&c->counter)); From e42997ef0820be00944853a873a4ea3644611ccc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 22 Jul 2016 22:43:55 -0500 Subject: [PATCH 070/128] FS-9376 #comment please try this --- src/mod/endpoints/mod_sofia/sofia.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index fb46114071..ed020b17c7 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -7463,15 +7463,13 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); - nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END()); - goto done; - - /* } else if (0 && r_sdp && !sofia_use_soa(tech_pvt)) { nua_respond(tech_pvt->nh, SIP_200_OK, NUTAG_MEDIA_ENABLE(0), SIPTAG_CONTACT_STR(tech_pvt->profile->url), SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END()); - */ + + goto done; + } else { ss_state = nua_callstate_completed; goto state_process; From 18f1d5689198f25a538a6730c2f85eb673f3dec6 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sun, 24 Jul 2016 12:35:30 +0800 Subject: [PATCH 071/128] FS-9357 cleanup and tweak debug --- src/switch_vpx.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/switch_vpx.c b/src/switch_vpx.c index 4427e3f934..5b5f42307e 100644 --- a/src/switch_vpx.c +++ b/src/switch_vpx.c @@ -966,7 +966,8 @@ static switch_status_t buffer_vp9_packets(vpx_context_t *context, switch_frame_t int len = 0; #ifdef DEBUG_VP9 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%02x %02x %02x %02x m=%d len=%4d " + switch_log_printf(SWITCH_CHANNEL_LOG, frame->m ? SWITCH_LOG_ERROR : SWITCH_LOG_INFO, + "[%02x %02x %02x %02x] m=%d len=%4d seq=%d ts=%d ssrc=%u " "have_pid=%d " "have_p_layer=%d " "have_layer_ind=%d " @@ -975,7 +976,7 @@ static switch_status_t buffer_vp9_packets(vpx_context_t *context, switch_frame_t "end=%d " "have_ss=%d " "zero=%d\n", - *data, *(data+1), *(data+2), *(data+3), frame->m, frame->datalen, + *data, *(data+1), *(data+2), *(data+3), frame->m, frame->datalen, frame->seq, frame->timestamp, frame->ssrc, desc->have_pid, desc->have_p_layer, desc->have_layer_ind, @@ -1001,7 +1002,7 @@ static switch_status_t buffer_vp9_packets(vpx_context_t *context, switch_frame_t vp9++; #ifdef DEBUG_VP9 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "have pid: %d start=%d end=%d\n", pid, desc->start, desc->end); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "have pid: %d start=%d end=%d\n", pid, desc->start, desc->end); #endif } @@ -1072,12 +1073,7 @@ static switch_status_t buffer_vp9_packets(vpx_context_t *context, switch_frame_t goto end; } - if (!switch_buffer_inuse(context->vpx_packet_buffer)) { // middle packet - //if (desc->start) { - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "got invalid vp9 packet, packet loss? resetting buffer\n"); - // switch_buffer_zero(context->vpx_packet_buffer); - //} - //} else { // start packet + if (!switch_buffer_inuse(context->vpx_packet_buffer)) { // start packet if (!desc->start) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "got invalid vp9 packet, packet loss? waiting for a start packet\n"); goto end; @@ -1090,7 +1086,7 @@ static switch_status_t buffer_vp9_packets(vpx_context_t *context, switch_frame_t end: #ifdef DEBUG_VP9 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffered %d bytes, buffer size: %" SWITCH_SIZE_T_FMT "\n", len, switch_buffer_inuse(context->vpx_packet_buffer)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "buffered %d bytes, buffer size: %" SWITCH_SIZE_T_FMT "\n", len, switch_buffer_inuse(context->vpx_packet_buffer)); #endif return SWITCH_STATUS_SUCCESS; From 7df07d30e01817f9485db3f06ae08f89390828ba Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sun, 24 Jul 2016 20:44:39 +0800 Subject: [PATCH 072/128] FS-9357 handle packet loss, reset decoder on mem err --- src/switch_vpx.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/switch_vpx.c b/src/switch_vpx.c index 5b5f42307e..9ad4ed8da5 100644 --- a/src/switch_vpx.c +++ b/src/switch_vpx.c @@ -42,6 +42,12 @@ // #define DEBUG_VP9 +#ifdef DEBUG_VP9 +#define VPX_SWITCH_LOG_LEVEL SWITCH_LOG_ERROR +#else +#define VPX_SWITCH_LOG_LEVEL SWITCH_LOG_DEBUG1 +#endif + #define SLICE_SIZE SWITCH_DEFAULT_VIDEO_SIZE #define KEY_FRAME_MIN_FREQ 250000 @@ -291,6 +297,7 @@ struct vpx_context { int got_start_frame; uint32_t last_received_timestamp; switch_bool_t last_received_complete_picture; + uint16_t last_received_seq; int need_key_frame; int need_encoder_reset; int need_decoder_reset; @@ -333,6 +340,7 @@ static switch_status_t init_decoder(switch_codec_t *codec) context->last_ts = 0; context->last_received_timestamp = 0; context->last_received_complete_picture = 0; + context->last_received_seq = 0; context->decoder_init = 1; context->got_key_frame = 0; context->no_key_frame = 0; @@ -406,7 +414,7 @@ static switch_status_t init_encoder(switch_codec_t *codec) config->g_lag_in_frames = 0; config->kf_max_dist = 360;//2000; threads = cpus / 4; - if (threads < 0) threads = 1; + if (threads < 1) threads = 1; config->g_threads = threads; if (context->is_vp9) { @@ -967,7 +975,7 @@ static switch_status_t buffer_vp9_packets(vpx_context_t *context, switch_frame_t #ifdef DEBUG_VP9 switch_log_printf(SWITCH_CHANNEL_LOG, frame->m ? SWITCH_LOG_ERROR : SWITCH_LOG_INFO, - "[%02x %02x %02x %02x] m=%d len=%4d seq=%d ts=%d ssrc=%u " + "[%02x %02x %02x %02x] m=%d len=%4d seq=%d ts=%u ssrc=%u " "have_pid=%d " "have_p_layer=%d " "have_layer_ind=%d " @@ -1111,11 +1119,16 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t * is_keyframe = IS_VP9_KEY_FRAME(*(unsigned char *)frame->data); is_start = IS_VP9_START_PKT(*(unsigned char *)frame->data); -#ifdef DEBUG_VP9 if (is_keyframe) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "================Got a key frame!!!!========================\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, VPX_SWITCH_LOG_LEVEL, "================Got a key frame!!!!========================\n"); } -#endif + + if (context->last_received_seq && context->last_received_seq + 1 != frame->seq) { + switch_log_printf(SWITCH_CHANNEL_LOG, VPX_SWITCH_LOG_LEVEL, "Packet loss detected last=%d got=%d lost=%d\n", context->last_received_seq, frame->seq, frame->seq - context->last_received_seq); + if (is_keyframe && context->vpx_packet_buffer) switch_buffer_zero(context->vpx_packet_buffer); + } + + context->last_received_seq = frame->seq; } else { // vp8 is_start = (*(unsigned char *)frame->data & 0x10); is_keyframe = IS_VP8_KEY_FRAME((uint8_t *)frame->data); @@ -1210,8 +1223,15 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t * err = vpx_codec_decode(decoder, data, (unsigned int)len, NULL, 0); if (err != VPX_CODEC_OK) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Error decoding %" SWITCH_SIZE_T_FMT " bytes, [%d:%s:%s]\n", + switch_log_printf(SWITCH_CHANNEL_LOG, VPX_SWITCH_LOG_LEVEL, "Error decoding %" SWITCH_SIZE_T_FMT " bytes, [%d:%s:%s]\n", len, err, vpx_codec_error(decoder), vpx_codec_error_detail(decoder)); + + + if (err == VPX_CODEC_MEM_ERROR) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "VPX MEM ERROR, resetting decoder!\n"); + context->need_decoder_reset = 1; + } + switch_goto_status(SWITCH_STATUS_RESTART, end); } From 2c8691009244922a99c5f243294d6a0ac2150f32 Mon Sep 17 00:00:00 2001 From: Mike Jerris Date: Mon, 25 Jul 2016 14:01:52 -0400 Subject: [PATCH 073/128] FS-9381: [mod_sofia] fix leak in sofia_presence_chat_send --- src/mod/endpoints/mod_sofia/sofia_presence.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 343c231a44..e1973efabe 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -384,6 +384,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) sofia_glue_free_destination(dst); switch_safe_free(dup_dest); + switch_safe_free(user_via); switch_safe_free(remote_host); } From 3227b02194842c92db4b3219ce8604e68c4bea41 Mon Sep 17 00:00:00 2001 From: John Briscoe Date: Tue, 26 Jul 2016 13:18:41 -0700 Subject: [PATCH 074/128] do not destroy conference if ghost(s) are present, add ghost count check before setting flag --- src/mod/applications/mod_conference/mod_conference.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 8f3b469517..28624d2120 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -2250,7 +2250,7 @@ SWITCH_STANDARD_APP(conference_function) if (conference) { switch_mutex_lock(conference->mutex); - if (conference_utils_test_flag(conference, CFLAG_DYNAMIC) && conference->count == 0) { + if (conference_utils_test_flag(conference, CFLAG_DYNAMIC) && conference->count == 0 && conference->count_ghosts == 0) { conference_utils_set_flag_locked(conference, CFLAG_DESTRUCT); } switch_mutex_unlock(conference->mutex); From 0dc59995c66e3a4be44a0a29426b2b6ce06248d9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 26 Jul 2016 21:33:14 -0500 Subject: [PATCH 075/128] FS-9382 --- src/switch_core_media.c | 6 +++--- src/switch_ivr_bridge.c | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 3a024a059c..ca5aa70c28 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -11304,7 +11304,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor switch_status_t status = SWITCH_STATUS_FALSE; switch_time_t now = switch_micro_time_now(); switch_codec_t *codec = switch_core_session_get_video_write_codec(session); - //switch_timer_t *timer; + switch_timer_t *timer; switch_media_handle_t *smh; switch_image_t *dup_img = NULL, *img = frame->img; switch_status_t encode_status; @@ -11454,7 +11454,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor frame = &write_frame; frame->img = img; -#if 0 + if (!switch_test_flag(frame, SFF_USE_VIDEO_TIMESTAMP)) { if (!(timer = switch_core_media_get_timer(session, SWITCH_MEDIA_TYPE_VIDEO))) { @@ -11468,7 +11468,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor frame->timestamp = timer->samplecount; } -#endif + switch_clear_flag(frame, SFF_SAME_IMAGE); frame->m = 0; diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 2cadf833d4..62d5daf600 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -195,7 +195,6 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj) if (switch_channel_media_up(b_channel)) { - switch_set_flag(read_frame, SFF_PROXY_PACKET); if (switch_core_session_write_video_frame(vh->session_b, read_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { switch_cond_next(); continue; From a2fd327fa7dae6a43e9a4561280bcde139974759 Mon Sep 17 00:00:00 2001 From: Spencer Thomason Date: Tue, 26 Jul 2016 13:48:13 -0700 Subject: [PATCH 076/128] FS-9386: [mod_snmp] Use net-snmp-config for SNMP libs if available FS-9386 #resolve --- configure.ac | 16 ++++++++++++++++ src/mod/event_handlers/mod_snmp/Makefile.am | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index db91f78a16..cce8ab0af4 100644 --- a/configure.ac +++ b/configure.ac @@ -1705,6 +1705,22 @@ else AC_MSG_WARN([python support disabled, building mod_python will fail!]) fi +# +# SNMP checks for mod_snmp +# +AC_PATH_PROG([NET_SNMP_CONFIG], [net-snmp-config], [no]) +if test "$NET_SNMP_CONFIG" != "no"; then + AC_MSG_CHECKING([for Net-SNMP libraries via net-snmp-config]) + SNMP_LIBS="`$NET_SNMP_CONFIG --base-agent-libs`" +else + # net-snmp-config not in path, fallback to sensible defaults + SNMP_LIBS="-lnetsnmpmibs -lnetsnmpagent -lnetsnmp" +fi + +# fix linking error on Solaris patched Net-SNMP +AS_CASE([$host], [*-solaris2*], [AC_CHECK_LIB([dladm], [dladm_open], [SNMP_LIBS="$SNMP_LIBS -ldladm"])]) +AC_SUBST(SNMP_LIBS) + CHECK_ERLANG # we never use this, and hard setting it will make cross compile work better diff --git a/src/mod/event_handlers/mod_snmp/Makefile.am b/src/mod/event_handlers/mod_snmp/Makefile.am index e949e9ad9e..a94ebe0c51 100644 --- a/src/mod/event_handlers/mod_snmp/Makefile.am +++ b/src/mod/event_handlers/mod_snmp/Makefile.am @@ -4,5 +4,5 @@ MODNAME=mod_snmp mod_LTLIBRARIES = mod_snmp.la mod_snmp_la_SOURCES = mod_snmp.c subagent.c mod_snmp_la_CFLAGS = $(AM_CFLAGS) -mod_snmp_la_LIBADD = $(switch_builddir)/libfreeswitch.la -lnetsnmpmibs -lnetsnmpagent -lnetsnmp +mod_snmp_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SNMP_LIBS) mod_snmp_la_LDFLAGS = -avoid-version -module -no-undefined -shared From 6c0f18d960eebeed859ddd4accbc36c5ee267aa9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 27 Jul 2016 14:29:12 -0500 Subject: [PATCH 077/128] FS-9154 #resolve [Add & remove video on re-invites] --- libs/sofia-sip/.update | 2 +- libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 7d1f2d2217..b9f2e8ad18 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Wed Apr 27 16:01:46 EDT 2016 +Wed Jul 27 14:15:49 CDT 2016 diff --git a/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c b/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c index 0e192acd0c..c80d45ce36 100644 --- a/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c +++ b/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c @@ -1061,9 +1061,11 @@ int soa_sdp_mode_set(sdp_session_t const *user, continue; } - send_mode = (sdp_mode_t)(um->m_mode & sdp_sendonly); - if (rm) - send_mode = (rm->m_mode & sdp_recvonly) ? sdp_sendonly : 0; + if (um->m_mode) { /* when its inactive, keep it inactive */ + send_mode = (sdp_mode_t)(um->m_mode & sdp_sendonly); + if (rm) + send_mode = (rm->m_mode & sdp_recvonly) ? sdp_sendonly : 0; + } else send_mode = um->m_mode; recv_mode = (sdp_mode_t)(um->m_mode & sdp_recvonly); From f34dac749e6be9294f985aca370e2ccbb1a6e756 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 28 Jul 2016 14:13:37 -0500 Subject: [PATCH 078/128] revert FS-9368 --- src/mod/endpoints/mod_sofia/sofia.c | 9 ++++- src/switch_core_media.c | 54 ++++++----------------------- src/switch_rtp.c | 21 +++++------ 3 files changed, 27 insertions(+), 57 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index ed020b17c7..233c121105 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -9157,9 +9157,16 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype && sip->sip_payload && sip->sip_payload->pl_data) { if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "media_control+xml")) { + switch_core_session_t *other_session; + if (switch_channel_test_flag(channel, CF_VIDEO)) { switch_core_media_gen_key_frame(session); - switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ); + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + sofia_glue_build_vid_refresh_message(other_session, sip->sip_payload->pl_data); + switch_core_session_rwunlock(other_session); + } else { + switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ); + } } } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && diff --git a/src/switch_core_media.c b/src/switch_core_media.c index ca5aa70c28..e7aab352fb 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -1926,15 +1926,6 @@ static void check_jb(switch_core_session_t *session, const char *input, int32_t switch_rtp_set_video_buffer_size(v_engine->rtp_session, frames, max_frames); } return; - } else if (!strcasecmp(input, "vpause")) { - switch_rtp_pause_jitter_buffer(v_engine->rtp_session, SWITCH_TRUE); - return; - } else if (!strcasecmp(input, "vresume")) { - switch_rtp_pause_jitter_buffer(v_engine->rtp_session, SWITCH_FALSE); - return; - } else if (!strcasecmp(input, "vstop")) { - switch_rtp_deactivate_jitter_buffer(v_engine->rtp_session); - return; } else if (!strncasecmp(input, "vdebug:", 7)) { s = input + 7; @@ -2059,11 +2050,6 @@ static void check_jb_sync(switch_core_session_t *session) } fps = switch_core_media_get_video_fps(session); - - - if (switch_test_flag(smh, SMF_JB_PAUSED)) { - return; - } switch_rtp_get_video_buffer_size(v_engine->rtp_session, &min_frames, &max_frames, &cur_frames, NULL); @@ -2651,7 +2637,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_write_frame(switch_core_sessio return SWITCH_STATUS_GENERR; } - if (type == SWITCH_MEDIA_TYPE_AUDIO && !switch_test_flag(frame, SFF_CNG) && !switch_test_flag(frame, SFF_PROXY_PACKET)) { + if (!switch_test_flag(frame, SFF_CNG) && !switch_test_flag(frame, SFF_PROXY_PACKET)) { if (engine->read_impl.encoded_bytes_per_packet) { bytes = engine->read_impl.encoded_bytes_per_packet; frames = ((int) frame->datalen / bytes); @@ -9644,29 +9630,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se case SWITCH_MESSAGE_INDICATE_BRIDGE: { - if (switch_rtp_ready(a_engine->rtp_session) || switch_rtp_ready(v_engine->rtp_session)) { + if (switch_rtp_ready(a_engine->rtp_session)) { const char *val; - - if ( + int ok = 0; + + if (!switch_channel_test_flag(session->channel, CF_VIDEO) && (!(val = switch_channel_get_variable(session->channel, "rtp_jitter_buffer_during_bridge")) || switch_false(val))) { if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && switch_channel_test_cap_partner(session->channel, CC_FS_RTP)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s PAUSE Jitterbuffer\n", switch_channel_get_name(session->channel)); - if (a_engine->rtp_session) { - switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_TRUE); - } - - if (v_engine->rtp_session) { - switch_rtp_pause_jitter_buffer(v_engine->rtp_session, SWITCH_TRUE); - } + switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_TRUE); switch_set_flag(smh, SMF_JB_PAUSED); } } - } - - if (switch_rtp_ready(a_engine->rtp_session)) { - const char *val; - int ok = 0; if (switch_channel_test_flag(session->channel, CF_PASS_RFC2833) && switch_channel_test_flag_partner(session->channel, CF_FS_RTP)) { switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833); @@ -9713,26 +9689,18 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se } goto end; case SWITCH_MESSAGE_INDICATE_UNBRIDGE: - - if (switch_rtp_ready(a_engine->rtp_session) || switch_rtp_ready(v_engine->rtp_session)) { + if (switch_rtp_ready(a_engine->rtp_session)) { + if (switch_test_flag(smh, SMF_JB_PAUSED)) { switch_clear_flag(smh, SMF_JB_PAUSED); if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s RESUME Jitterbuffer\n", switch_channel_get_name(session->channel)); - if (a_engine->rtp_session) { - switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_FALSE); - } - - if (v_engine->rtp_session) { - switch_rtp_pause_jitter_buffer(v_engine->rtp_session, SWITCH_FALSE); - } + switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_FALSE); } } - } - - if (switch_rtp_ready(a_engine->rtp_session)) { + if (switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s deactivate passthru 2833 mode.\n", switch_channel_get_name(session->channel)); @@ -11454,7 +11422,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor frame = &write_frame; frame->img = img; - if (!switch_test_flag(frame, SFF_USE_VIDEO_TIMESTAMP)) { if (!(timer = switch_core_media_get_timer(session, SWITCH_MEDIA_TYPE_VIDEO))) { @@ -11469,7 +11436,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor frame->timestamp = timer->samplecount; } - switch_clear_flag(frame, SFF_SAME_IMAGE); frame->m = 0; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 9834045ec2..284ac2819e 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4061,7 +4061,7 @@ SWITCH_DECLARE(switch_jb_t *) switch_rtp_get_jitter_buffer(switch_rtp_t *rtp_ses SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause) { - if (!switch_rtp_ready(rtp_session) || (!rtp_session->jb && !rtp_session->vb)) { + if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) { return SWITCH_STATUS_FALSE; } @@ -4070,11 +4070,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp } if (rtp_session->pause_jb && !pause) { - if (rtp_session->vb) { - switch_jb_reset(rtp_session->vb); - } else { - switch_jb_reset(rtp_session->jb); - } + switch_jb_reset(rtp_session->jb); } rtp_session->pause_jb = pause ? 1 : 0; @@ -5650,7 +5646,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (rtp_session->has_rtp && *bytes) { uint32_t read_ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc); - if (rtp_session->vb && jb_valid(rtp_session) && !rtp_session->pause_jb) { + if (rtp_session->vb && jb_valid(rtp_session)) { status = switch_jb_put_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, *bytes); if (status == SWITCH_STATUS_TOO_LATE) { @@ -5745,7 +5741,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t } } - if (rtp_session->vb && jb_valid(rtp_session) && !rtp_session->pause_jb) { + if (rtp_session->vb && jb_valid(rtp_session)) { switch_status_t vstatus = switch_jb_get_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, bytes); status = vstatus; @@ -6335,7 +6331,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ pt = 200000; } - if (rtp_session->vb && !rtp_session->pause_jb) { + if (rtp_session->vb) { if (switch_jb_poll(rtp_session->vb)) { pt = 0; } @@ -6344,12 +6340,12 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ if ((io_flags & SWITCH_IO_FLAG_NOBLOCK)) { pt = 0; } - + poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt); //if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) { - // switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "WTF Poll %d %d\n", pt, poll_status); + // switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "WTF Poll %d\n", poll_status); //} if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && rtp_session->dtmf_data.out_digit_dur > 0) { @@ -6366,7 +6362,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } - if (poll_status == SWITCH_STATUS_SUCCESS || (rtp_session->vb && !rtp_session->pause_jb && switch_jb_poll(rtp_session->vb))) { + if (poll_status == SWITCH_STATUS_SUCCESS || (rtp_session->vb && switch_jb_poll(rtp_session->vb))) { got_rtp_poll = 1; @@ -7301,6 +7297,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session, } } + if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA) || switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { /* Normalize the timestamps to our own base by generating a made up starting point then adding the measured deltas to that base so if the timestamps and ssrc of the source change, it will not break the other end's jitter bufffer / decoder etc *cough* CHROME *cough* From 9fe7c48df7ffc937218d92b305e3d5bba06b06ea Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 28 Jul 2016 16:27:17 -0500 Subject: [PATCH 079/128] FS-9390 #resolve ['Segmentation fault' during call setup] --- src/switch_ivr_originate.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 47b49725a4..d35cb9662f 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1759,9 +1759,18 @@ static void *SWITCH_THREAD_FUNC early_thread_run(switch_thread_t *thread, void * switch_codec_implementation_t read_impl = { 0 }; for (i = 0; i < MAX_PEERS && i < state->ttl; i++) { - if (switch_core_session_read_lock(state->originate_status[i].peer_session) == SWITCH_STATUS_SUCCESS) { - originate_status[i].peer_session = state->originate_status[i].peer_session; - originate_status[i].peer_channel = switch_core_session_get_channel(state->originate_status[i].peer_session); + switch_core_session_t *session = state->originate_status[i].peer_session; + switch_channel_t *channel = NULL; + + if (session) channel = switch_core_session_get_channel(session); + + if (!session || !channel || !switch_channel_up(channel)) { + continue; + } + + if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) { + originate_status[i].peer_session = session; + originate_status[i].peer_channel = channel; } } From ac2734e90cdf7de580c83c0df46371eb57fcca29 Mon Sep 17 00:00:00 2001 From: Mike Jerris Date: Fri, 29 Jul 2016 13:36:29 -0400 Subject: [PATCH 080/128] FS-9369: [core_media] add_ice_candidates=true var to enable inserting ice candidates in outgoing sdp --- src/switch_core_media.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index e7aab352fb..cc4026fc11 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -7718,6 +7718,10 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess smh->mparams->rtcp_video_interval_msec = SWITCH_RTCP_VIDEO_INTERVAL_MSEC; } + if (switch_true(switch_channel_get_variable(session->channel, "add_ice_candidates"))) { + switch_channel_set_flag(session->channel, CF_ICE); + } + if ( switch_rtp_has_dtls() && dtls_ok(session)) { if (switch_channel_test_flag(session->channel, CF_AVPF) || switch_true(switch_channel_get_variable(smh->session->channel, "rtp_use_dtls"))) { From e2928b8a75919059277945874b5261f6fae8f7fa Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sat, 30 Jul 2016 10:27:09 +0800 Subject: [PATCH 081/128] FS-9394 #resolve fix h263 leak --- src/mod/applications/mod_av/avcodec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c index 5373400e8c..e76b4030ba 100644 --- a/src/mod/applications/mod_av/avcodec.c +++ b/src/mod/applications/mod_av/avcodec.c @@ -693,7 +693,10 @@ static switch_status_t consume_h263_bitstream(h264_codec_context_t *context, swi #endif } - if (!context->nalus[context->nalu_current_index].len) frame->m = 1; + if (!context->nalus[context->nalu_current_index].len) { + av_packet_unref(&context->encoder_avpacket); + frame->m = 1; + } #if 0 { From 589a0e682e67054bd1b2f351629b0af0e5ec3035 Mon Sep 17 00:00:00 2001 From: Muhammad Zaka Date: Fri, 17 Jun 2016 10:45:28 +0100 Subject: [PATCH 082/128] FS-9276 new feature proxy in-dialog calls sip notify and info similar to proxy hold --- .../endpoints/mod_sofia/conf/sofia.conf.xml | 21 ++++++- src/mod/endpoints/mod_sofia/mod_sofia.h | 5 ++ src/mod/endpoints/mod_sofia/sofia.c | 56 +++++++++++++++++++ src/mod/endpoints/mod_sofia/sofia_glue.c | 29 +++++++++- 4 files changed, 109 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/conf/sofia.conf.xml b/src/mod/endpoints/mod_sofia/conf/sofia.conf.xml index a03f52ac00..36502849d4 100644 --- a/src/mod/endpoints/mod_sofia/conf/sofia.conf.xml +++ b/src/mod/endpoints/mod_sofia/conf/sofia.conf.xml @@ -495,11 +495,30 @@ really need to change this. --> - + + diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 70ef0dd241..6d97c55f81 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -764,6 +764,8 @@ struct sofia_profile { ka_type_t keepalive; int bind_attempts; int bind_attempt_interval; + char *proxy_notify_events; + char *proxy_info_content_types; }; @@ -1066,6 +1068,8 @@ void sofia_reg_release_gateway__(const char *file, const char *func, int line, s #define sofia_use_soa(_t) sofia_test_flag(_t, TFLAG_ENABLE_SOA) +#define sofia_test_extra_headers(val) (((!strncasecmp(val, "X-", 2) && strncasecmp(val, "X-FS-", 5)) || !strncasecmp(val, "P-", 2) || !strncasecmp(val, "On", 2)) ? 1 : 0) + #define check_decode(_var, _session) do { \ assert(_session); \ if (!zstr(_var)) { \ @@ -1162,6 +1166,7 @@ switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *use char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix); void sofia_glue_set_extra_headers(switch_core_session_t *session, sip_t const *sip, const char *prefix); char *sofia_glue_get_extra_headers_from_event(switch_event_t *event, const char *prefix); +char *sofia_glue_get_non_extra_unknown_headers(sip_t const *sip); void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, switch_bool_t send); void sofia_send_callee_id(switch_core_session_t *session, const char *name, const char *number); int sofia_sla_supported(sip_t const *sip); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 233c121105..dad12ed7b4 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -679,6 +679,29 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, /* if no session, assume it could be an incoming notify from a gateway subscription */ if (session) { + if (!zstr(profile->proxy_notify_events) && (!strcasecmp(profile->proxy_notify_events, "all") || strstr(profile->proxy_notify_events, sip->sip_event->o_type))) { + switch_core_session_t *other_session; + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); + const char *full_to = NULL; + char *pl = NULL; + char *unknown = NULL; + + full_to = switch_str_nil(switch_channel_get_variable(switch_core_session_get_channel(other_session), "sip_full_to")); + if (sip->sip_payload && sip->sip_payload->pl_data) { + pl = switch_core_session_strdup(other_session, (char*)sip->sip_payload->pl_data); + } + unknown = sofia_glue_get_non_extra_unknown_headers(sip); + nua_notify(other_tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), + TAG_IF((full_to), SIPTAG_TO_STR(full_to)), SIPTAG_SUBSCRIPTION_STATE_STR("active"), + SIPTAG_EVENT_STR(sip->sip_event->o_type), TAG_IF(!zstr(unknown), SIPTAG_HEADER_STR(unknown)), + TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)), TAG_END()); + switch_safe_free(unknown); + switch_core_session_rwunlock(other_session); + } + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); + goto end; + } /* make sure we have a proper "talk" event */ if (strcasecmp(sip->sip_event->o_type, "talk")) { goto error; @@ -5621,6 +5644,10 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_PROXY_HOLD); } + } else if (!strcasecmp(var, "proxy-notify-events")) { + profile->proxy_notify_events = switch_core_strdup(profile->pool, val); + } else if (!strcasecmp(var, "proxy-info-content-types")) { + profile->proxy_info_content_types = switch_core_strdup(profile->pool, val); } } @@ -9114,8 +9141,37 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t assert(switch_core_session_get_private(session)); sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_INFO_HEADER_PREFIX); + if (!zstr(profile->proxy_info_content_types) && sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype && + (!strcasecmp(profile->proxy_info_content_types,"all") || strstr(profile->proxy_info_content_types,sip->sip_content_type->c_type))) { + switch_core_session_t *other_session; + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + char *pl = NULL; + char *ct = NULL; + char *extra_headers = NULL; + char *unknown = NULL; + private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); + ct = switch_core_session_strdup(other_session, (char*)sip->sip_content_type->c_type); + if (sip->sip_payload && sip->sip_payload->pl_data) { + pl = switch_core_session_strdup(other_session,(char*)sip->sip_payload->pl_data); + } + unknown = sofia_glue_get_non_extra_unknown_headers(sip); + + extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_INFO_HEADER_PREFIX); + + nua_info(other_tech_pvt->nh, + SIPTAG_CONTENT_TYPE_STR(ct), + TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), + TAG_IF(!zstr(unknown), SIPTAG_HEADER_STR(unknown)), + TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)), + TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)), + TAG_END()); + switch_safe_free(extra_headers); + switch_safe_free(unknown); + switch_core_session_rwunlock(other_session); + } + } if (sip && sip->sip_content_type && sip->sip_content_type->c_type && !strcasecmp(sip->sip_content_type->c_type, "freeswitch/data")) { char *data = NULL; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index cef4c61429..acbddcaf73 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -644,7 +644,7 @@ void sofia_glue_set_extra_headers(switch_core_session_t *session, sip_t const *s } for (un = sip->sip_unknown; un; un = un->un_next) { - if ((!strncasecmp(un->un_name, "X-", 2) && strncasecmp(un->un_name, "X-FS-", 5)) || !strncasecmp(un->un_name, "P-", 2) || !strncasecmp(un->un_name, "On", 2)) { + if (sofia_test_extra_headers(un->un_name)) { if (!zstr(un->un_value)) { switch_snprintf(name, sizeof(name), "%s%s", prefix, un->un_name); switch_channel_set_variable(channel, name, un->un_value); @@ -685,6 +685,33 @@ char *sofia_glue_get_extra_headers_from_event(switch_event_t *event, const char return extra_headers; } +char *sofia_glue_get_non_extra_unknown_headers(sip_t const *sip) +{ + char *unknown = NULL; + switch_stream_handle_t stream = { 0 }; + sip_unknown_t *un; + + if (!sip) { + return NULL; + } + + SWITCH_STANDARD_STREAM(stream); + for (un = sip->sip_unknown; un; un = un->un_next) { + if (!sofia_test_extra_headers(un->un_name)) { + if (!zstr(un->un_value)) { + stream.write_function(&stream, "%s: %s\r\n",un->un_name,un->un_value); + } + } + } + if (!zstr((char *) stream.data)) { + unknown = stream.data; + } else { + switch_safe_free(stream.data); + } + + return unknown; +} + switch_status_t sofia_glue_do_invite(switch_core_session_t *session) { char *alert_info = NULL; From 4a520d4a1e4436ff2f3001ea4b600d1fb69171cb Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Wed, 3 Aug 2016 16:44:38 -0400 Subject: [PATCH 083/128] FS-9380: switch_core_media.c , fix_ext-rtip-ip_not_used_when_originating --- src/switch_core_media.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index cc4026fc11..8b2dab05de 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -6102,6 +6102,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_choose_port(switch_core_sessio use_ip = smh->mparams->rtpip; } + if (zstr(smh->mparams->remote_ip)) { /* no remote_ip, we're originating */ + if (!zstr(smh->mparams->extrtpip)) { /* and we've got an ext-rtp-ip, eg, from verto config */ + use_ip = smh->mparams->extrtpip; /* let's use it for composing local sdp to send to client */ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, + "%s will use %s instead of %s in SDP, because we're originating and we have an ext-rtp-ip setting\n", + switch_channel_get_name(smh->session->channel), smh->mparams->extrtpip, smh->mparams->rtpip); + } + } engine->adv_sdp_port = sdp_port; engine->adv_sdp_ip = smh->mparams->adv_sdp_audio_ip = smh->mparams->extrtpip = switch_core_session_strdup(session, use_ip); From f5e8257da6ec247b913ee2439fe5de811236f5cb Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Wed, 3 Aug 2016 16:55:34 -0400 Subject: [PATCH 084/128] FS-9380: switch_core_media.c , cleaned from logging --- src/switch_core_media.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 8b2dab05de..84ce2322a3 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -6105,9 +6105,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_choose_port(switch_core_sessio if (zstr(smh->mparams->remote_ip)) { /* no remote_ip, we're originating */ if (!zstr(smh->mparams->extrtpip)) { /* and we've got an ext-rtp-ip, eg, from verto config */ use_ip = smh->mparams->extrtpip; /* let's use it for composing local sdp to send to client */ + /* switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s will use %s instead of %s in SDP, because we're originating and we have an ext-rtp-ip setting\n", switch_channel_get_name(smh->session->channel), smh->mparams->extrtpip, smh->mparams->rtpip); + */ } } engine->adv_sdp_port = sdp_port; From 9030e13589bb69546bf5c3460471191246533016 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Wed, 3 Aug 2016 18:41:18 -0500 Subject: [PATCH 085/128] FS-9401: [core,mod_amqp] fix leak in usage of hash itterator --- src/mod/event_handlers/mod_amqp/mod_amqp_logging.c | 5 +++-- src/switch_event.c | 1 + src/switch_jitterbuffer.c | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/mod/event_handlers/mod_amqp/mod_amqp_logging.c b/src/mod/event_handlers/mod_amqp/mod_amqp_logging.c index 8d4e4805be..da512cef39 100644 --- a/src/mod/event_handlers/mod_amqp/mod_amqp_logging.c +++ b/src/mod/event_handlers/mod_amqp/mod_amqp_logging.c @@ -94,12 +94,13 @@ switch_status_t mod_amqp_logging_recv(const switch_log_node_t *node, switch_log_ if (switch_queue_trypush(logging->send_queue, msg) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "AMQP logging message queue full. Messages will be dropped!\n"); - return SWITCH_STATUS_SUCCESS; + switch_safe_free(hi); + goto done; } } } - + done: switch_safe_free(json); return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_event.c b/src/switch_event.c index 58d5b81735..4ebe0f37d5 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -2752,6 +2752,7 @@ static void unsub_all_switch_event_channel(void) free(head); } + switch_safe_free(hi); switch_thread_rwlock_unlock(event_channel_manager.rwlock); } diff --git a/src/switch_jitterbuffer.c b/src/switch_jitterbuffer.c index 427498a5d2..b396dd4611 100644 --- a/src/switch_jitterbuffer.c +++ b/src/switch_jitterbuffer.c @@ -1039,7 +1039,7 @@ SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb) top: - for (hi = switch_core_hash_first(jb->missing_seq_hash); hi; hi = switch_core_hash_next(&hi)) { + for (hi = switch_core_hash_first_iter(jb->missing_seq_hash, hi); hi; hi = switch_core_hash_next(&hi)) { uint16_t seq; //const char *token; switch_time_t then = 0; @@ -1076,6 +1076,8 @@ SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb) } } + switch_safe_free(hi); + if (least && switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(least))) { jb_debug(jb, 3, "Found NACKABLE seq %u\n", least); nack = (uint32_t) htons(least); From 341e94b28d966ae47390606c5447bb56f2453465 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 3 Aug 2016 23:57:00 -0500 Subject: [PATCH 086/128] FS-8761 #resolve [Memory leak in FreeSWITCH] --- libs/sofia-sip/libsofia-sip-ua/tport/ws.c | 6 +++--- src/mod/endpoints/mod_verto/ws.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c index 7fe9f182bf..f3783c024e 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c @@ -547,9 +547,9 @@ static int establish_logical_layer(wsh_t *wsh) wsh->sanity--; - if (!wsh->block) { - return -2; - } + //if (!wsh->block) { + // return -2; + //} } while (wsh->sanity > 0); diff --git a/src/mod/endpoints/mod_verto/ws.c b/src/mod/endpoints/mod_verto/ws.c index 265dd10d8e..954e9f43df 100644 --- a/src/mod/endpoints/mod_verto/ws.c +++ b/src/mod/endpoints/mod_verto/ws.c @@ -547,9 +547,9 @@ static int establish_logical_layer(wsh_t *wsh) wsh->sanity--; - if (!wsh->block) { - return -2; - } + //if (!wsh->block) { + //return -2; + //} } while (wsh->sanity > 0); From 1ba5f069478dccdb05d0eccddfd03a0075d1ba44 Mon Sep 17 00:00:00 2001 From: William Henry Date: Thu, 4 Aug 2016 09:44:19 -0400 Subject: [PATCH 087/128] FS-9403 #resolve [add timestamp for when user was pushed into queue that lives with the channel] --- src/mod/applications/mod_fifo/mod_fifo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index cda0386eb6..0bb89ecd69 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -2756,6 +2756,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm); switch_channel_set_variable(channel, "fifo_status", "WAITING"); switch_channel_set_variable(channel, "fifo_timestamp", date); + switch_channel_set_variable(channel, "fifo_push_timestamp", date); switch_channel_set_variable(channel, "fifo_serviced_uuid", NULL); switch_channel_set_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_BRIDGE_TAG); From 61c487c3e8c852765b3a454c523ff3ee1e5a003c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 6 Aug 2016 11:47:07 -0500 Subject: [PATCH 088/128] Revert "FS-8761 #resolve [Memory leak in FreeSWITCH]" This reverts commit 341e94b28d966ae47390606c5447bb56f2453465. --- libs/sofia-sip/libsofia-sip-ua/tport/ws.c | 6 +++--- src/mod/endpoints/mod_verto/ws.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c index f3783c024e..7fe9f182bf 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c @@ -547,9 +547,9 @@ static int establish_logical_layer(wsh_t *wsh) wsh->sanity--; - //if (!wsh->block) { - // return -2; - //} + if (!wsh->block) { + return -2; + } } while (wsh->sanity > 0); diff --git a/src/mod/endpoints/mod_verto/ws.c b/src/mod/endpoints/mod_verto/ws.c index 954e9f43df..265dd10d8e 100644 --- a/src/mod/endpoints/mod_verto/ws.c +++ b/src/mod/endpoints/mod_verto/ws.c @@ -547,9 +547,9 @@ static int establish_logical_layer(wsh_t *wsh) wsh->sanity--; - //if (!wsh->block) { - //return -2; - //} + if (!wsh->block) { + return -2; + } } while (wsh->sanity > 0); From 1e7b4a13016608ac353156bdfc5e0aa180aebe62 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 6 Aug 2016 11:49:21 -0500 Subject: [PATCH 089/128] FS-8761 #resolve [Memory leak in FreeSWITCH] --- libs/sofia-sip/.update | 2 +- .../libsofia-sip-ua/tport/tport_type_ws.c | 17 ++++++++++++++++- libs/sofia-sip/libsofia-sip-ua/tport/tport_ws.h | 1 + libs/sofia-sip/libsofia-sip-ua/tport/ws.c | 2 +- libs/sofia-sip/libsofia-sip-ua/tport/ws.h | 2 +- 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index b9f2e8ad18..b824aceab0 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Wed Jul 27 14:15:49 CDT 2016 +Sat Aug 6 11:48:53 CDT 2016 diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c index 050b2f8364..1390689513 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c @@ -461,6 +461,7 @@ int tport_ws_init_secondary(tport_t *self, int socket, int accepted, tport_ws_t *wstp = (tport_ws_t *)self; self->tp_has_connection = 1; + self->tp_params->tpp_keepalive = 5000; /* override the default 30 minute timeout on tport connections */ self->tp_params->tpp_idle = UINT_MAX; @@ -496,7 +497,7 @@ int tport_ws_init_secondary(tport_t *self, int socket, int accepted, wstp->ws_initialized = 1; self->tp_pre_framed = 1; - + tport_set_secondary_timer(self); return 0; } @@ -592,6 +593,20 @@ int tport_ws_next_timer(tport_t *self, su_time_t *return_target, char const **return_why) { + tport_ws_t *wstp = (tport_ws_t *)self; + + if (establish_logical_layer(&wstp->ws) < 0) { + if (wstp->tos++ == 1) { + tport_close(self); + SU_DEBUG_7(("%s(%p): %s to " TPN_FORMAT "%s\n", + __func__, (void *)self, + "timeout establishing connection\n", TPN_ARGS(self->tp_name), "")); + return -1; + } + } else { + self->tp_params->tpp_keepalive = 30000; + } + return tport_next_recv_timeout(self, return_target, return_why) | tport_next_keepalive(self, return_target, return_why); diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_ws.h b/libs/sofia-sip/libsofia-sip-ua/tport/tport_ws.h index d48101e5cb..4e2e0f474d 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_ws.h +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_ws.h @@ -59,6 +59,7 @@ typedef struct tport_ws_s { char wstp_buffer[65536]; size_t wstp_buflen; SU_S8_T ws_initialized; + unsigned char tos; unsigned ws_secure:1; unsigned:0; } tport_ws_t; diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c index 7fe9f182bf..5e5bbd638d 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c @@ -500,7 +500,7 @@ static int restore_socket(ws_socket_t sock) #endif -static int establish_logical_layer(wsh_t *wsh) +int establish_logical_layer(wsh_t *wsh) { if (!wsh->sanity) { diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.h b/libs/sofia-sip/libsofia-sip-ua/tport/ws.h index 045ff32acc..83a6890cca 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.h +++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.h @@ -119,7 +119,7 @@ typedef struct wsh_s { ssize_t ws_send_buf(wsh_t *wsh, ws_opcode_t oc); ssize_t ws_feed_buf(wsh_t *wsh, void *data, size_t bytes); - +int establish_logical_layer(wsh_t *wsh); ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block); ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes); ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data); From 5f5346491943417c7609b834712ee4e5846d3605 Mon Sep 17 00:00:00 2001 From: Josh Allmann Date: Sat, 6 Aug 2016 02:25:11 +0000 Subject: [PATCH 090/128] FS-9409: Wait for avformat reader thread before reading. Attempting to read before the reader thread is ready causes a spurious EOF and skipped playback. --- src/mod/applications/mod_av/avformat.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index 7d0ca45815..7546ad6391 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -1239,6 +1239,7 @@ SWITCH_STANDARD_API(av_format_api_function) struct av_file_context { switch_memory_pool_t *pool; switch_mutex_t *mutex; + switch_thread_cond_t *cond; switch_buffer_t *buf; switch_buffer_t *audio_buffer; switch_timer_t video_timer; @@ -1261,6 +1262,7 @@ struct av_file_context { record_helper_t eh; switch_thread_t *file_read_thread; int file_read_thread_running; + int file_read_thread_started; switch_time_t video_start_time; switch_image_t *last_img; int read_fps; @@ -1417,7 +1419,11 @@ static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, vo int sync = 0; int eof = 0; + switch_mutex_lock(context->mutex); + context->file_read_thread_started = 1; context->file_read_thread_running = 1; + switch_thread_cond_signal(context->cond); + switch_mutex_unlock(context->mutex); while (context->file_read_thread_running && !context->closed) { int vid_frames = 0; @@ -1684,6 +1690,7 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa } switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool); + switch_thread_cond_create(&context->cond, handle->memory_pool); switch_buffer_create_dynamic(&context->audio_buffer, 512, 512, 0); if (!context->audio_buffer) { @@ -2064,6 +2071,12 @@ static switch_status_t av_file_read(switch_file_handle_t *handle, void *data, si return SWITCH_STATUS_SUCCESS; } + switch_mutex_lock(context->mutex); + while (!context->file_read_thread_started) { + switch_thread_cond_wait(context->cond, context->mutex); + } + switch_mutex_unlock(context->mutex); + if (!context->file_read_thread_running && switch_buffer_inuse(context->audio_buffer) == 0) { *len = 0; return SWITCH_STATUS_FALSE; From 9fbf9d02e34066c6d7dd19d9fb080df1b6f02089 Mon Sep 17 00:00:00 2001 From: Piotr Gregor Date: Mon, 8 Aug 2016 17:23:57 +0100 Subject: [PATCH 091/128] FS-9069: [mod_avmd] add detection time to beep event Add detection time to BEEP event and total session running time to STOP event. --- src/mod/applications/mod_avmd/mod_avmd.c | 79 ++++++++++++++++++------ 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index 6fb0471f90..e7ee38d0f5 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -182,7 +182,7 @@ typedef struct { double f; /* freq_table_t ft; */ avmd_state_t state; - switch_time_t start_time; + switch_time_t start_time, stop_time, detection_start_time, detection_stop_time; size_t samples_streak; /* number of DESA samples in single streak without reset needed to validate SMA estimator */ size_t sample_count; } avmd_session_t; @@ -202,7 +202,8 @@ static switch_status_t avmd_register_all_events(void); static void avmd_unregister_all_events(void); static void -avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, double v_freq, double amp, double v_amp, avmd_beep_state_t beep_status, uint8_t info); +avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, double v_freq, double amp, double v_amp, avmd_beep_state_t beep_status, uint8_t info, + switch_time_t detection_start_time, switch_time_t detection_stop_time, switch_time_t start_time, switch_time_t stop_time); /* API [set default], reset to factory settings */ static void avmd_set_xml_default_configuration(switch_mutex_t *mutex); @@ -259,6 +260,8 @@ init_avmd_session_data(avmd_session_t *avmd_session, switch_core_session_t *fs_s memcpy(&avmd_session->settings, &avmd_globals.settings, sizeof(struct avmd_settings)); switch_mutex_init(&avmd_session->mutex, SWITCH_MUTEX_DEFAULT, switch_core_session_get_pool(fs_session)); avmd_session->sample_count = 0; + avmd_session->detection_start_time = 0; + avmd_session->detection_stop_time = 0; buf_sz = BEEP_LEN((uint32_t)avmd_session->rate) / (uint32_t)SINE_LEN(avmd_session->rate); if (buf_sz < 1) { @@ -424,9 +427,11 @@ avmd_unregister_all_events(void) } static void -avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, double v_freq, double amp, double v_amp, avmd_beep_state_t beep_status, uint8_t info) { +avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, double v_freq, double amp, double v_amp, avmd_beep_state_t beep_status, uint8_t info, + switch_time_t detection_start_time, switch_time_t detection_stop_time, switch_time_t start_time, switch_time_t stop_time) { int res; switch_event_t *event; + switch_time_t detection_time, total_time; switch_status_t status; switch_event_t *event_copy; char buf[AVMD_CHAR_BUF_LEN]; @@ -467,9 +472,23 @@ avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Amplitude-variance", "ERROR (TRUNCATED)"); } switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Amplitude-variance", buf); + + detection_time = detection_stop_time - detection_start_time; + res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%" PRId64 "", detection_time); + if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Detection time truncated [%s], [%d] attempted!\n", buf, res); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detection-time", "ERROR (TRUNCATED)"); + } + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detection-time", buf); break; case AVMD_EVENT_SESSION_START: + res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%" PRId64 "", start_time); + if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Start time truncated [%s], [%d] attempted!\n", buf, res); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Start-time", "ERROR (TRUNCATED)"); + } + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Start-time", buf); break; case AVMD_EVENT_SESSION_STOP: @@ -478,6 +497,13 @@ avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Error, avmd session object not found in media bug!\n"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "stop-status", "ERROR (AVMD SESSION OBJECT NOT FOUND IN MEDIA BUG)"); } + total_time = stop_time - start_time; + res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%" PRId64 "", total_time); + if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Total time truncated [%s], [%d] attempted!\n", buf, res); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Total-time", "ERROR (TRUNCATED)"); + } + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Total-time", buf); break; default: @@ -1084,7 +1110,7 @@ SWITCH_STANDARD_APP(avmd_start_app) goto end; } switch_channel_set_private(channel, "_avmd_", bug); /* Set the avmd tag to detect an existing avmd media bug */ - avmd_fire_event(AVMD_EVENT_SESSION_START, session, 0, 0, 0, 0, 0, 0); + avmd_fire_event(AVMD_EVENT_SESSION_START, session, 0, 0, 0, 0, 0, 0, 0, 0, avmd_session->start_time, 0); if (avmd_session->settings.report_status == 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Avmd on channel [%s] started!\n", switch_channel_get_name(channel)); } @@ -1099,6 +1125,7 @@ SWITCH_STANDARD_APP(avmd_stop_app) switch_media_bug_t *bug; switch_channel_t *channel; avmd_session_t *avmd_session; + switch_time_t start_time, stop_time, total_time; uint8_t report_status = 0, avmd_found = 1; avmd_beep_state_t beep_status = BEEP_NOTDETECTED; @@ -1137,18 +1164,20 @@ SWITCH_STANDARD_APP(avmd_stop_app) switch_mutex_lock(avmd_session->mutex); report_status = avmd_session->settings.report_status; beep_status = avmd_session->state.beep_state; + avmd_session->stop_time = switch_micro_time_now(); + start_time = avmd_session->start_time; + stop_time = avmd_session->stop_time; + total_time = stop_time - start_time; switch_mutex_unlock(avmd_session->mutex); } switch_channel_set_private(channel, "_avmd_", NULL); switch_core_media_bug_remove(session, &bug); if (avmd_found == 1) { - avmd_fire_event(AVMD_EVENT_SESSION_STOP, session, 0, 0, 0, 0, beep_status, 1); - } else { - avmd_fire_event(AVMD_EVENT_SESSION_STOP, session, 0, 0, 0, 0, beep_status, 0); - } - if (report_status == 1) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Avmd on channel [%s] stopped, beep status: [%s]\n", - switch_channel_get_name(channel), beep_status == BEEP_DETECTED ? "DETECTED" : "NOTDETECTED"); + avmd_fire_event(AVMD_EVENT_SESSION_STOP, session, 0, 0, 0, 0, beep_status, 1, 0, 0, start_time, stop_time); + if (report_status == 1) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Avmd on channel [%s] stopped, beep status: [%s], total running time [%" PRId64 "] [us]\n", + switch_channel_get_name(channel), beep_status == BEEP_DETECTED ? "DETECTED" : "NOTDETECTED", total_time); + } } return; } @@ -1405,15 +1434,19 @@ SWITCH_STANDARD_API(avmd_api_main) if (bug != NULL) { /* If we have a stop remove audio bug */ if (strcasecmp(command, "stop") == 0) { + avmd_session = (avmd_session_t*) switch_core_media_bug_get_user_data(bug); + if (avmd_session == NULL) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_session), SWITCH_LOG_ERROR, "Stop failed - no avmd session object" + " on this channel [%s]!\n", switch_channel_get_name(channel)); + goto end; + } uuid_dup = switch_core_strdup(switch_core_session_get_pool(fs_session), uuid); switch_channel_set_private(channel, "_avmd_", NULL); switch_core_media_bug_remove(fs_session, &bug); - avmd_fire_event(AVMD_EVENT_SESSION_STOP, fs_session, 0, 0, 0, 0, 0, 0); + avmd_fire_event(AVMD_EVENT_SESSION_STOP, fs_session, 0, 0, 0, 0, 0, 0, 0, 0, avmd_session->start_time, avmd_session->stop_time); if (avmd_globals.settings.report_status == 1) { - stream->write_function(stream, "+OK\n [%s] [%s] stopped\n\n", - uuid_dup, switch_channel_get_name(channel)); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_session), SWITCH_LOG_INFO, - "Avmd on channel [%s] stopped!\n", switch_channel_get_name(channel)); + stream->write_function(stream, "+OK\n [%s] [%s] stopped\n\n", uuid_dup, switch_channel_get_name(channel)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_session), SWITCH_LOG_INFO, "Avmd on channel [%s] stopped!\n", switch_channel_get_name(channel)); } goto end; } @@ -1529,7 +1562,7 @@ SWITCH_STANDARD_API(avmd_api_main) switch_channel_set_private(channel, "_avmd_", bug); /* Set the vmd tag to detect an existing vmd media bug */ - avmd_fire_event(AVMD_EVENT_SESSION_START, fs_session, 0, 0, 0, 0, 0, 0); + avmd_fire_event(AVMD_EVENT_SESSION_START, fs_session, 0, 0, 0, 0, 0, 0, 0, 0, avmd_session->start_time, 0); if (avmd_globals.settings.report_status == 1) { stream->write_function(stream, "+OK\n [%s] [%s] started!\n\n", uuid, switch_channel_get_name(channel)); @@ -1556,6 +1589,7 @@ end: */ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) { switch_channel_t *channel; + switch_time_t detection_time; circ_buffer_t *b; size_t pos; double omega, amplitude; @@ -1570,6 +1604,9 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) { /* If beep has already been detected skip the CPU heavy stuff */ if (s->state.beep_state == BEEP_DETECTED) return; + if (s->detection_start_time == 0) { + s->detection_start_time = switch_micro_time_now(); /* start detection timer */ + } /* Precompute values used heavily in the inner loop */ sine_len_i = (uint32_t) SINE_LEN(s->rate); @@ -1678,11 +1715,13 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) { sma_digital_freq = 0.5 * acos(s->sma_b.sma); #endif /* !WIN32 && AVMD_FAST_MATH */ - switch_channel_set_variable_printf(channel, "avmd_total_time", "[%d]", (int)(switch_micro_time_now() - s->start_time) / 1000); + s->detection_stop_time = switch_micro_time_now(); /* stop detection timer */ + detection_time = s->detection_stop_time - s->detection_start_time; /* detection time length */ + switch_channel_set_variable_printf(channel, "avmd_total_time", "[%" PRId64 "]", detection_time / 1000); switch_channel_execute_on(channel, "execute_on_avmd_beep"); - avmd_fire_event(AVMD_EVENT_BEEP, s->session, TO_HZ(s->rate, sma_digital_freq), v, s->sma_amp_b.sma, v_amp, 0, 0); + avmd_fire_event(AVMD_EVENT_BEEP, s->session, TO_HZ(s->rate, sma_digital_freq), v, s->sma_amp_b.sma, v_amp, 0, 0, s->detection_start_time, s->detection_stop_time, 0, 0); if (s->settings.report_status == 1) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_INFO, "<<< AVMD - Beep Detected: f = [%f] variance = [%f], amplitude = [%f] variance = [%f] >>>\n", TO_HZ(s->rate, sma_digital_freq), v, s->sma_amp_b.sma, v_amp); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_INFO, "<<< AVMD - Beep Detected: f = [%f] variance = [%f], amplitude = [%f] variance = [%f], detection time [%" PRId64 "] [us] >>>\n", TO_HZ(s->rate, sma_digital_freq), v, s->sma_amp_b.sma, v_amp, detection_time); } switch_channel_set_variable(channel, "avmd_detect", "TRUE"); RESET_SMA_BUFFER(&s->sma_b); From 8abc16f501816307d45304f090c56fccd7b09a21 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 8 Aug 2016 16:39:44 -0500 Subject: [PATCH 092/128] FS-8761 --- libs/sofia-sip/.update | 2 +- .../libsofia-sip-ua/tport/tport_type_ws.c | 30 ++++++++++++++----- .../libsofia-sip-ua/tport/tport_ws.h | 2 +- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index b824aceab0..0ef1bfcdf6 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Sat Aug 6 11:48:53 CDT 2016 +Mon Aug 8 16:39:35 CDT 2016 diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c index 1390689513..6b525581f1 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c @@ -494,6 +494,8 @@ int tport_ws_init_secondary(tport_t *self, int socket, int accepted, return *return_reason = "WS_INIT", -1; } + wstp->connected = time(NULL); + wstp->ws_initialized = 1; self->tp_pre_framed = 1; @@ -594,19 +596,31 @@ int tport_ws_next_timer(tport_t *self, char const **return_why) { tport_ws_t *wstp = (tport_ws_t *)self; + int ll = establish_logical_layer(&wstp->ws); + int punt = 0; - if (establish_logical_layer(&wstp->ws) < 0) { - if (wstp->tos++ == 1) { - tport_close(self); - SU_DEBUG_7(("%s(%p): %s to " TPN_FORMAT "%s\n", - __func__, (void *)self, - "timeout establishing connection\n", TPN_ARGS(self->tp_name), "")); - return -1; + if (ll == -1) { + punt = 1; + } else if (ll < 0) { + time_t now = time(NULL); + if (now - wstp->connected > 5) { + punt = 2; } } else { - self->tp_params->tpp_keepalive = 30000; + self->tp_params->tpp_keepalive = 0; } + if (punt) { + tport_close(self); + + SU_DEBUG_7(("%s(%p): %s to " TPN_FORMAT "%s\n", + __func__, (void *)self, + (punt == 2 ? "Timeout establishing SSL" : "Error establishing SSL"), TPN_ARGS(self->tp_name), "")); + + return -1; + } + + return tport_next_recv_timeout(self, return_target, return_why) | tport_next_keepalive(self, return_target, return_why); diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_ws.h b/libs/sofia-sip/libsofia-sip-ua/tport/tport_ws.h index 4e2e0f474d..d43e02e2ca 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_ws.h +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_ws.h @@ -59,7 +59,7 @@ typedef struct tport_ws_s { char wstp_buffer[65536]; size_t wstp_buflen; SU_S8_T ws_initialized; - unsigned char tos; + time_t connected; unsigned ws_secure:1; unsigned:0; } tport_ws_t; From 79689c4109d70513954c43d9e4858d12d12b91dd Mon Sep 17 00:00:00 2001 From: Italo Rossi Date: Tue, 9 Aug 2016 16:17:30 -0500 Subject: [PATCH 093/128] FS-9415 [mod_spy] - Increasing loop so we can also look for variable_verto_user and variable_verto_host --- 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 cc737517c1..fd213ffec4 100644 --- a/src/mod/applications/mod_spy/mod_spy.c +++ b/src/mod/applications/mod_spy/mod_spy.c @@ -168,7 +168,7 @@ static switch_status_t process_event(switch_event_t *event) char *username[5] = { NULL }; char *domain[5] = { NULL }; char key[512]; - char *uuid = NULL, *my_uuid = NULL; + char *my_uuid = NULL; int i; int found = 0; @@ -203,7 +203,7 @@ static switch_status_t process_event(switch_event_t *event) } } - for (i = 0; i < 4; i++) { + for (i = 0; i < 5; i++) { if (username[i] && domain[i]) { spy_t *spy = NULL; @@ -215,7 +215,7 @@ static switch_status_t process_event(switch_event_t *event) switch_channel_t *channel = switch_core_session_get_channel(session); my_uuid = switch_event_get_header(event, "Unique-ID"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UserSpy retrieved uuid %s for key %s, activating eavesdrop\n", uuid, key); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UserSpy retrieved uuid %s for key %s, activating eavesdrop\n", my_uuid, key); switch_channel_set_variable(channel, "spy_uuid", my_uuid); found++; From c79441d84ef5132596e20e0d9d1469aacc24e844 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 10 Aug 2016 21:57:42 -0500 Subject: [PATCH 094/128] try to deliver locally to verto too --- src/mod/endpoints/mod_verto/mod_verto.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 8316620cc2..03361aaffa 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -161,7 +161,7 @@ static void close_socket(ws_socket_t *sock) } } - +void verto_broadcast(const char *event_channel, cJSON *json, const char *key, switch_event_channel_id_t id); static int ssl_init = 0; static int verto_init_ssl(verto_profile_t *profile) @@ -3819,8 +3819,10 @@ static switch_bool_t verto__broadcast_func(const char *method, cJSON *params, js } jevent = cJSON_Duplicate(params, 1); + verto_broadcast(event_channel, jevent, modname, globals.event_channel_id); switch_event_channel_broadcast(event_channel, &jevent, modname, globals.event_channel_id); + if (jsock->profile->mcast_pub.sock != ws_sock_invalid) { if ((json_text = cJSON_PrintUnformatted(params))) { From a3648f244fd739749e78b2363bf363890b036cc6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 11 Aug 2016 10:04:01 -0500 Subject: [PATCH 095/128] tweak on yesterday's commit --- html5/verto/video_demo/verto.js | 2 +- src/mod/endpoints/mod_verto/mod_verto.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/html5/verto/video_demo/verto.js b/html5/verto/video_demo/verto.js index 997d63a119..aba518952b 100644 --- a/html5/verto/video_demo/verto.js +++ b/html5/verto/video_demo/verto.js @@ -21,7 +21,7 @@ var master = null; var canvas_id = null; var second_screen = null; var save_settings = true; - +var vertoHandle = null; var video_screen = "webcam" $( ".selector" ).pagecontainer({ "theme": "a" }); diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 03361aaffa..8ce0020475 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -3819,7 +3819,7 @@ static switch_bool_t verto__broadcast_func(const char *method, cJSON *params, js } jevent = cJSON_Duplicate(params, 1); - verto_broadcast(event_channel, jevent, modname, globals.event_channel_id); + write_event(event_channel, NULL, jevent); switch_event_channel_broadcast(event_channel, &jevent, modname, globals.event_channel_id); From 48cec71c7635ad2d353908b825dc0ae8ae2dd1dd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 11 Aug 2016 10:41:42 -0500 Subject: [PATCH 096/128] FS-9419 #resolve [Add event_channel_broadcast api] --- .../applications/mod_commands/mod_commands.c | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 135896e60f..64d25dd315 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -6900,6 +6900,38 @@ SWITCH_STANDARD_JSON_API(json_execute_function) return status; } +SWITCH_STANDARD_API(event_channel_broadcast_api_function) +{ + cJSON *jdata = NULL; + const char *channel; + + if (!cmd) { + stream->write_function(stream, "-ERR parsing channel\n", SWITCH_VA_NONE); + return SWITCH_STATUS_SUCCESS; + } + + if (!(jdata = cJSON_Parse(cmd))) { + stream->write_function(stream, "-ERR parsing json\n"); + } + + + if (jdata) { + if (!(channel = cJSON_GetObjectCstr(jdata, "eventChannel"))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO EVENT CHANNEL SPECIFIED\n"); + } else { + switch_event_channel_broadcast(channel, &jdata, modname, NO_EVENT_CHANNEL_ID); + stream->write_function(stream, "+OK message sent\n", SWITCH_VA_NONE); + } + + if (jdata) { + cJSON_Delete(jdata); + } + } + + return SWITCH_STATUS_SUCCESS; + +} + SWITCH_STANDARD_JSON_API(json_api_function) { cJSON *data, *cmd, *arg, *reply; @@ -7090,6 +7122,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "db_cache", "Manage db cache", db_cache_function, "status"); SWITCH_ADD_API(commands_api_interface, "domain_exists", "Check if a domain exists", domain_exists_function, ""); SWITCH_ADD_API(commands_api_interface, "echo", "Echo", echo_function, ""); + SWITCH_ADD_API(commands_api_interface, "event_channel_broadcast", "Broadcast", event_channel_broadcast_api_function, " "); SWITCH_ADD_API(commands_api_interface, "escape", "Escape a string", escape_function, ""); SWITCH_ADD_API(commands_api_interface, "eval", "eval (noop)", eval_function, "[uuid: ]"); SWITCH_ADD_API(commands_api_interface, "expand", "Execute an api with variable expansion", expand_function, "[uuid: ] "); From 5b71dffb8004c6e7045afeaf42c6a785c7496975 Mon Sep 17 00:00:00 2001 From: Spencer Thomason Date: Thu, 19 May 2016 13:28:01 -0700 Subject: [PATCH 097/128] FS-9183: [mod_sofia] Handle 415 Unsupported Media Type as 488 Handle 415 Unsupported Media Type the same as 488 Not Acceptable Here after t.38 ReINVITE. This resolves an issue where the call would fail and translates the response code to the more standard 488 Not Acceptable Here allowing the call to continue in audio mode. FS-9183 #resolve --- src/mod/endpoints/mod_sofia/sofia.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index dad12ed7b4..0330dc1941 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6526,6 +6526,12 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status switch_core_media_proxy_remote_addr(session, NULL); } + if (status == 415) { + int new_status = 488; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Overriding %d %s with %d\n", status, phrase, new_status); + status = new_status; + } + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing %d %s to other leg\n%s\n", status, phrase, switch_str_nil(r_sdp)); if (switch_core_session_compare(session, other_session)) { From 2febb55761a83d5b295e784056f59238dc4e4754 Mon Sep 17 00:00:00 2001 From: Spencer Thomason Date: Thu, 11 Aug 2016 18:42:23 -0700 Subject: [PATCH 098/128] FS-9424 #resolve Define byte order correctly on Solaris/SPARC --- src/include/switch_platform.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/include/switch_platform.h b/src/include/switch_platform.h index 962bf972b3..00909770ee 100644 --- a/src/include/switch_platform.h +++ b/src/include/switch_platform.h @@ -139,6 +139,9 @@ typedef int gid_t; #ifndef __BYTE_ORDER #ifdef SWITCH_BYTE_ORDER #define __BYTE_ORDER SWITCH_BYTE_ORDER +/* solaris */ +#elif defined(_BIG_ENDIAN) +#define __BYTE_ORDER __BIG_ENDIAN #else #define __BYTE_ORDER __LITTLE_ENDIAN #endif From 2e3227b50f897ab7471b09979ba25b6ca0ff5887 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 12 Aug 2016 14:10:23 -0500 Subject: [PATCH 099/128] FS-9422 #resolve [Freeswitch Exit/Crash on SDP Negotiation] #comment renegotiate-codec-on-hold renegotiate-codec-on-reinvite are both removed in this commit --- src/include/switch_core_media.h | 2 - src/mod/endpoints/mod_sofia/mod_sofia.c | 1 - src/mod/endpoints/mod_sofia/sofia.c | 13 ----- src/mod/endpoints/mod_verto/mod_verto.c | 2 - src/switch_core_media.c | 67 +++++-------------------- 5 files changed, 12 insertions(+), 73 deletions(-) diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 988ebbea42..096bc815fc 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -64,8 +64,6 @@ typedef enum { SCMF_CODEC_GREEDY, SCMF_CODEC_SCROOGE, SCMF_DISABLE_HOLD, - SCMF_RENEG_ON_HOLD, - SCMF_RENEG_ON_REINVITE, SCMF_LIBERAL_DTMF, SCMF_SUPPRESS_CNG, SCMF_DISABLE_RTP_AUTOADJ, diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index b43be77da4..36ef8b06b9 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1213,7 +1213,6 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi case SWITCH_MESSAGE_INDICATE_MEDIA_RENEG: { if (msg->string_arg) { - sofia_set_media_flag(tech_pvt->profile, SCMF_RENEG_ON_REINVITE); sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA); } diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index dad12ed7b4..8d561c3f80 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -4330,7 +4330,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) sofia_set_pflag(profile, PFLAG_ENABLE_CHAT); profile->auto_restart = 1; sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING); - sofia_set_media_flag(profile, SCMF_RENEG_ON_REINVITE); sofia_set_media_flag(profile, SCMF_RTP_AUTOFLUSH_DURING_BRIDGE); profile->contact_user = SOFIA_DEFAULT_CONTACT_USER; sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID); @@ -4609,18 +4608,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_IGNORE_183NOSDP); } - } else if (!strcasecmp(var, "renegotiate-codec-on-hold")) { - if (switch_true(val)) { - sofia_set_media_flag(profile, SCMF_RENEG_ON_HOLD); - } else { - sofia_clear_media_flag(profile, SCMF_RENEG_ON_HOLD); - } - } else if (!strcasecmp(var, "renegotiate-codec-on-reinvite")) { - if (switch_true(val)) { - sofia_set_media_flag(profile, SCMF_RENEG_ON_REINVITE); - } else { - sofia_clear_media_flag(profile, SCMF_RENEG_ON_REINVITE); - } } else if (!strcasecmp(var, "presence-probe-on-register")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER); diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 8ce0020475..817b0e837e 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -2389,8 +2389,6 @@ static void verto_set_media_options(verto_pvt_t *tech_pvt, verto_profile_t *prof tech_pvt->mparams->jb_msec = "-1"; switch_media_handle_set_media_flag(tech_pvt->smh, SCMF_SUPPRESS_CNG); - switch_media_handle_set_media_flag(tech_pvt->smh, SCMF_RENEG_ON_REINVITE); - //tech_pvt->mparams->auto_rtp_bugs = profile->auto_rtp_bugs; tech_pvt->mparams->timer_name = profile->timer_name; //tech_pvt->mparams->vflags = profile->vflags; diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 84ce2322a3..03678e6e33 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -1868,7 +1868,6 @@ SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *ses switch_channel_set_variable(session->channel, "rtp_use_codec_string", codec_string); smh->codec_order_last = switch_separate_string(tmp_codec_string, ',', smh->codec_order, SWITCH_MAX_CODECS); smh->mparams->num_codecs = switch_loadable_module_get_codecs_sorted(smh->codecs, smh->fmtp, SWITCH_MAX_CODECS, smh->codec_order, smh->codec_order_last); - } static void check_jb(switch_core_session_t *session, const char *input, int32_t jb_msec, int32_t maxlen, switch_bool_t silent) @@ -3716,7 +3715,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s int scrooge = 0; sdp_parser_t *parser = NULL; sdp_session_t *sdp; - int reneg = 1; const switch_codec_implementation_t **codec_array; int total_codecs; switch_rtp_engine_t *a_engine, *v_engine; @@ -4104,48 +4102,15 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s && switch_true(val))) && !smh->mparams->hold_laps) { smh->mparams->hold_laps++; - if (switch_core_media_toggle_hold(session, sendonly)) { - reneg = switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_HOLD); - if ((val = switch_channel_get_variable(session->channel, "rtp_renegotiate_codec_on_hold"))) { - reneg = switch_true(val); - } - } - } - - if (reneg) { - reneg = switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_REINVITE); - - if ((val = switch_channel_get_variable(session->channel, "rtp_renegotiate_codec_on_reinvite"))) { - reneg = switch_true(val); - } - } - - if (session->bugs) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, - "Session is connected to a media bug. " - "Re-Negotiation implicitly disabled.\n"); - reneg = 0; - } - - if (switch_channel_test_flag(session->channel, CF_RECOVERING)) { - reneg = 0; - } - - if (sdp_type == SDP_TYPE_RESPONSE && smh->num_negotiated_codecs) { - /* response to re-invite or update, only negotiated codecs are valid */ - reneg = 0; + switch_core_media_toggle_hold(session, sendonly); } - if (!reneg && smh->num_negotiated_codecs) { - codec_array = smh->negotiated_codecs; - total_codecs = smh->num_negotiated_codecs; - } else if (reneg) { - smh->mparams->num_codecs = 0; - switch_core_media_prepare_codecs(session, SWITCH_FALSE); - codec_array = smh->codecs; - total_codecs = smh->mparams->num_codecs; - } + smh->mparams->num_codecs = 0; + smh->num_negotiated_codecs = 0; + switch_core_media_prepare_codecs(session, SWITCH_FALSE); + codec_array = smh->codecs; + total_codecs = smh->mparams->num_codecs; if (switch_rtp_has_dtls() && dtls_ok(session)) { @@ -4207,7 +4172,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s } x = 0; - + for (map = m->m_rtpmaps; map; map = map->rm_next) { int32_t i; const char *rm_encoding; @@ -4439,7 +4404,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s match = 1; a_engine->codec_negotiated = 1; - smh->num_negotiated_codecs = 0; for(j = 0; j < m_idx; j++) { payload_map_t *pmap = switch_core_media_add_payload_map(session, @@ -4498,6 +4462,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s pmap->rm_fmtp = switch_core_session_strdup(session, (char *) mmap->rm_fmtp); pmap->agreed_pt = (switch_payload_t) mmap->rm_pt; + smh->negotiated_codecs[smh->num_negotiated_codecs++] = mimp; pmap->recv_pt = (switch_payload_t)mmap->rm_pt; @@ -4531,14 +4496,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s -#if 0 - if (!switch_true(mirror) && - switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && - (!switch_channel_test_flag(session->channel, CF_REINVITE) || switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_REINVITE))) { - switch_core_media_get_offered_pt(session, matches[0].imp, &a_engine->cur_payload_map->recv_pt); - } -#endif - switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->recv_pt); switch_channel_set_variable(session->channel, "rtp_audio_recv_pt", tmp); @@ -4786,10 +4743,11 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (!(rm_encoding = map->rm_encoding)) { rm_encoding = ""; } + printf("WTF TOT %d\n", total_codecs); for (i = 0; i < total_codecs; i++) { const switch_codec_implementation_t *imp = codec_array[i]; - + if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) { continue; } @@ -4825,7 +4783,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d] +++ is saved as a match\n", imp->iananame, map->rm_pt); - m_idx++; + + m_idx++; } vmatch = 0; @@ -9852,8 +9811,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1); } - switch_media_handle_set_media_flag(smh, SCMF_RENEG_ON_REINVITE); - if (msg->numeric_arg && switch_core_session_get_partner(session, &nsession) == SWITCH_STATUS_SUCCESS) { msg->numeric_arg = 0; switch_core_session_receive_message(nsession, msg); From eeba18394d5b29dd5a16cd73e60491c1ab44788c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 12 Aug 2016 14:28:45 -0500 Subject: [PATCH 100/128] FS-9410 #resolve [PLI Missing Media Source SSRC] --- src/switch_rtp.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 284ac2819e..8dbbeac4a0 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2072,13 +2072,13 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session) rtp_session->rtcp_send_msg.header.length = htons((uint16_t)(rtcp_bytes / 4) - 1); if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) { - //if (rtp_session->remote_ssrc == 0) { - // rtp_session->remote_ssrc = rtp_session->stats.rtcp.peer_ssrc; - //} + if (rtp_session->remote_ssrc == 0 && rtp_session->stats.rtcp.peer_ssrc) { + rtp_session->remote_ssrc = rtp_session->stats.rtcp.peer_ssrc; + } - //if (rtp_session->remote_ssrc == 0) { - // rtp_session->remote_ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc); - //} + if (rtp_session->remote_ssrc == 0 && rtp_session->last_rtp_hdr.ssrc) { + rtp_session->remote_ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc); + } if (rtp_session->pli_count) { @@ -2095,7 +2095,8 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session) ext_hdr->send_ssrc = htonl(rtp_session->ssrc); ext_hdr->recv_ssrc = htonl(rtp_session->remote_ssrc); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Sending RTCP PLI\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Sending RTCP PLI %u %u\n", + rtp_session->ssrc, rtp_session->remote_ssrc); ext_hdr->length = htons((uint8_t)(sizeof(switch_rtcp_ext_hdr_t) / 4) - 1); rtcp_bytes += sizeof(switch_rtcp_ext_hdr_t); From 8928852d66c5f1c00c52bf8cf0c56372bd36540f Mon Sep 17 00:00:00 2001 From: Spencer Thomason Date: Fri, 12 Aug 2016 13:38:10 -0700 Subject: [PATCH 101/128] FS-9423 #resolve Handle null value in ACL list name --- src/switch_core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/switch_core.c b/src/switch_core.c index 039531bb86..e06b6b1f39 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1373,6 +1373,10 @@ SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_ switch_bool_t ok = SWITCH_FALSE; char *ipv4 = NULL; + if (!list_name) { + return SWITCH_FALSE; + } + if ((ipv4 = switch_network_ipv4_mapped_ipv6_addr(ip_str))) { ip_str = ipv4; ipv6 = NULL; From 3fa367b0fafb5c4bcc9c5fc366eac53fa6a98c2f Mon Sep 17 00:00:00 2001 From: Chad Phillips Date: Tue, 9 Aug 2016 17:18:49 -0500 Subject: [PATCH 102/128] FS-9161: add example Verto settings to example configs detach-timeout-sec, enable-fs-events, enable-presence --- conf/vanilla/autoload_configs/verto.conf.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/conf/vanilla/autoload_configs/verto.conf.xml b/conf/vanilla/autoload_configs/verto.conf.xml index 8b839dedf8..7714053083 100644 --- a/conf/vanilla/autoload_configs/verto.conf.xml +++ b/conf/vanilla/autoload_configs/verto.conf.xml @@ -2,6 +2,12 @@ + + + + + + From 8269b8215bc33bc343a78810a9c6acd6b5ce5c70 Mon Sep 17 00:00:00 2001 From: Chad Phillips Date: Sat, 18 Jun 2016 15:02:35 -0500 Subject: [PATCH 103/128] FS-9281: Add support for QQVGA resolution in Verto QQVGA is a standard 160x120 resolution, useful for cases of very slow upload bandwidth. Adds the resolution to the core FSRTC lib, and to the Verto video demo and Verto Communicator --- html5/verto/js/src/jquery.FSRTC.js | 2 +- .../src/vertoService/services/vertoService.js | 14 ++++++++++++- html5/verto/video_demo/index.html | 4 ++++ html5/verto/video_demo/verto.js | 20 ++++++++++++++++++- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/html5/verto/js/src/jquery.FSRTC.js b/html5/verto/js/src/jquery.FSRTC.js index c0785576ff..225c1b16ec 100644 --- a/html5/verto/js/src/jquery.FSRTC.js +++ b/html5/verto/js/src/jquery.FSRTC.js @@ -1089,7 +1089,7 @@ return [w, h]; } - var resList = [[320, 180], [320, 240], [640, 360], [640, 480], [1280, 720], [1920, 1080]]; + var resList = [[160, 120], [320, 180], [320, 240], [640, 360], [640, 480], [1280, 720], [1920, 1080]]; var resI = 0; var ttl = 0; diff --git a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js index 824e5e9e91..12583b4571 100644 --- a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js +++ b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js @@ -3,6 +3,11 @@ /* Controllers */ var videoQuality = []; var videoQualitySource = [{ + id: 'qqvga', + label: 'QQVGA 160x120', + width: 160, + height: 120 +}, { id: 'qvga', label: 'QVGA 320x240', width: 320, @@ -35,6 +40,10 @@ var videoQualitySource = [{ }, ]; var videoResolution = { + qqvga: { + width: 160, + height: 120 + }, qvga: { width: 320, height: 240 @@ -910,7 +919,10 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora storage.data.useDedenc = false; storage.data.vidQual = 'hd'; - if (upBand < 512) { + if (upBand < 256) { + storage.data.vidQual = 'qqvga'; + } + else if (upBand < 512) { storage.data.vidQual = 'qvga'; } else if (upBand < 1024) { diff --git a/html5/verto/video_demo/index.html b/html5/verto/video_demo/index.html index 74992e5807..229275e9cf 100644 --- a/html5/verto/video_demo/index.html +++ b/html5/verto/video_demo/index.html @@ -394,6 +394,10 @@ if ($('#devices').is(':visible')) {
Video Quality: + + + + diff --git a/html5/verto/video_demo/verto.js b/html5/verto/video_demo/verto.js index aba518952b..e0ee4aec19 100644 --- a/html5/verto/video_demo/verto.js +++ b/html5/verto/video_demo/verto.js @@ -140,7 +140,12 @@ function real_size() { function check_vid_res() { - if ($("#vqual_qvga").is(':checked')) { + if ($("#vqual_qqvga").is(':checked')) { + vid_width = 160; + vid_height = 120; + local_vid_width = 80; + local_vid_height = 60; + } else if ($("#vqual_qvga").is(':checked')) { vid_width = 320; vid_height = 240; local_vid_width = 160; @@ -218,6 +223,10 @@ function do_speed_test(fn) $("#vqual_qvga").prop("checked", true); vid = "320x240"; } + if (outgoingBandwidth < 256) { + $("#vqual_qqvga").prop("checked", true); + vid = "160x120"; + } //} if (incomingBandwidth === "default") { @@ -1315,6 +1324,15 @@ function init() { + $("#vqual_qqvga").prop("checked", vqual === "qqvga").change(function(e) { + if ($("#vqual_qqvga").is(':checked')) { + vqual = "qqvga"; + $.cookie("verto_demo_vqual", vqual, { + expires: 365 + }); + } + }); + $("#vqual_qvga").prop("checked", vqual === "qvga").change(function(e) { if ($("#vqual_qvga").is(':checked')) { vqual = "qvga"; From c278c9f63f74fbc93e1b6eef81d19803c36b0fe5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 15 Aug 2016 17:10:42 -0500 Subject: [PATCH 104/128] FS-9375 #resolve [DTMF not working on OPUS after Call Transfer ] #comment Can we try to reproduce with this version on all 3 boxes (not just the patch but the whole rev as-is) --- src/mod/endpoints/mod_sofia/sofia.c | 25 +++++++++++++++---------- src/switch_core_media.c | 2 +- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 8d561c3f80..502892a141 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1590,20 +1590,25 @@ static void our_sofia_event_callback(nua_event_t event, if (channel && sip) { const char *r_sdp = NULL; - if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK) && sip->sip_payload && sip->sip_payload->pl_data) { - r_sdp = sip->sip_payload->pl_data; + if (sip->sip_payload && sip->sip_payload->pl_data) { + if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK)) { + r_sdp = sip->sip_payload->pl_data; - if (tech_pvt->mparams.last_sdp_str) { - tech_pvt->mparams.prev_sdp_str = tech_pvt->mparams.last_sdp_str; - } - tech_pvt->mparams.last_sdp_str = NULL; + if (tech_pvt->mparams.last_sdp_str) { + tech_pvt->mparams.prev_sdp_str = tech_pvt->mparams.last_sdp_str; + } + tech_pvt->mparams.last_sdp_str = NULL; - if (!zstr(tech_pvt->mparams.prev_sdp_str) && strcmp(tech_pvt->mparams.prev_sdp_str, sip->sip_payload->pl_data)) { + if (!zstr(tech_pvt->mparams.prev_sdp_str) && strcmp(tech_pvt->mparams.prev_sdp_str, sip->sip_payload->pl_data)) { + switch_channel_set_variable(channel, "sip_reinvite_sdp", sip->sip_payload->pl_data); + tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data); + } else { + tech_pvt->mparams.last_sdp_str = tech_pvt->mparams.prev_sdp_str; + } + } else { switch_channel_set_variable(channel, "sip_reinvite_sdp", sip->sip_payload->pl_data); tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data); - } else { - tech_pvt->mparams.last_sdp_str = tech_pvt->mparams.prev_sdp_str; } } @@ -6872,7 +6877,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (tech_pvt->mparams.last_sdp_response) { r_sdp = tech_pvt->mparams.last_sdp_response; } - } else if (ss_state == nua_callstate_received) { + } else if (ss_state == nua_callstate_received || ss_state == nua_callstate_ready) { if (tech_pvt->mparams.last_sdp_str) { r_sdp = tech_pvt->mparams.last_sdp_str; } diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 03678e6e33..4c552b7caf 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -4108,7 +4108,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s smh->mparams->num_codecs = 0; smh->num_negotiated_codecs = 0; - switch_core_media_prepare_codecs(session, SWITCH_FALSE); + switch_core_media_prepare_codecs(session, SWITCH_TRUE); codec_array = smh->codecs; total_codecs = smh->mparams->num_codecs; From 8786dd626e2356919f8ef048a7698b4492c822da Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Tue, 16 Aug 2016 13:37:31 -0500 Subject: [PATCH 105/128] FS-9362: [mod_sofia] fix sofia compile error on newer clang included in new osx Conflicts: libs/sofia-sip/.update --- libs/sofia-sip/.update | 2 +- libs/sofia-sip/libsofia-sip-ua/su/su_time.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 0ef1bfcdf6..eb6dc88486 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Mon Aug 8 16:39:35 CDT 2016 +Tue Aug 16 13:39:03 CDT 2016 diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_time.c b/libs/sofia-sip/libsofia-sip-ua/su/su_time.c index 2326bfaba8..2782dcec77 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_time.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_time.c @@ -398,7 +398,7 @@ uint64_t su_nanocounter(void) static int init = 0; static clockid_t cpu = CLOCK_REALTIME; -# define CLOCK_GETTIMEOFDAY 0xdedbeefUL +# define CLOCK_GETTIMEOFDAY ((clockid_t)-1) if (init == 0) { init = 1; From a433c20b34c7d357fbd45ede959619ca94bcf5ea Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Aug 2016 12:39:47 -0500 Subject: [PATCH 106/128] FS-9434 #resolve [SDP parser in sofia does not recognize UDP/TLS/RTP/SAVP] --- libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c index 4a79bf3b36..887e4e818a 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c +++ b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c @@ -1397,6 +1397,8 @@ void sdp_media_transport(sdp_media_t *m, char const *s) m->m_proto = sdp_proto_rtp, m->m_proto_name = "RTP/AVP"; else if (su_casematch(s, "RTP/SAVP")) m->m_proto = sdp_proto_srtp, m->m_proto_name = "RTP/SAVP"; + else if (su_casematch(s, "UDP/TLS/RTP/SAVP")) + m->m_proto = sdp_proto_srtp, m->m_proto_name = "RTP/SAVP"; else if (su_casematch(s, "RTP/SAVPF")) m->m_proto = sdp_proto_extended_srtp, m->m_proto_name = "RTP/SAVPF"; else if (su_casematch(s, "UDP/TLS/RTP/SAVPF")) From 3c92bad18e020e22a2dd29c8a129bb3ca7656b21 Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 17 Aug 2016 12:52:40 -0500 Subject: [PATCH 107/128] FS-9425 fix copy and paste error where we were not setting the height properly. --- src/mod/applications/mod_conference/mod_conference.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 28624d2120..47f44ec6e5 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -2761,10 +2761,10 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co } } - if (scale_h264_canvas_width < 320 || scale_h264_canvas_width < 180) { + if (scale_h264_canvas_width < 320 || scale_h264_canvas_height < 180) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid scale-h264-canvas-size, falling back to 320x180\n"); scale_h264_canvas_width = 320; - scale_h264_canvas_width = 180; + scale_h264_canvas_height = 180; } } else if (!strcasecmp(var, "scale-h264-canvas-fps-divisor") && !zstr(val)) { scale_h264_canvas_fps_divisor = atoi(val); From b9733c577cdfec3a3aa7365640353e3aceecc542 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Aug 2016 18:18:53 -0500 Subject: [PATCH 108/128] FS-9436 #resolve [RTCP PLI Media Source SSRC wrong after re-INVITE] --- src/include/switch_types.h | 1 + src/switch_rtp.c | 25 ++++++++++++++----------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 2bcf0414dd..4f5d0d1b74 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -766,6 +766,7 @@ typedef enum { SWITCH_RTP_FLAG_NACK, SWITCH_RTP_FLAG_TMMBR, SWITCH_RTP_FLAG_GEN_TS_DELTA, + SWITCH_RTP_FLAG_DETECT_SSRC, SWITCH_RTP_FLAG_INVALID } switch_rtp_flag_t; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 8dbbeac4a0..6028a0d596 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2070,17 +2070,8 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session) rtcp_generate_report_block(rtp_session, rtcp_report_block); rtp_session->rtcp_send_msg.header.length = htons((uint16_t)(rtcp_bytes / 4) - 1); - - if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) { - if (rtp_session->remote_ssrc == 0 && rtp_session->stats.rtcp.peer_ssrc) { - rtp_session->remote_ssrc = rtp_session->stats.rtcp.peer_ssrc; - } - - if (rtp_session->remote_ssrc == 0 && rtp_session->last_rtp_hdr.ssrc) { - rtp_session->remote_ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc); - } - + if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) { if (rtp_session->pli_count) { switch_rtcp_ext_hdr_t *ext_hdr; @@ -3736,7 +3727,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_ssrc(switch_rtp_t *rtp_session, u SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_ssrc(switch_rtp_t *rtp_session, uint32_t ssrc) { rtp_session->remote_ssrc = ssrc; - + rtp_session->flags[SWITCH_RTP_FLAG_DETECT_SSRC] = 0; return SWITCH_STATUS_SUCCESS; } @@ -4007,6 +3998,7 @@ SWITCH_DECLARE(switch_rtp_t *) switch_rtp_new(const char *rx_host, rtp_session->rx_host = switch_core_strdup(rtp_session->pool, rx_host); rtp_session->rx_port = rx_port; switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH); + switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_DETECT_SSRC); } else { switch_rtp_release_port(rx_host, rx_port); } @@ -5259,6 +5251,17 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t rtp_session->missed_count = 0; switch_cp_addr(rtp_session->rtp_from_addr, rtp_session->from_addr); rtp_session->last_rtp_hdr = rtp_session->recv_msg.header; + + + if (rtp_session->flags[SWITCH_RTP_FLAG_DETECT_SSRC]) { + //if (rtp_session->remote_ssrc != rtp_session->stats.rtcp.peer_ssrc && rtp_session->stats.rtcp.peer_ssrc) { + // rtp_session->remote_ssrc = rtp_session->stats.rtcp.peer_ssrc; + //} + + if (rtp_session->remote_ssrc != rtp_session->last_rtp_hdr.ssrc && rtp_session->last_rtp_hdr.ssrc) { + rtp_session->remote_ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc); + } + } } } From bfb9e96f845d3739f027db0c53b4cb30e0b50669 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Aug 2016 18:22:11 -0500 Subject: [PATCH 109/128] FS-9437 #resolve [Delete avatar if video is enabled mid-call] --- src/mod/applications/mod_conference/conference_loop.c | 1 + src/mod/applications/mod_conference/conference_video.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/mod/applications/mod_conference/conference_loop.c b/src/mod/applications/mod_conference/conference_loop.c index ed2d54bf12..a25c4319b0 100644 --- a/src/mod/applications/mod_conference/conference_loop.c +++ b/src/mod/applications/mod_conference/conference_loop.c @@ -707,6 +707,7 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob if (switch_channel_test_flag(channel, CF_VIDEO) && !conference_utils_member_test_flag(member, MFLAG_ACK_VIDEO)) { conference_utils_member_set_flag_locked(member, MFLAG_ACK_VIDEO); + switch_img_free(&member->avatar_png_img); conference_video_check_avatar(member, SWITCH_FALSE); switch_core_session_video_reinit(member->session); conference_video_set_floor_holder(member->conference, member, SWITCH_FALSE); diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 060f769f66..252e149f6c 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -1930,6 +1930,10 @@ void conference_video_pop_next_image(conference_member_t *member, switch_image_t int size = 0; void *pop; + if (member->avatar_png_img && switch_channel_test_flag(member->channel, CF_VIDEO_READY) && conference_utils_member_test_flag(member, MFLAG_ACK_VIDEO)) { + switch_img_free(&member->avatar_png_img); + } + if (!member->avatar_png_img && switch_channel_test_flag(member->channel, CF_VIDEO_READY)) { do { if (switch_queue_trypop(member->video_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { @@ -3863,6 +3867,7 @@ switch_status_t conference_video_thread_callback(switch_core_session_t *session, if (switch_queue_trypush(member->video_queue, img_copy) != SWITCH_STATUS_SUCCESS) { switch_img_free(&img_copy); } + } switch_thread_rwlock_unlock(member->conference->rwlock); From ea5b39365af78be85b73673699040727ec9952c9 Mon Sep 17 00:00:00 2001 From: Luis Azedo Date: Thu, 18 Aug 2016 10:23:55 -0500 Subject: [PATCH 110/128] FS-9440 add transfer_destination --- src/mod/endpoints/mod_sofia/sofia.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index b6284a6b70..7f886a307d 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -8903,6 +8903,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t switch_core_session_t *b_session; switch_channel_set_variable_printf(channel, "transfer_to", "blind:%s", br ? br : exten); + switch_channel_set_variable_printf(channel, "transfer_destination", "blind:%s", exten); if (!zstr(br) && (b_session = switch_core_session_locate(br))) { const char *var; From f8c2abc189f27ca13b2ddd6dc334ef7738ccb37d Mon Sep 17 00:00:00 2001 From: Luis Azedo Date: Thu, 18 Aug 2016 11:04:08 -0500 Subject: [PATCH 111/128] FS-9441 optional skip member outcall beep --- src/mod/applications/mod_conference/conference_loop.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_conference/conference_loop.c b/src/mod/applications/mod_conference/conference_loop.c index a25c4319b0..67592c874a 100644 --- a/src/mod/applications/mod_conference/conference_loop.c +++ b/src/mod/applications/mod_conference/conference_loop.c @@ -1122,6 +1122,7 @@ void conference_loop_output(conference_member_t *member) const char *prefix = switch_channel_get_variable(channel, "conference_auto_outcall_prefix"); const char *maxwait = switch_channel_get_variable(channel, "conference_auto_outcall_maxwait"); const char *delimiter_val = switch_channel_get_variable(channel, "conference_auto_outcall_delimiter"); + const char *skip_member_beep = switch_channel_get_variable(channel, "conference_auto_outcall_skip_member_beep"); int to = 60; int wait_sec = 2; int loops = 0; @@ -1185,7 +1186,8 @@ void conference_loop_output(conference_member_t *member) goto end; } - conference_member_play_file(member, "tone_stream://%(500,0,640)", 0, SWITCH_TRUE); + if (!skip_member_beep || !switch_true(skip_member_beep)) + conference_member_play_file(member, "tone_stream://%(500,0,640)", 0, SWITCH_TRUE); } if (!conference_utils_test_flag(member->conference, CFLAG_ANSWERED)) { From 2636141c32df5bb8b36588de2ac3a048054c3235 Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 18 Aug 2016 15:12:28 -0500 Subject: [PATCH 112/128] Revert FS-8565, its getting a few blames for 3cx interop issues, we need to revisit the original reason and make sure this was the right fix. --- src/switch_rtp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 6028a0d596..a2c4ebdc3e 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2920,7 +2920,6 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_ switch_mutex_lock(rtp_session->write_mutex); rtp_session->remote_addr = remote_addr; - switch_cp_addr(rtp_session->rtp_from_addr, rtp_session->remote_addr); if (change_adv_addr) { rtp_session->remote_host_str = switch_core_strdup(rtp_session->pool, host); From 7b9184e94fe57e0921974a70697c6d5760f717ba Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 18 Aug 2016 19:10:48 -0400 Subject: [PATCH 113/128] Fix compiler warning/error in ftmod_r2.c --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 2 -- 1 file changed, 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 2dea680987..8b36cdb8f3 100755 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -1021,7 +1021,6 @@ static void ftdm_r2_on_chan_log(openr2_chan_t *r2chan, const char *file, const c static int ftdm_r2_on_dnis_digit_received(openr2_chan_t *r2chan, char digit) { ftdm_sigmsg_t sigev; - ftdm_r2_data_t *r2data; ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); ftdm_size_t collected_len = R2CALL(ftdmchan)->dnis_index; @@ -1039,7 +1038,6 @@ static int ftdm_r2_on_dnis_digit_received(openr2_chan_t *r2chan, char digit) sigev.span_id = ftdmchan->span_id; sigev.channel = ftdmchan; sigev.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT; - r2data = ftdmchan->span->signal_data; if (ftdm_span_send_signal(ftdmchan->span, &sigev) == FTDM_BREAK) { ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Requested to stop getting DNIS. Current DNIS = %s\n", ftdmchan->caller_data.dnis.digits); return OR2_STOP_DNIS_REQUEST; From fb065a148aca5925dd13893c80bdb60c7f459cc3 Mon Sep 17 00:00:00 2001 From: Piotr Gregor Date: Fri, 19 Aug 2016 19:41:19 +0100 Subject: [PATCH 114/128] FS-9447: [mod_avmd] increase default value of samples to skip Increase value of samples to skip at the beginning of new frame. This increases the robustness against false detections observed on German voicemail from Switzerland (see wav audio attached to case FS-9447). --- .../conf/autoload_configs/avmd.conf.xml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/mod/applications/mod_avmd/conf/autoload_configs/avmd.conf.xml b/src/mod/applications/mod_avmd/conf/autoload_configs/avmd.conf.xml index 039658cf8d..2366195621 100644 --- a/src/mod/applications/mod_avmd/conf/autoload_configs/avmd.conf.xml +++ b/src/mod/applications/mod_avmd/conf/autoload_configs/avmd.conf.xml @@ -8,12 +8,14 @@ - - + + without reset. This parameter helps to avoid false beeps, bigger this value is + smaller the probability of getting false detection --> - + of the frame and/or after reset has happened. This serves the purpose of skipping first few + estimations on each frame, as these estimations may be inaccurate. This parameter also helps + to give more robust detections when it's value is increased (up to scertain limit of about 60). --> +