diff --git a/build/modules.conf.most b/build/modules.conf.most index 128c07f18c..5c72ffa27c 100644 --- a/build/modules.conf.most +++ b/build/modules.conf.most @@ -92,6 +92,7 @@ endpoints/mod_skinny endpoints/mod_skypopen endpoints/mod_sofia endpoints/mod_verto +event_handlers/mod_amqp event_handlers/mod_cdr_csv event_handlers/mod_cdr_mongodb #event_handlers/mod_cdr_pg_csv @@ -100,6 +101,7 @@ event_handlers/mod_erlang_event event_handlers/mod_event_multicast event_handlers/mod_event_socket event_handlers/mod_format_cdr +event_handlers/mod_hiredis event_handlers/mod_json_cdr #event_handlers/mod_radius_cdr event_handlers/mod_odbc_cdr diff --git a/conf/testing/autoload_configs/modules.conf.xml b/conf/testing/autoload_configs/modules.conf.xml index cfd02d3b64..f0e099661f 100644 --- a/conf/testing/autoload_configs/modules.conf.xml +++ b/conf/testing/autoload_configs/modules.conf.xml @@ -6,6 +6,7 @@ + diff --git a/conf/testing/autoload_configs/opus.conf.xml b/conf/testing/autoload_configs/opus.conf.xml index 022cc15912..72ea62029e 100644 --- a/conf/testing/autoload_configs/opus.conf.xml +++ b/conf/testing/autoload_configs/opus.conf.xml @@ -1,28 +1,10 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + diff --git a/conf/testing/dialplan/default/0000_local_extensions.xml b/conf/testing/dialplan/default/0000_local_extensions.xml index c47ccb9fb8..54de0b245d 100644 --- a/conf/testing/dialplan/default/0000_local_extensions.xml +++ b/conf/testing/dialplan/default/0000_local_extensions.xml @@ -11,4 +11,10 @@ + + + + + + diff --git a/conf/testing/dialplan/default/0024_play_video.xml b/conf/testing/dialplan/default/0024_play_video.xml index 0fc06995e8..efaadbe5a3 100644 --- a/conf/testing/dialplan/default/0024_play_video.xml +++ b/conf/testing/dialplan/default/0024_play_video.xml @@ -4,3 +4,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/vanilla/autoload_configs/amqp.conf.xml b/conf/vanilla/autoload_configs/amqp.conf.xml index 0d139169a9..43bff5d23e 100644 --- a/conf/vanilla/autoload_configs/amqp.conf.xml +++ b/conf/vanilla/autoload_configs/amqp.conf.xml @@ -20,8 +20,8 @@ - - + + @@ -54,7 +54,7 @@ - + diff --git a/conf/vanilla/sip_profiles/external-ipv6.xml b/conf/vanilla/sip_profiles/external-ipv6.xml index ea66679c37..99e8feb246 100644 --- a/conf/vanilla/sip_profiles/external-ipv6.xml +++ b/conf/vanilla/sip_profiles/external-ipv6.xml @@ -13,7 +13,7 @@ - + diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index e514ab1a94..43468800ae 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -2,12 +2,33 @@ ##### -*- mode:shell-script; indent-tabs-mode:nil; sh-basic-offset:2 -*- ##### Author: Travis Cross +codename="sid" +modulelist_opt="" +modules_add="" +use_sysvinit="" +while getopts "c:m:p:v" o; do + case "$o" in + c) codename="$OPTARG" ;; + m) modulelist_opt="$OPTARG" ;; + p) modules_add="$modules_add $OPTARG";; + v) use_sysvinit="true";; + esac +done +shift $(($OPTIND-1)) + +if [ x${use_sysvinit} = x ]; then + case "$codename" in + wheezy|trusty|utopic) use_sysvinit="true";; + *) use_sysvinit="false";; + esac +fi + mod_dir="../src/mod" conf_dir="../conf" lang_dir="../conf/vanilla/lang" fs_description="FreeSWITCH is a scalable open source cross-platform telephony platform designed to route and interconnect popular communication protocols using audio, video, text or any other form of media." mod_build_depends="." mod_depends="." mod_recommends="." mod_suggests="." -supported_debian_distros="squeeze wheezy jessie sid" +supported_debian_distros="wheezy jessie stretch sid" supported_ubuntu_distros="trusty utopic" supported_distros="$supported_debian_distros $supported_ubuntu_distros" avoid_mods=( @@ -46,11 +67,14 @@ avoid_mods_jessie=( avoid_mods_wheezy=( event_handlers/mod_amqp languages/mod_java -) -avoid_mods_squeeze=( - event_handlers/mod_amqp - formats/mod_vlc languages/mod_managed + applications/mod_av + applications/mod_cv + applications/mod_hiredis + formats/mod_shout + applications/mod_sonar + applications/mod_soundtouch + formats/mod_vlc ) avoid_mods_trusty=( ) @@ -75,13 +99,16 @@ freeswitch-dbg libfreeswitch1-dbg libfreeswitch-dev freeswitch-doc -freeswitch-init -freeswitch-sysvinit -freeswitch-systemd freeswitch-lang freeswitch-timezones ) +if [ ${use_sysvinit} = "true" ]; then + manual_pkgs=( "${manual_pkgs[@]}" "freeswitch-sysvinit" ) +else + manual_pkgs=( "${manual_pkgs[@]}" "freeswitch-systemd" ) +fi + err () { echo "$0 error: $1" >&2 exit 1 @@ -285,16 +312,20 @@ list_freeswitch_all_dbg_replaces () { print_source_control () { local libtool_dep="libtool, libtool-bin" case "$codename" in - squeeze|wheezy|trusty) libtool_dep="libtool" ;; + wheezy|trusty) libtool_dep="libtool" ;; esac -cat < Build-Depends: # for debian - debhelper (>= 8.0.0), + ${debhelper_dep}, # bootstrapping automake (>= 1.9), autoconf, ${libtool_dep}, # core build @@ -822,33 +853,6 @@ Description: documentation for FreeSWITCH This package contains Doxygen-produce documentation for FreeSWITCH. It may be an empty package at the moment. -Package: freeswitch-init -Architecture: all -Depends: \${misc:Depends}, - freeswitch-sysvinit (= \${binary:Version}), - freeswitch-systemd (= \${binary:Version}) -Description: FreeSWITCH startup configuration - $(debian_wrap "${fs_description}") - . - This is a metapackage which depends on the default system startup - packages for FreeSWITCH. - -Package: freeswitch-sysvinit -Architecture: all -Depends: \${misc:Depends}, lsb-base (>= 3.0-6) -Description: FreeSWITCH SysV init script - $(debian_wrap "${fs_description}") - . - This package contains the SysV init script for FreeSWITCH. - -Package: freeswitch-systemd -Architecture: all -Depends: \${misc:Depends} -Description: FreeSWITCH systemd configuration - $(debian_wrap "${fs_description}") - . - This package contains the systemd configuration for FreeSWITCH. - ## misc ## languages @@ -873,7 +877,37 @@ Description: Timezone files for FreeSWITCH . $(debian_wrap "This package includes the timezone files for FreeSWITCH.") +## startup + EOF + +if [ ${use_sysvinit} = "true" ]; then + cat <= 3.0-6), sysvinit +Conflicts: freeswitch-init +Provides: freeswitch-init +Description: FreeSWITCH SysV init script + $(debian_wrap "${fs_description}") + . + This package contains the SysV init script for FreeSWITCH. + +EOF +else + cat <&2 echo >&2 @@ -1324,9 +1348,17 @@ for x in postinst postrm preinst prerm; do cp -a freeswitch.$x freeswitch-all.$x done cp -a freeswitch-doc.docs freeswitch-all.docs -#cp -a freeswitch-systemd.freeswitch.service freeswitch-all.freeswitch.service -cp -a freeswitch-sysvinit.freeswitch.default freeswitch-all.freeswitch.default -cp -a freeswitch-sysvinit.freeswitch.init freeswitch-all.freeswitch.init + +if [ ${use_sysvinit} = "true" ]; then + cp -a freeswitch-sysvinit.freeswitch.init freeswitch-all.freeswitch.init + cp -a freeswitch-sysvinit.freeswitch.default freeswitch-all.freeswitch.default + echo -n freeswitch-sysvinit >freeswitch-init.provided_by +else + cp -a freeswitch-systemd.freeswitch.service freeswitch-all.freeswitch.service + cp -a freeswitch-systemd.freeswitch.tmpfile freeswitch-all.freeswitch.tmpfile + echo -n freeswitch-systemd >freeswitch-init.provided_by +fi + echo "Generating additional lintian overrides..." >&2 grep -e '^Package:' control | while xread l; do diff --git a/debian/control-modules b/debian/control-modules index c009c96ee0..66c040f5d2 100644 --- a/debian/control-modules +++ b/debian/control-modules @@ -611,7 +611,6 @@ Description: VLC streaming Build-Depends: libvlc-dev (>= 2.0.0) Depends: vlc-nox Suggests: vlc-dbg -Distro-Conflicts: squeeze Module: formats/mod_webm Description: Adds mod_webm diff --git a/debian/freeswitch-systemd.freeswitch.service b/debian/freeswitch-systemd.freeswitch.service index 5a46d8731c..2a3a97089b 100644 --- a/debian/freeswitch-systemd.freeswitch.service +++ b/debian/freeswitch-systemd.freeswitch.service @@ -8,14 +8,14 @@ After=syslog.target network.target local-fs.target ; service Type=forking PIDFile=/run/freeswitch/freeswitch.pid -ExecStart=/usr/bin/freeswitch -ncwait -nonat +Environment="DAEMON_OPTS=-nonat" +EnvironmentFile=-/etc/default/freeswitch +ExecStart=/usr/bin/freeswitch -u freeswitch -g freeswitch -ncwait $DAEMON_OPTS TimeoutSec=45s Restart=always ; exec -RuntimeDirectory=freeswitch -RuntimeDirectoryMode=0755 -User=freeswitch -Group=freeswitch +User=root +Group=daemon LimitCORE=infinity LimitNOFILE=100000 LimitNPROC=60000 @@ -28,5 +28,27 @@ CPUSchedulingPolicy=rr CPUSchedulingPriority=89 UMask=0007 +; alternatives which you can enforce by placing a unit drop-in into +; /etc/systemd/system/freeswitch.service.d/*.conf: +; +; User=freeswitch +; Group=freeswitch +; ExecStart= +; ExecStart=/usr/bin/freeswitch -ncwait -nonat -rp +; +; empty ExecStart is required to flush the list. +; +; if your filesystem supports extended attributes, execute +; setcap 'cap_net_bind_service,cap_sys_nice=+ep' /usr/bin/freeswitch +; this will also allow socket binding on low ports +; +; otherwise, remove the -rp option from ExecStart and +; add these lines to give real-time priority to the process: +; +; PermissionsStartOnly=true +; ExecStartPost=/bin/chrt -f -p 1 $MAINPID +; +; execute "systemctl daemon-reload" after editing the unit files. + [Install] WantedBy=multi-user.target diff --git a/debian/freeswitch-systemd.freeswitch.tmpfile b/debian/freeswitch-systemd.freeswitch.tmpfile new file mode 100644 index 0000000000..baea7b8113 --- /dev/null +++ b/debian/freeswitch-systemd.freeswitch.tmpfile @@ -0,0 +1 @@ +d /var/run/freeswitch 0755 freeswitch freeswitch - - diff --git a/debian/freeswitch-systemd.install b/debian/freeswitch-systemd.install deleted file mode 100644 index d647282ecd..0000000000 --- a/debian/freeswitch-systemd.install +++ /dev/null @@ -1 +0,0 @@ -/lib/systemd/system/freeswitch.service diff --git a/debian/rules b/debian/rules index b2e43d68d0..7cfe4c1c2e 100755 --- a/debian/rules +++ b/debian/rules @@ -98,13 +98,18 @@ override_dh_strip: override_dh_auto_install: dh_auto_install dh_auto_install -- -C libs/esl pymod-install - mkdir -p debian/tmp/lib/systemd/system - install -m0644 debian/freeswitch-systemd.freeswitch.service debian/tmp/lib/systemd/system/freeswitch.service rm -f debian/tmp/usr/share/freeswitch/grammar/model/communicator/COPYING override_dh_installinit: - dh_installinit -pfreeswitch-sysvinit --name=freeswitch - dh_installinit -pfreeswitch-all --name=freeswitch + if [ `cat debian/freeswitch-init.provided_by` = freeswitch-systemd ]; then \ + dh_systemd_enable -pfreeswitch-systemd --name=freeswitch; \ + dh_systemd_start -pfreeswitch-systemd --name=freeswitch; \ + dh_systemd_enable -pfreeswitch-all --name=freeswitch; \ + dh_systemd_start -pfreeswitch-all --name=freeswitch; \ + else \ + dh_installinit -pfreeswitch-sysvinit --name=freeswitch; \ + dh_installinit -pfreeswitch-all --name=freeswitch; \ + fi override_dh_makeshlibs: dh_makeshlibs diff --git a/html5/verto/verto_communicator/bower.json b/html5/verto/verto_communicator/bower.json index c69b4785d5..6a05c29a06 100644 --- a/html5/verto/verto_communicator/bower.json +++ b/html5/verto/verto_communicator/bower.json @@ -28,6 +28,7 @@ "bootstrap": "~3.3.4", "angular-toastr": "~1.4.1", "angular": "~1.3.15", + "angular-sanitize": "~1.3.15", "angular-route": "~1.3.15", "angular-prompt": "~1.1.1", "angular-animate": "~1.3.15", diff --git a/html5/verto/verto_communicator/src/css/verto.css b/html5/verto/verto_communicator/src/css/verto.css index 9bc3a8b70c..d307eecdaf 100644 --- a/html5/verto/verto_communicator/src/css/verto.css +++ b/html5/verto/verto_communicator/src/css/verto.css @@ -925,6 +925,10 @@ body .modal-body .btn-group .btn.active { color: #FFF; } +.chat-img { + display: block; +} + .chat-members .chat-member-item { padding: 8px 16px; height: 56px; diff --git a/html5/verto/verto_communicator/src/index.html b/html5/verto/verto_communicator/src/index.html index a1594f8a7f..c450607c9f 100644 --- a/html5/verto/verto_communicator/src/index.html +++ b/html5/verto/verto_communicator/src/index.html @@ -56,7 +56,7 @@ - + @@ -66,6 +66,7 @@ + @@ -87,14 +88,14 @@ - + - + - + @@ -119,6 +120,9 @@ + + + @@ -133,4 +137,3 @@ - diff --git a/html5/verto/verto_communicator/src/partials/chat.html b/html5/verto/verto_communicator/src/partials/chat.html index 6fb10a878f..7e10b05db3 100644 --- a/html5/verto/verto_communicator/src/partials/chat.html +++ b/html5/verto/verto_communicator/src/partials/chat.html @@ -23,15 +23,15 @@

-
{{ member.name }}
+
{{ member.name }}
({{ member.number }}) - +
Floor
Presenter

- +
-

{{ message.body }}

+

diff --git a/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js b/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js index 0952ed1dce..966a7c1f7e 100644 --- a/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js +++ b/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js @@ -6,8 +6,10 @@ 'ngRoute', 'vertoControllers', 'vertoDirectives', + 'vertoFilters', 'ngStorage', 'ngAnimate', + 'ngSanitize', 'toastr', 'FBAngular', 'cgPrompt', @@ -56,17 +58,17 @@ vertoApp.run(['$rootScope', '$location', 'toastr', 'prompt', 'verto', function($rootScope, $location, toastr, prompt, verto) { - + $rootScope.$on( "$routeChangeStart", function(event, next, current) { if (!verto.data.connected) { if ( next.templateUrl === "partials/login.html") { - // pass + // pass } else { $location.path("/"); } } }); - + $rootScope.$on('$routeChangeSuccess', function(event, current, previous) { $rootScope.title = current.$$route.title; }); @@ -77,7 +79,7 @@ $rootScope.safeProtocol = true; } - + $rootScope.promptInput = function(title, message, label, callback) { var ret = prompt({ title: title, diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js index cd8fff2021..256d1bb3e5 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js @@ -39,8 +39,8 @@ console.log('chat.newMessage', data); $scope.$apply(function() { $scope.messages.push(data); - if (data.from != verto.data.name && (!$scope.chatStatus || - $scope.activePane != 'chat')) { + if (data.from != verto.data.name && + (!$scope.chatStatus && $scope.activePane != 'chat')) { ++$rootScope.chat_counter; } $timeout(function() { @@ -116,6 +116,11 @@ $scope.$apply(function() { // console.log('Updating', memberIdx, ' <', $scope.members[memberIdx], // '> with <', member, '>'); + // Checking if it's me + if (parseInt(member.id) == parseInt(verto.data.conferenceMemberID)) { + verto.data.mutedMic = member.status.audio.muted; + verto.data.mutedVideo = member.status.video.muted; + } angular.extend($scope.members[memberIdx], member); }); } @@ -171,7 +176,7 @@ $scope.confBanner = function(memberID) { console.log('$scope.confBanner'); - + prompt({ title: 'Please insert the banner text', input: true, diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js index daa9b95b69..b34aad8631 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js @@ -13,7 +13,7 @@ $scope.storage = storage; $scope.call_history = angular.element("#call_history").hasClass('active'); $rootScope.chatStatus = angular.element('#wrapper').hasClass('toggled'); - + $scope.showReconnectModal = true; /** * (explanation) scope in another controller extends rootScope (singleton) */ @@ -84,6 +84,7 @@ } $scope.closeChat(); + $scope.showReconnectModal = false; verto.disconnect(disconnectCallback); verto.hangup(); @@ -170,7 +171,9 @@ backdrop: 'static', keyboard: false }; - ws_modalInstance = $scope.openModal('partials/ws_reconnect.html', 'ModalWsReconnectController', options); + if ($scope.showReconnectModal) { + ws_modalInstance = $scope.openModal('partials/ws_reconnect.html', 'ModalWsReconnectController', options); + }; }; function onWSLogin(ev, data) { diff --git a/html5/verto/verto_communicator/src/vertoFilters/filters/picturify.js b/html5/verto/verto_communicator/src/vertoFilters/filters/picturify.js new file mode 100644 index 0000000000..f4f7dfe3f1 --- /dev/null +++ b/html5/verto/verto_communicator/src/vertoFilters/filters/picturify.js @@ -0,0 +1,26 @@ +(function () { + 'use strict'; + + angular + .module('vertoFilters') + .filter('picturify', function() { + var regex = /\s*\S*<\/a>/i; + var regex64 = /data:image\/(\s*\S*);base64,((?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=))/g; + + return function (text, width, n) { + var i = 0; + width = width || 150; //default width + if(regex64.test(text)) { + text = text.replace(regex64, '') + } + + do { + text = text.replace(regex, ''); + } while((!n || (n && i++ < n)) && regex.test(text)); + + return text; + } + + }); + +})(); diff --git a/html5/verto/verto_communicator/src/vertoFilters/vertoFilters.module.js b/html5/verto/verto_communicator/src/vertoFilters/vertoFilters.module.js new file mode 100644 index 0000000000..f58933133b --- /dev/null +++ b/html5/verto/verto_communicator/src/vertoFilters/vertoFilters.module.js @@ -0,0 +1,4 @@ +(function() { + 'use strict'; + var vertoFilters = angular.module('vertoFilters', []); +})(); diff --git a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js index 652d5aa0da..26c13c6fc1 100644 --- a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js +++ b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js @@ -346,7 +346,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora $rootScope.$emit('call.conference', 'conference'); data.chattingWith = pvtData.chatID; data.confRole = pvtData.role; - + data.conferenceMemberID = pvtData.conferenceMemberID; var conf = new $.verto.conf(v, { dialog: dialog, hasVid: storage.data.useVideo, diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index b96563f178..7b7cd0aeb8 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -1529,7 +1529,7 @@ switch_status_t conference_api_sub_vid_logo_img(conference_member_t *member, swi if (!strcasecmp(text, "allclear")) { switch_channel_set_variable(member->channel, "video_logo_path", NULL); member->video_logo = NULL; - } if (!strcasecmp(text, "clear")) { + } else if (!strcasecmp(text, "clear")) { member->video_logo = NULL; } else { member->video_logo = switch_core_strdup(member->pool, text); @@ -2386,7 +2386,6 @@ switch_status_t conference_api_sub_record(conference_obj_t *conference, switch_s switch_status_t conference_api_sub_norecord(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) { int all, before = conference->record_count, ttl = 0; - switch_event_t *event; switch_assert(conference != NULL); switch_assert(stream != NULL); @@ -2398,15 +2397,6 @@ switch_status_t conference_api_sub_norecord(conference_obj_t *conference, switch if (!conference_record_stop(conference, stream, all ? NULL : argv[2]) && !all) { stream->write_function(stream, "non-existant recording '%s'\n", argv[2]); - } else { - if (test_eflag(conference, EFLAG_RECORD) && - switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { - conference_event_add_data(conference, event); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "stop-recording"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", all ? "all" : argv[2]); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Other-Recordings", conference->record_count ? "true" : "false"); - switch_event_fire(&event); - } } ttl = before - conference->record_count; @@ -2435,7 +2425,7 @@ switch_status_t conference_api_sub_pauserec(conference_obj_t *conference, switch } stream->write_function(stream, "%s recording file %s\n", action == REC_ACTION_PAUSE ? "Pause" : "Resume", argv[2]); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s recording file %s\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s recording file %s\n", action == REC_ACTION_PAUSE ? "Pause" : "Resume", argv[2]); if (!conference_record_action(conference, argv[2], action)) { diff --git a/src/mod/applications/mod_conference/conference_event.c b/src/mod/applications/mod_conference/conference_event.c index b37ecd7e66..5c373d391f 100644 --- a/src/mod/applications/mod_conference/conference_event.c +++ b/src/mod/applications/mod_conference/conference_event.c @@ -391,7 +391,9 @@ void conference_event_adv_la(conference_obj_t *conference, conference_member_t * const char *event_channel = cookie ? cookie : uuid; switch_event_t *variables; switch_event_header_t *hp; + char idstr[128] = ""; + snprintf(idstr, sizeof(idstr), "%d", member->id); msg = cJSON_CreateObject(); data = json_add_child_obj(msg, "pvtData", NULL); @@ -403,6 +405,7 @@ void conference_event_adv_la(conference_obj_t *conference, conference_member_t * cJSON_AddItemToObject(data, "laName", cJSON_CreateString(conference->la_name)); cJSON_AddItemToObject(data, "role", cJSON_CreateString(conference_utils_member_test_flag(member, MFLAG_MOD) ? "moderator" : "participant")); cJSON_AddItemToObject(data, "chatID", cJSON_CreateString(conference->chat_id)); + cJSON_AddItemToObject(data, "conferenceMemberID", cJSON_CreateString(idstr)); cJSON_AddItemToObject(data, "canvasCount", cJSON_CreateNumber(conference->canvas_count)); if (conference_utils_member_test_flag(member, MFLAG_SECOND_SCREEN)) { diff --git a/src/mod/applications/mod_conference/conference_loop.c b/src/mod/applications/mod_conference/conference_loop.c index 162e50cc36..c31fb6ddcd 100644 --- a/src/mod/applications/mod_conference/conference_loop.c +++ b/src/mod/applications/mod_conference/conference_loop.c @@ -583,7 +583,7 @@ void conference_loop_transfer(conference_member_t *member, caller_control_action switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_ERROR, "Unable to allocate memory to duplicate transfer data.\n"); goto done; } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, "Transfering to: %s, %s, %s\n", exten, dialplan, context); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_INFO, "Transfering to: %s, %s, %s\n", exten, dialplan, context); switch_ivr_session_transfer(member->session, exten, dialplan, context); @@ -633,7 +633,7 @@ void conference_loop_exec_app(conference_member_t *member, caller_control_action goto done; } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, "Execute app: %s, %s\n", app, arg); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_INFO, "Execute app: %s, %s\n", app, arg); channel = switch_core_session_get_channel(member->session); @@ -745,6 +745,18 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob } } + if (switch_channel_test_flag(member->channel, CF_CONFERENCE_RESET_MEDIA)) { + switch_channel_clear_flag(member->channel, CF_CONFERENCE_RESET_MEDIA); + member->loop_loop = 1; + + if (conference_member_setup_media(member, member->conference)) { + switch_mutex_unlock(member->read_mutex); + break; + } + + goto do_continue; + } + if (switch_test_flag(read_frame, SFF_CNG)) { if (member->conference->agc_level) { member->nt_tally++; @@ -945,18 +957,6 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob } } - if (switch_channel_test_flag(member->channel, CF_CONFERENCE_RESET_MEDIA)) { - switch_channel_clear_flag(member->channel, CF_CONFERENCE_RESET_MEDIA); - member->loop_loop = 1; - - if (conference_member_setup_media(member, member->conference)) { - switch_mutex_unlock(member->read_mutex); - break; - } - - goto do_continue; - } - /* skip frames that are not actual media or when we are muted or silent */ if ((conference_utils_member_test_flag(member, MFLAG_TALKING) || member->energy_level == 0 || conference_utils_test_flag(member->conference, CFLAG_AUDIO_ALWAYS)) && conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) && !conference_utils_test_flag(member->conference, CFLAG_WAIT_MOD) @@ -1388,7 +1388,7 @@ void conference_loop_output(conference_member_t *member) return; } - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Channel leaving conference, cause: %s\n", + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_INFO, "Channel leaving conference, cause: %s\n", switch_channel_cause2str(switch_channel_get_cause(channel))); /* if it's an outbound channel, store the release cause in the conference struct, we might need it */ diff --git a/src/mod/applications/mod_conference/conference_member.c b/src/mod/applications/mod_conference/conference_member.c index 5d60dcd16c..2114b9b0fd 100644 --- a/src/mod/applications/mod_conference/conference_member.c +++ b/src/mod/applications/mod_conference/conference_member.c @@ -125,7 +125,7 @@ void conference_member_bind_controls(conference_member_t *member, const char *co for(i = 0; i < conference_loop_mapping_len(); i++) { if (!strcasecmp(key, control_mappings[i].name)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s binding '%s' to '%s'\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s binding '%s' to '%s'\n", switch_core_session_get_name(member->session), digits, key); conference_member_do_binding(member, control_mappings[i].handler, digits, data); diff --git a/src/mod/applications/mod_conference/conference_record.c b/src/mod/applications/mod_conference/conference_record.c index 5ff2dc18dc..37d11178c3 100644 --- a/src/mod/applications/mod_conference/conference_record.c +++ b/src/mod/applications/mod_conference/conference_record.c @@ -91,6 +91,7 @@ switch_status_t conference_record_stop(conference_obj_t *conference, switch_stre switch_mutex_lock(conference->member_mutex); for (member = conference->members; member; member = member->next) { if (conference_utils_member_test_flag(member, MFLAG_NOCHANNEL) && (!path || !strcmp(path, member->rec_path))) { + conference->record_count--; if (!conference_utils_test_flag(conference, CFLAG_CONF_RESTART_AUTO_RECORD) && member->rec && member->rec->autorec) { stream->write_function(stream, "Stopped AUTO recording file %s (Auto Recording Now Disabled)\n", member->rec_path); conference->auto_record = 0; @@ -99,12 +100,12 @@ switch_status_t conference_record_stop(conference_obj_t *conference, switch_stre } conference_utils_member_clear_flag_locked(member, MFLAG_RUNNING); + count++; } } - conference->record_count -= count; switch_mutex_unlock(conference->member_mutex); return count; @@ -379,11 +380,12 @@ void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *thread, v switch_mutex_unlock(conference->mutex); switch_core_file_close(&member->rec->fh); } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Recording of %s Stopped\n", rec->path); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Recording of %s Stopped\n", rec->path); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { conference_event_add_data(conference, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "stop-recording"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", rec->path); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Other-Recordings", conference->record_count ? "true" : "false"); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Samples-Out", "%ld", (long) member->rec->fh.samples_out); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Samplerate", "%ld", (long) member->rec->fh.samplerate); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Milliseconds-Elapsed", "%ld", (long) member->rec->fh.samples_out / (member->rec->fh.samplerate / 1000)); diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 963ae9aa15..77562e40a6 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -362,7 +362,7 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob } } if (is_talking == 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Conference has been idle for over %d seconds, terminating\n", conference->terminate_on_silence); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Conference has been idle for over %d seconds, terminating\n", conference->terminate_on_silence); conference_utils_set_flag(conference, CFLAG_DESTRUCT); } } @@ -376,7 +376,7 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob switch_channel_t *channel = switch_core_session_get_channel(imember->session); char *rfile = switch_channel_expand_variables(channel, conference->auto_record); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Auto recording file: %s\n", rfile); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Auto recording file: %s\n", rfile); conference_record_launch_thread(conference, rfile, -1, SWITCH_TRUE); if (rfile != conference->auto_record) { @@ -2967,7 +2967,7 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co if ((val = switch_channel_get_variable(channel, "sound_prefix")) && !zstr(val)) { /* if no sound_prefix was set, use the channel sound_prefix */ conference->sound_prefix = switch_core_strdup(conference->pool, val); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "using channel sound prefix: %s\n", conference->sound_prefix); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "using channel sound prefix: %s\n", conference->sound_prefix); } } diff --git a/src/mod/applications/mod_distributor/mod_distributor.c b/src/mod/applications/mod_distributor/mod_distributor.c index 7b1ae3790e..b02b438669 100644 --- a/src/mod/applications/mod_distributor/mod_distributor.c +++ b/src/mod/applications/mod_distributor/mod_distributor.c @@ -238,6 +238,7 @@ static struct dist_node *find_next(struct dist_list *list, int etotal, char **ex list->last = -1; } match = NULL; + matches = 0; for (np = list->nodes; np; np = np->next) { if (np->cur_weight < list->target_weight) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "%s %d/%d\n", np->name, np->cur_weight, list->target_weight); diff --git a/src/mod/applications/mod_easyroute/mod_easyroute.c b/src/mod/applications/mod_easyroute/mod_easyroute.c index e039c86e38..db5852ea91 100644 --- a/src/mod/applications/mod_easyroute/mod_easyroute.c +++ b/src/mod/applications/mod_easyroute/mod_easyroute.c @@ -165,8 +165,8 @@ static switch_status_t load_config(void) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot find SQL Database! (Where\'s the gateways table\?\?)\n"); } } - } else if (globals.db_dsn) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Connection (did you enable it?!)\n"); + } else if (!globals.db_dsn) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Connection (did you enable it?)\n"); } reallydone: diff --git a/src/mod/applications/mod_esf/mod_esf.c b/src/mod/applications/mod_esf/mod_esf.c index 87cfba30fa..d295ca4ae0 100644 --- a/src/mod/applications/mod_esf/mod_esf.c +++ b/src/mod/applications/mod_esf/mod_esf.c @@ -475,7 +475,10 @@ SWITCH_STANDARD_APP(bcast_function) read_impl.actual_samples_per_second, ebuf, &encoded_datalen, &rate, &flag); - read_frame->data = encoded_data; + if (read_frame->buflen >= encoded_datalen) { + memcpy(read_frame->data, encoded_data, encoded_datalen); + } + read_frame->datalen = encoded_datalen; } else { diff --git a/src/mod/applications/mod_hiredis/mod_hiredis.c b/src/mod/applications/mod_hiredis/mod_hiredis.c index 8a6077390c..2b1b85459f 100644 --- a/src/mod/applications/mod_hiredis/mod_hiredis.c +++ b/src/mod/applications/mod_hiredis/mod_hiredis.c @@ -41,7 +41,7 @@ SWITCH_STANDARD_APP(raw_app) switch_channel_t *channel = switch_core_session_get_channel(session); char *response = NULL, *profile_name = NULL, *cmd = NULL; hiredis_profile_t *profile = NULL; - + if ( !zstr(data) ) { profile_name = strdup(data); } else { @@ -63,7 +63,7 @@ SWITCH_STANDARD_APP(raw_app) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: Unable to locate profile[%s]\n", profile_name); return; } - + if ( hiredis_profile_execute_sync(profile, cmd, &response) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: profile[%s] error executing [%s] because [%s]\n", profile_name, cmd, response); } @@ -81,13 +81,13 @@ SWITCH_STANDARD_API(raw_api) hiredis_profile_t *profile = NULL; char *data = NULL, *input = NULL, *response = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; - + if ( !zstr(cmd) ) { input = strdup(cmd); } else { switch_goto_status(SWITCH_STATUS_GENERR, done); } - + if ( (data = strchr(input, ' '))) { *data = '\0'; data++; @@ -101,7 +101,7 @@ SWITCH_STANDARD_API(raw_api) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: Unable to locate profile[%s]\n", input); switch_goto_status(SWITCH_STATUS_GENERR, done); } - + if ( hiredis_profile_execute_sync(profile, data, &response) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: profile[%s] error executing [%s] reason:[%s]\n", input, data, response); switch_goto_status(SWITCH_STATUS_GENERR, done); @@ -114,24 +114,26 @@ SWITCH_STANDARD_API(raw_api) return status; } -/* -SWITCH_LIMIT_INCR(name) static switch_status_t name (switch_core_session_t *session, const char *realm, const char *resource, +/* +SWITCH_LIMIT_INCR(name) static switch_status_t name (switch_core_session_t *session, const char *realm, const char *resource, const int max, const int interval) */ SWITCH_LIMIT_INCR(hiredis_limit_incr) { switch_channel_t *channel = switch_core_session_get_channel(session); hiredis_profile_t *profile = NULL; - char *hashkey = NULL, *response = NULL; + char *hashkey = NULL, *response = NULL, *limit_key = NULL; int64_t count = 0; /* Redis defines the incr action as to be performed on a 64 bit signed integer */ time_t now = switch_epoch_time_now(NULL); switch_status_t status = SWITCH_STATUS_SUCCESS; + hiredis_limit_pvt_t *limit_pvt = NULL; + switch_memory_pool_t *session_pool = switch_core_session_get_pool(session); if ( zstr(realm) ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: realm must be defined\n"); switch_goto_status(SWITCH_STATUS_GENERR, done); } - + profile = switch_core_hash_find(mod_hiredis_globals.profiles, realm); if ( !profile ) { @@ -140,11 +142,13 @@ SWITCH_LIMIT_INCR(hiredis_limit_incr) } if ( interval ) { - hashkey = switch_mprintf("incr %s_%d", resource, now % interval); + limit_key = switch_mprintf("%s_%d", resource, now % interval); } else { - hashkey = switch_mprintf("incr %s", resource); + limit_key = switch_mprintf("%s", resource); } + hashkey = switch_mprintf("incr %s", limit_key); + if ( hiredis_profile_execute_sync(profile, hashkey, &response) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: profile[%s] error executing [%s] because [%s]\n", realm, hashkey, response); switch_channel_set_variable(channel, "hiredis_raw_response", response); @@ -153,6 +157,14 @@ SWITCH_LIMIT_INCR(hiredis_limit_incr) switch_channel_set_variable(channel, "hiredis_raw_response", response); + limit_pvt = switch_core_alloc(session_pool, sizeof(hiredis_limit_pvt_t)); + limit_pvt->next = switch_channel_get_private(channel, "hiredis_limit_pvt"); + limit_pvt->realm = switch_core_strdup(session_pool, realm); + limit_pvt->resource = switch_core_strdup(session_pool, resource); + limit_pvt->limit_key = switch_core_strdup(session_pool, limit_key); + limit_pvt->inc = 1; + switch_channel_set_private(channel, "hiredis_limit_pvt", limit_pvt); + count = atoll(response); if ( !count || count > max ) { @@ -160,6 +172,7 @@ SWITCH_LIMIT_INCR(hiredis_limit_incr) } done: + switch_safe_free(limit_key); switch_safe_free(response); switch_safe_free(hashkey); return status; @@ -174,32 +187,48 @@ SWITCH_LIMIT_RELEASE(hiredis_limit_release) hiredis_profile_t *profile = switch_core_hash_find(mod_hiredis_globals.profiles, realm); char *hashkey = NULL, *response = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; + hiredis_limit_pvt_t *limit_pvt = switch_channel_get_private(channel, "hiredis_limit_pvt"); if ( !zstr(realm) ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: realm must be defined\n"); switch_goto_status(SWITCH_STATUS_GENERR, done); } - + if ( !profile ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: Unable to locate profile[%s]\n", realm); switch_goto_status(SWITCH_STATUS_GENERR, done); } + /* If realm and resource are NULL, then clear all of the limits */ if ( !realm && !resource ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis does not yet support release on NULL realm[%s] and resource[%s]\n", realm, resource); - switch_goto_status(SWITCH_STATUS_GENERR, done); - } + hiredis_limit_pvt_t *tmp = limit_pvt; - hashkey = switch_mprintf("decr %s", resource); + while (tmp) { + hashkey = switch_mprintf("decr %s", tmp->limit_key); + limit_pvt = tmp->next; + + if ( hiredis_profile_execute_sync(profile, hashkey, &response) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: profile[%s] error executing [%s] because [%s]\n", + tmp->realm, hashkey, response); + } + + tmp = limit_pvt; + switch_safe_free(response); + switch_safe_free(hashkey); + } + } else { + + hashkey = switch_mprintf("decr %s", limit_pvt->limit_key); + + if ( hiredis_profile_execute_sync(profile, hashkey, &response) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: profile[%s] error executing [%s] because [%s]\n", realm, hashkey, response); + switch_channel_set_variable(channel, "hiredis_raw_response", response); + switch_goto_status(SWITCH_STATUS_GENERR, done); + } - if ( hiredis_profile_execute_sync(profile, hashkey, &response) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: profile[%s] error executing [%s] because [%s]\n", realm, hashkey, response); switch_channel_set_variable(channel, "hiredis_raw_response", response); - switch_goto_status(SWITCH_STATUS_GENERR, done); } - switch_channel_set_variable(channel, "hiredis_raw_response", response); - done: switch_safe_free(response); switch_safe_free(hashkey); @@ -212,14 +241,14 @@ SWITCH_LIMIT_USAGE(name) static int name (const char *realm, const char *resourc SWITCH_LIMIT_USAGE(hiredis_limit_usage) { hiredis_profile_t *profile = switch_core_hash_find(mod_hiredis_globals.profiles, realm); - int64_t count = 0; /* Redis defines the incr action as to be performed on a 64 bit signed integer */ + int64_t count = 0; /* Redis defines the incr action as to be performed on a 64 bit signed integer */ char *hashkey = NULL, *response = NULL; - + if ( !zstr(realm) ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: realm must be defined\n"); goto err; } - + if ( !profile ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: Unable to locate profile[%s]\n", realm); goto err; @@ -237,7 +266,7 @@ SWITCH_LIMIT_USAGE(hiredis_limit_usage) switch_safe_free(response); switch_safe_free(hashkey); return count; - + err: switch_safe_free(response); switch_safe_free(hashkey); @@ -251,7 +280,7 @@ SWITCH_LIMIT_RESET(hiredis_limit_reset) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: unable to globally reset hiredis limit resources. Use 'hiredis_raw set resource_name 0'\n"); - + return SWITCH_STATUS_GENERR; } @@ -263,12 +292,12 @@ SWITCH_LIMIT_INTERVAL_RESET(hiredis_limit_interval_reset) hiredis_profile_t *profile = switch_core_hash_find(mod_hiredis_globals.profiles, realm); switch_status_t status = SWITCH_STATUS_SUCCESS; char *hashkey = NULL, *response = NULL; - + if ( !zstr(realm) ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: realm must be defined\n"); switch_goto_status(SWITCH_STATUS_GENERR, done); } - + if ( !profile ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: Unable to locate profile[%s]\n", realm); switch_goto_status(SWITCH_STATUS_GENERR, done); @@ -306,7 +335,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_hiredis_load) mod_hiredis_globals.pool = pool; switch_core_hash_init(&(mod_hiredis_globals.profiles)); - + if ( mod_hiredis_do_config() != SWITCH_STATUS_SUCCESS ) { return SWITCH_STATUS_GENERR; } diff --git a/src/mod/applications/mod_hiredis/mod_hiredis.h b/src/mod/applications/mod_hiredis/mod_hiredis.h index becb565dcc..5655fc7501 100644 --- a/src/mod/applications/mod_hiredis/mod_hiredis.h +++ b/src/mod/applications/mod_hiredis/mod_hiredis.h @@ -29,9 +29,17 @@ typedef struct hiredis_profile_s { int debug; hiredis_connection_t *conn; - hiredis_connection_t *conn_head; + hiredis_connection_t *conn_head; } hiredis_profile_t; +typedef struct hiredis_limit_pvt_s { + char *realm; + char *resource; + char *limit_key; + int inc; + struct hiredis_limit_pvt_s *next; +} hiredis_limit_pvt_t; + switch_status_t mod_hiredis_do_config(); switch_status_t hiredis_profile_create(hiredis_profile_t **new_profile, char *name, uint8_t port); switch_status_t hiredis_profile_destroy(hiredis_profile_t **old_profile); diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index 9b9ec670e0..305986eebf 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -753,7 +753,6 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, if (*flag & SFF_PLC) { switch_core_session_t *session = codec->session; - switch_channel_t *channel = switch_core_session_get_channel(session); switch_jb_t *jb = NULL; plc = 1; @@ -761,6 +760,8 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, encoded_data = NULL; if ((opus_prefs.use_jb_lookahead || context->use_jb_lookahead) && context->codec_settings.useinbandfec && session) { + switch_channel_t *channel = switch_core_session_get_channel(session); + if (!context->look_check) { context->look_ts = switch_true(switch_channel_get_variable_dup(channel, "jb_use_timestamps", SWITCH_FALSE, -1)); context->look_check = 1; diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/serportx.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/serportx.h index bb00d97672..4d29bb4ccc 100644 --- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/serportx.h +++ b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/serportx.h @@ -13,7 +13,7 @@ #include #include "ctb-0.16/iobase.h" -#if _MSC_VER < 1900 +#if defined(_MSC_VER) && _MSC_VER < 1900 # define snprintf _snprintf #endif diff --git a/src/mod/endpoints/mod_rtmp/mod_rtmp.c b/src/mod/endpoints/mod_rtmp/mod_rtmp.c index 9066148566..a838fa3423 100644 --- a/src/mod/endpoints/mod_rtmp/mod_rtmp.c +++ b/src/mod/endpoints/mod_rtmp/mod_rtmp.c @@ -2030,6 +2030,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_rtmp_load) rtmp_register_invoke_function("connect", rtmp_i_connect); rtmp_register_invoke_function("createStream", rtmp_i_createStream); + rtmp_register_invoke_function("initStream", rtmp_i_initStream); rtmp_register_invoke_function("closeStream", rtmp_i_noop); rtmp_register_invoke_function("deleteStream", rtmp_i_noop); rtmp_register_invoke_function("play", rtmp_i_play); diff --git a/src/mod/endpoints/mod_rtmp/mod_rtmp.h b/src/mod/endpoints/mod_rtmp/mod_rtmp.h index 8c398d76d7..d75410c315 100644 --- a/src/mod/endpoints/mod_rtmp/mod_rtmp.h +++ b/src/mod/endpoints/mod_rtmp/mod_rtmp.h @@ -596,6 +596,7 @@ typedef enum { /* Invokable functions from flash */ RTMP_INVOKE_FUNCTION(rtmp_i_connect); RTMP_INVOKE_FUNCTION(rtmp_i_createStream); +RTMP_INVOKE_FUNCTION(rtmp_i_initStream); RTMP_INVOKE_FUNCTION(rtmp_i_noop); RTMP_INVOKE_FUNCTION(rtmp_i_play); RTMP_INVOKE_FUNCTION(rtmp_i_publish); diff --git a/src/mod/endpoints/mod_rtmp/rtmp_sig.c b/src/mod/endpoints/mod_rtmp/rtmp_sig.c index a526d8e1ea..c319fc7881 100644 --- a/src/mod/endpoints/mod_rtmp/rtmp_sig.c +++ b/src/mod/endpoints/mod_rtmp/rtmp_sig.c @@ -134,7 +134,16 @@ RTMP_INVOKE_FUNCTION(rtmp_i_createStream) amf0_number_new(rsession->next_streamid), NULL); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rsession->uuid), SWITCH_LOG_INFO, "Replied to createStream (%u)\n", rsession->next_streamid); + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rsession->uuid), SWITCH_LOG_INFO, "Replied to createStream (%u)\n", amf0_get_number(argv[1])); + + rsession->next_streamid++; + + return SWITCH_STATUS_SUCCESS; +} + +RTMP_INVOKE_FUNCTION(rtmp_i_initStream) +{ + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rsession->uuid), SWITCH_LOG_INFO, "Received initStream (%u)\n", rsession->next_streamid); rsession->next_streamid++; @@ -222,7 +231,7 @@ RTMP_INVOKE_FUNCTION(rtmp_i_play) rtmp_send_invoke_free(rsession, RTMP_DEFAULT_STREAM_NOTIFY, 0, rsession->media_streamid, amf0_str("onStatus"), - amf0_number_new(1), + amf0_number_new(0), amf0_null_new(), object, NULL); @@ -236,7 +245,7 @@ RTMP_INVOKE_FUNCTION(rtmp_i_play) rtmp_send_invoke_free(rsession, RTMP_DEFAULT_STREAM_NOTIFY, 0, rsession->media_streamid, amf0_str("onStatus"), - amf0_number_new(1), + amf0_number_new(0), amf0_null_new(), object, NULL); @@ -256,6 +265,7 @@ RTMP_INVOKE_FUNCTION(rtmp_i_play) RTMP_INVOKE_FUNCTION(rtmp_i_publish) { + amf0_data *object = amf0_object_new(); unsigned char buf[] = { INT16(RTMP_CTRL_STREAM_BEGIN), @@ -264,12 +274,17 @@ RTMP_INVOKE_FUNCTION(rtmp_i_publish) rtmp_send_message(rsession, 2, 0, RTMP_TYPE_USERCTRL, 0, buf, sizeof(buf), 0); - rtmp_send_invoke_free(rsession, amfnumber, 0, 0, - amf0_str("_result"), - amf0_number_new(transaction_id), + amf0_object_add(object, "level", amf0_str("status")); + amf0_object_add(object, "code", amf0_str("NetStream.Publish.Start")); + amf0_object_add(object, "description", amf0_str("description")); + amf0_object_add(object, "details", amf0_str("details")); + amf0_object_add(object, "clientid", amf0_number_new(217834719)); + + rtmp_send_invoke_free(rsession, RTMP_DEFAULT_STREAM_NOTIFY, 0, state->stream_id, + amf0_str("onStatus"), + amf0_number_new(0), amf0_null_new(), - amf0_null_new(), - NULL); + object, NULL); switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rsession->uuid), SWITCH_LOG_INFO, "Got publish on stream %u.\n", state->stream_id); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index d74688c70c..8689295222 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -842,6 +842,11 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) } } + if ((tech_pvt->mparams.last_sdp_str && strstr(tech_pvt->mparams.last_sdp_str, "a=setup")) || + (tech_pvt->mparams.local_sdp_str && strstr(tech_pvt->mparams.local_sdp_str, "a=setup"))) { + session_timeout = 0; + } + if ((tech_pvt->session_timeout = session_timeout)) { tech_pvt->session_refresher = switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? nua_local_refresher : nua_remote_refresher; } else { @@ -1452,7 +1457,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi { char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX); - nua_invite(tech_pvt->nh, NUTAG_MEDIA_ENABLE(0), SIPTAG_PAYLOAD_STR(msg->string_arg), + nua_invite(tech_pvt->nh, NUTAG_MEDIA_ENABLE(0), + TAG_IF(msg->string_arg, SIPTAG_CONTENT_TYPE_STR("application/sdp")), + TAG_IF(msg->string_arg, SIPTAG_PAYLOAD_STR(msg->string_arg)), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END()); switch_safe_free(extra_headers); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index d69a5bd291..2a06e882ef 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6517,12 +6517,17 @@ void *SWITCH_THREAD_FUNC media_on_hold_thread_run(switch_thread_t *thread, void switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL); switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL); - switch_ivr_media(switch_core_session_get_uuid(other_session), SMF_REBRIDGE|SMF_REPLYONLY_B); - - if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) { - switch_core_media_clear_rtp_flag(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ); + if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) { + switch_ivr_media(switch_core_session_get_uuid(other_session), SMF_REBRIDGE|SMF_REPLYONLY_B); + } else { + switch_ivr_media(switch_core_session_get_uuid(other_session), SMF_REBRIDGE); } + + switch_core_media_clear_rtp_flag(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ); + switch_core_media_clear_rtp_flag(other_session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ); + + switch_core_media_toggle_hold(session, 1); } switch_core_session_rwunlock(other_session); @@ -7023,7 +7028,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), SIPTAG_CONTACT_STR(tech_pvt->reply_contact), //SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str), - SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), + TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_CONTENT_TYPE_STR("application/sdp")), + TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str)), //SOATAG_REUSE_REJECTED(1), //SOATAG_RTP_SELECT(1), SOATAG_AUDIO_AUX("cn telephone-event"), @@ -7334,7 +7340,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_core_session_message_t *msg; private_object_t *other_tech_pvt; int media_on_hold = switch_true(switch_channel_get_variable_dup(channel, "bypass_media_resume_on_hold", SWITCH_FALSE, -1)); - + + switch_core_media_clear_rtp_flag(other_session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ); + if (switch_channel_test_flag(channel, CF_PROXY_MODE) && !is_t38 && ((profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) || media_on_hold)) { if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp)) { @@ -7342,6 +7350,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp); switch_channel_clear_flag(channel, CF_PROXY_MODE); switch_core_media_set_local_sdp(tech_pvt->session, NULL, SWITCH_FALSE); + switch_core_media_clear_rtp_flag(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ); if (!switch_channel_media_ready(channel)) { if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) { diff --git a/src/mod/event_handlers/mod_amqp/mod_amqp.h b/src/mod/event_handlers/mod_amqp/mod_amqp.h index 56e7e6372d..f82a8c5a9c 100644 --- a/src/mod/event_handlers/mod_amqp/mod_amqp.h +++ b/src/mod/event_handlers/mod_amqp/mod_amqp.h @@ -128,6 +128,7 @@ typedef struct { char *name; char *exchange; + char *queue; char *binding_key; /* Note: The AMQP channel is not reentrant this MUTEX serializes sending events. */ diff --git a/src/mod/event_handlers/mod_amqp/mod_amqp_command.c b/src/mod/event_handlers/mod_amqp/mod_amqp_command.c index 6299b7a656..ba12ffcba6 100644 --- a/src/mod/event_handlers/mod_amqp/mod_amqp_command.c +++ b/src/mod/event_handlers/mod_amqp/mod_amqp_command.c @@ -86,7 +86,7 @@ switch_status_t mod_amqp_command_create(char *name, switch_xml_t cfg) switch_xml_t params, param, connections, connection; switch_threadattr_t *thd_attr = NULL; switch_memory_pool_t *pool; - char *exchange = NULL, *binding_key = NULL; + char *exchange = NULL, *binding_key = NULL, *queue = NULL; if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { goto err; @@ -119,8 +119,10 @@ switch_status_t mod_amqp_command_create(char *name, switch_xml_t cfg) if ( interval && interval > 0 ) { profile->reconnect_interval_ms = interval; } - } else if (!strncmp(var, "exchange", 8)) { + } else if (!strncmp(var, "exchange-name", 13)) { exchange = switch_core_strdup(profile->pool, val); + } else if (!strncmp(var, "queue-name", 10)) { + queue = switch_core_strdup(profile->pool, val); } else if (!strncmp(var, "binding_key", 11)) { binding_key = switch_core_strdup(profile->pool, val); } @@ -129,6 +131,7 @@ switch_status_t mod_amqp_command_create(char *name, switch_xml_t cfg) /* Handle defaults of string types */ profile->exchange = exchange ? exchange : switch_core_strdup(profile->pool, "TAP.Commands"); + profile->queue = queue ? queue : NULL; profile->binding_key = binding_key ? binding_key : switch_core_strdup(profile->pool, "commandBindingKey"); if ((connections = switch_xml_child(cfg, "connections")) != NULL) { @@ -151,11 +154,8 @@ switch_status_t mod_amqp_command_create(char *name, switch_xml_t cfg) } } profile->conn_active = NULL; - - if ( mod_amqp_connection_open(profile->conn_root, &(profile->conn_active), profile->name, profile->custom_attr) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile[%s] was unable to connect to any connection\n", profile->name); - } - + /* We are not going to open the command queue connection on create, but instead wait for the running thread to open it */ + /* Start the worker threads */ switch_threadattr_create(&thd_attr, profile->pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); @@ -200,11 +200,24 @@ void * SWITCH_THREAD_FUNC mod_amqp_command_thread(switch_thread_t *thread, void continue; } + /* Check if exchange already exists */ + amqp_exchange_declare(profile->conn_active->state, 1, + amqp_cstring_bytes(profile->exchange), + amqp_cstring_bytes("topic"), + 0, /* passive */ + 1, /* durable */ + amqp_empty_table); + + if (mod_amqp_log_if_amqp_error(amqp_get_rpc_reply(profile->conn_active->state), "Checking for command exchange")) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to create missing command exchange", profile->name); + continue; + } + /* Ensure we have a queue */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Creating command queue"); recv_queue = amqp_queue_declare(profile->conn_active->state, // state 1, // channel - amqp_empty_bytes, // queue name + profile->queue ? amqp_cstring_bytes(profile->queue) : amqp_empty_bytes, // queue name 0, 0, // passive, durable 0, 1, // exclusive, auto-delete amqp_empty_table); // args diff --git a/src/mod/event_handlers/mod_amqp/mod_amqp_producer.c b/src/mod/event_handlers/mod_amqp/mod_amqp_producer.c index 088be1e1ff..3c82aa6225 100644 --- a/src/mod/event_handlers/mod_amqp/mod_amqp_producer.c +++ b/src/mod/event_handlers/mod_amqp/mod_amqp_producer.c @@ -176,7 +176,6 @@ switch_status_t mod_amqp_producer_create(char *name, switch_xml_t cfg) switch_threadattr_t *thd_attr = NULL; char *exchange = NULL, *exchange_type = NULL, *content_type = NULL; int exchange_durable = 1; /* durable */ - int exchange_auto_delete = 0; int delivery_mode = -1; int delivery_timestamp = 1; switch_memory_pool_t *pool; @@ -246,8 +245,6 @@ switch_status_t mod_amqp_producer_create(char *name, switch_xml_t cfg) exchange = switch_core_strdup(profile->pool, val); } else if (!strncmp(var, "exchange-durable", 16)) { exchange_durable = switch_true(val); - } else if (!strncmp(var, "exchange-auto-delete", 20)) { - exchange_auto_delete = switch_true(val); } else if (!strncmp(var, "delivery-mode", 13)) { delivery_mode = atoi(val); } else if (!strncmp(var, "delivery-timestamp", 18)) { @@ -289,7 +286,6 @@ switch_status_t mod_amqp_producer_create(char *name, switch_xml_t cfg) profile->exchange = exchange ? exchange : switch_core_strdup(profile->pool, "TAP.Events"); profile->exchange_type = exchange_type ? exchange_type : switch_core_strdup(profile->pool, "topic"); profile->exchange_durable = exchange_durable; - profile->exchange_auto_delete = exchange_auto_delete; profile->delivery_mode = delivery_mode; profile->delivery_timestamp = delivery_timestamp; profile->content_type = content_type ? content_type : switch_core_strdup(profile->pool, MOD_AMQP_DEFAULT_CONTENT_TYPE); @@ -340,8 +336,8 @@ switch_status_t mod_amqp_producer_create(char *name, switch_xml_t cfg) amqp_exchange_declare(profile->conn_active->state, 1, amqp_cstring_bytes(profile->exchange), amqp_cstring_bytes(profile->exchange_type), + 0, /* passive */ profile->exchange_durable, - profile->exchange_auto_delete, amqp_empty_table); if (mod_amqp_log_if_amqp_error(amqp_get_rpc_reply(profile->conn_active->state), "Declaring exchange")) { diff --git a/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c b/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c index 720a164d30..15add81d79 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c @@ -288,7 +288,7 @@ static iks *prompt_component_handle_input_error(struct rayo_actor *prompt, struc RAYO_SEND_REPLY(prompt, RAYO_COMPONENT(prompt)->client_jid, iq); /* done */ - iks_delete(PROMPT_COMPONENT(prompt)->iq); + PROMPT_COMPONENT(prompt)->iq = NULL; RAYO_RELEASE(prompt); RAYO_DESTROY(prompt); 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 a8a530bd46..0ff2b7cec3 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -1108,7 +1108,7 @@ SWITCH_STANDARD_API(local_stream_function) local_stream_name = argv[1]; - if (!strcasecmp(argv[0], "hup")) { + if (!strcasecmp(argv[0], "hup") && local_stream_name) { switch_mutex_lock(globals.mutex); source = switch_core_hash_find(globals.source_hash, local_stream_name); switch_mutex_unlock(globals.mutex); @@ -1118,7 +1118,7 @@ SWITCH_STANDARD_API(local_stream_function) stream->write_function(stream, "+OK hup stream: %s", source->name); goto done; } - } else if (!strcasecmp(argv[0], "stop")) { + } else if (!strcasecmp(argv[0], "stop") && local_stream_name) { switch_mutex_lock(globals.mutex); source = switch_core_hash_find(globals.source_hash, local_stream_name); switch_mutex_unlock(globals.mutex); @@ -1130,7 +1130,7 @@ SWITCH_STANDARD_API(local_stream_function) source->stopped = 1; stream->write_function(stream, "+OK"); - } else if (!strcasecmp(argv[0], "reload")) { + } else if (!strcasecmp(argv[0], "reload") && local_stream_name) { switch_mutex_lock(globals.mutex); source = switch_core_hash_find(globals.source_hash, local_stream_name); switch_mutex_unlock(globals.mutex); @@ -1143,7 +1143,7 @@ SWITCH_STANDARD_API(local_stream_function) source->full_reload = 1; source->part_reload = 1; stream->write_function(stream, "+OK"); - } else if (!strcasecmp(argv[0], "start")) { + } else if (!strcasecmp(argv[0], "start") && local_stream_name) { switch_mutex_lock(globals.mutex); source = switch_core_hash_find(globals.source_hash, local_stream_name); switch_mutex_unlock(globals.mutex); diff --git a/src/switch_channel.c b/src/switch_channel.c index f528f84a9d..fc587b8b20 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -499,7 +499,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf(switch_channel_t *chan int x = 0; if (!sensitive) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "RECV DTMF %c:%d\n", new_dtmf.digit, new_dtmf.duration); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_INFO, "RECV DTMF %c:%d\n", new_dtmf.digit, new_dtmf.duration); } if (new_dtmf.digit != 'w' && new_dtmf.digit != 'W') { diff --git a/src/switch_core.c b/src/switch_core.c index 7e79a92f42..b7b14fded2 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -928,7 +928,7 @@ SWITCH_DECLARE(int32_t) switch_core_set_process_privileges(void) SWITCH_DECLARE(int32_t) set_low_priority(void) { #ifdef WIN32 - SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS); + return SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS); #else #if defined(USE_SCHED_SETSCHEDULER) && ! defined(SOLARIS_PRIVILEGES) /* @@ -955,16 +955,16 @@ SWITCH_DECLARE(int32_t) set_low_priority(void) fprintf(stderr, "ERROR: Could not set nice level\n"); return -1; } -#endif #endif return 0; +#endif } SWITCH_DECLARE(int32_t) set_realtime_priority(void) { #ifdef WIN32 - SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); + return SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); #else #ifdef USE_SCHED_SETSCHEDULER /* diff --git a/src/switch_core_media.c b/src/switch_core_media.c index d2846fa637..06dc92ebaf 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -1820,7 +1820,7 @@ SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *ses -static void check_jb(switch_core_session_t *session, const char *input, int32_t jb_msec, int32_t maxlen) +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; switch_media_handle_t *smh; @@ -1920,8 +1920,8 @@ static void check_jb(switch_core_session_t *session, const char *input, int32_t 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 { - int qlen, maxqlen = 30; - + int qlen, maxqlen = 50; + qlen = jb_msec / (a_engine->read_impl.microseconds_per_packet / 1000); if (maxlen) { @@ -1934,14 +1934,16 @@ static void check_jb(switch_core_session_t *session, const char *input, int32_t 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, "Setting Jitterbuffer to %dms (%d frames) (%d max frames)\n", - jb_msec, qlen, maxqlen); + if (!silent) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_DEBUG, "Setting 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 { + } else if (!silent) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen); } @@ -2028,14 +2030,14 @@ static void check_jb_sync(switch_core_session_t *session) } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), - SWITCH_LOG_DEBUG, "%s %s \"%s\" Sync A/V JB to %dms %u VFrames FPS %u a:%s v:%s\n", + SWITCH_LOG_DEBUG1, "%s %s \"%s\" Sync A/V JB to %dms %u VFrames FPS %u a:%s v:%s\n", switch_core_session_get_uuid(session), switch_channel_get_name(session->channel), switch_channel_get_variable_dup(session->channel, "caller_id_name", SWITCH_FALSE, -1), jb_sync_msec, frames, fps, sync_audio ? "yes" : "no", sync_video ? "yes" : "no"); if (sync_audio) { - check_jb(session, NULL, jb_sync_msec, 0); + check_jb(session, NULL, jb_sync_msec, 0, SWITCH_TRUE); } } @@ -2213,7 +2215,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session } } - check_jb(session, NULL, 0, 0); + check_jb(session, NULL, 0, 0, SWITCH_FALSE); engine->check_frames = 0; engine->last_ts = 0; @@ -3571,7 +3573,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s { uint8_t match = 0; uint8_t vmatch = 0; - switch_payload_t best_te = 0, te = 0, cng_pt = 0; + switch_payload_t best_te = 0, cng_pt = 0; unsigned long best_te_rate = 8000, cng_rate = 8000; sdp_media_t *m; sdp_attribute_t *attr; @@ -4061,7 +4063,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (!best_te || map->rm_rate == a_engine->cur_payload_map->rm_rate) { best_te = (switch_payload_t) map->rm_pt; best_te_rate = map->rm_rate; - smh->mparams->recv_te = best_te; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set telephone-event payload to %u@%ld\n", best_te, best_te_rate); } continue; @@ -4405,7 +4406,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (!best_te || map->rm_rate == a_engine->cur_payload_map->adv_rm_rate) { best_te = (switch_payload_t) map->rm_pt; best_te_rate = map->rm_rate; - smh->mparams->recv_te = best_te; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set telephone-event payload to %u@%lu\n", best_te, best_te_rate); } continue; @@ -4442,41 +4442,41 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s } if (best_te) { - if (sdp_type == SDP_TYPE_RESPONSE) { - te = smh->mparams->te = (switch_payload_t) best_te; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Set 2833 dtmf send payload to %u\n", - switch_channel_get_name(session->channel), best_te); + smh->mparams->te_rate = best_te_rate; + + if (sdp_type == SDP_TYPE_REQUEST) { + smh->mparams->te = smh->mparams->recv_te = (switch_payload_t) best_te; switch_channel_set_variable(session->channel, "dtmf_type", "rfc2833"); smh->mparams->dtmf_type = DTMF_2833; - if (a_engine->rtp_session) { - switch_rtp_set_telephony_event(a_engine->rtp_session, (switch_payload_t) best_te); - switch_channel_set_variable_printf(session->channel, "rtp_2833_send_payload", "%d", best_te); - } } else { - te = smh->mparams->recv_te = smh->mparams->te = (switch_payload_t) best_te; - smh->mparams->te_rate = best_te_rate; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Set 2833 dtmf send/recv payload to %u\n", - switch_channel_get_name(session->channel), te); + smh->mparams->te = (switch_payload_t) best_te; switch_channel_set_variable(session->channel, "dtmf_type", "rfc2833"); smh->mparams->dtmf_type = DTMF_2833; - if (a_engine->rtp_session) { - switch_rtp_set_telephony_event(a_engine->rtp_session, te); - switch_channel_set_variable_printf(session->channel, "rtp_2833_send_payload", "%d", te); - switch_rtp_set_telephony_recv_event(a_engine->rtp_session, te); - switch_channel_set_variable_printf(session->channel, "rtp_2833_recv_payload", "%d", te); - } } + + if (a_engine->rtp_session) { + switch_rtp_set_telephony_event(a_engine->rtp_session, smh->mparams->te); + switch_channel_set_variable_printf(session->channel, "rtp_2833_send_payload", "%d", smh->mparams->te); + switch_rtp_set_telephony_recv_event(a_engine->rtp_session, smh->mparams->recv_te); + switch_channel_set_variable_printf(session->channel, "rtp_2833_recv_payload", "%d", smh->mparams->recv_te); + } + + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Set 2833 dtmf send payload to %u recv payload to %u\n", + switch_channel_get_name(session->channel), smh->mparams->te, smh->mparams->recv_te); + + } else { /* by default, use SIP INFO if 2833 is not in the SDP */ if (!switch_false(switch_channel_get_variable(channel, "rtp_info_when_no_2833"))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No 2833 in SDP. Disable 2833 dtmf and switch to INFO\n"); switch_channel_set_variable(session->channel, "dtmf_type", "info"); smh->mparams->dtmf_type = DTMF_INFO; - te = smh->mparams->recv_te = smh->mparams->te = 0; + smh->mparams->recv_te = smh->mparams->te = 0; } else { switch_channel_set_variable(session->channel, "dtmf_type", "none"); smh->mparams->dtmf_type = DTMF_NONE; - te = smh->mparams->recv_te = smh->mparams->te = 0; + smh->mparams->recv_te = smh->mparams->te = 0; } } @@ -6234,7 +6234,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi interval = 5000; } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating RTCP PORT %d\n", remote_rtcp_port); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Activating RTCP PORT %d\n", remote_rtcp_port); switch_rtp_activate_rtcp(a_engine->rtp_session, interval, remote_rtcp_port, a_engine->rtcp_mux > 0); } @@ -6285,7 +6285,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi } - check_jb(session, NULL, 0, 0); + check_jb(session, NULL, 0, 0, SWITCH_FALSE); if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec"))) { int v = atoi(val); @@ -6728,7 +6728,7 @@ static const char *get_media_profile_name(switch_core_session_t *session, int se switch_assert(session); if (switch_channel_test_flag(session->channel, CF_AVPF)) { - if (switch_channel_test_flag(session->channel, CF_DTLS)) { + if (switch_channel_test_flag(session->channel, CF_DTLS) || secure) { if (switch_channel_test_flag(session->channel, CF_AVPF_MOZ)) { return "UDP/TLS/RTP/SAVPF"; } else { @@ -8662,7 +8662,7 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 1); clear_pmaps(v_engine); pmap = switch_core_media_add_payload_map(session, - SWITCH_MEDIA_TYPE_AUDIO, + SWITCH_MEDIA_TYPE_VIDEO, "PROXY-VID", NULL, NULL, @@ -8675,11 +8675,15 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) v_engine->cur_payload_map = pmap; switch_snprintf(vport_buf, sizeof(vport_buf), "%u", v_engine->adv_sdp_port); + if (switch_channel_media_ready(session->channel) && !switch_rtp_ready(v_engine->rtp_session)) { switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE); switch_channel_set_flag(session->channel, CF_REINVITE); switch_core_media_activate_rtp(session); } + + v_engine->codec_negotiated = 1; + switch_core_media_set_video_codec(session, SWITCH_FALSE); } strncpy(q, p, 8); @@ -8950,7 +8954,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se case SWITCH_MESSAGE_INDICATE_JITTER_BUFFER: { if (switch_rtp_ready(a_engine->rtp_session)) { - check_jb(session, msg->string_arg, 0, 0); + check_jb(session, msg->string_arg, 0, 0, SWITCH_FALSE); } } break; diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index d55b8ac29b..09e225aef4 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -199,7 +199,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_set_terminators(switch_ivr_d dmachine->realm->terminators = switch_core_strdup(dmachine->pool, terminators); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Digit parser %s: Setting terminators for realm '%s' to '%s'\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Digit parser %s: Setting terminators for realm '%s' to '%s'\n", dmachine->name, dmachine->realm->name, terminators); return SWITCH_STATUS_SUCCESS; diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index e25fff1bf5..d17d3fa77c 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -77,28 +77,30 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj) switch_codec_t *b_codec = switch_core_session_get_video_write_codec(vh->session_b); switch_file_handle_t *fh; - switch_assert(a_codec); - switch_assert(b_codec); - if (switch_channel_test_flag(channel, CF_VIDEO_REFRESH_REQ)) { refresh_timer = refresh_cnt; } - if (switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ)) { - if (a_codec->implementation->impl_id == b_codec->implementation->impl_id && !switch_channel_test_flag(b_channel, CF_VIDEO_DECODED_READ)) { - if (set_decoded_read) { - switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ); - set_decoded_read = 0; + if (!switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { + switch_assert(a_codec); + switch_assert(b_codec); + + if (switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ)) { + if (a_codec->implementation->impl_id == b_codec->implementation->impl_id && !switch_channel_test_flag(b_channel, CF_VIDEO_DECODED_READ)) { + if (set_decoded_read) { + switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ); + set_decoded_read = 0; + refresh_timer = refresh_cnt; + } + } + } else { + if (a_codec->implementation->impl_id != b_codec->implementation->impl_id || + switch_channel_test_flag(b_channel, CF_VIDEO_DECODED_READ)) { + switch_channel_set_flag_recursive(channel, CF_VIDEO_DECODED_READ); + set_decoded_read = 1; refresh_timer = refresh_cnt; } } - } else { - if (a_codec->implementation->impl_id != b_codec->implementation->impl_id || - switch_channel_test_flag(b_channel, CF_VIDEO_DECODED_READ)) { - switch_channel_set_flag_recursive(channel, CF_VIDEO_DECODED_READ); - set_decoded_read = 1; - refresh_timer = refresh_cnt; - } } if (refresh_timer) { diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index a71cbd537b..c65b80b7d4 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -817,6 +817,9 @@ struct ringback { switch_file_handle_t *fh; int silence; uint8_t asis; + int channels; + void *mux_buf; + int mux_buflen; }; typedef struct ringback ringback_t; @@ -825,12 +828,29 @@ static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map { ringback_t *tto = ts->user_data; int wrote; + void *buf; + int buflen; if (!tto) { return -1; } wrote = teletone_mux_tones(ts, map); - switch_buffer_write(tto->audio_buffer, ts->buffer, wrote * 2); + + if (tto->channels != 1) { + if (tto->mux_buflen < wrote * 2 * tto->channels) { + tto->mux_buflen = wrote * 2 * tto->channels; + tto->mux_buf = realloc(tto->mux_buf, tto->mux_buflen); + } + memcpy(tto->mux_buf, ts->buffer, wrote * 2); + switch_mux_channels((int16_t *) tto->mux_buf, wrote, 1, tto->channels); + buf = tto->mux_buf; + buflen = wrote * 2 * tto->channels; + } else { + buf = ts->buffer; + buflen = wrote * 2; + } + + switch_buffer_write(tto->audio_buffer, buf, buflen); return 0; } @@ -926,7 +946,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_answer(switch_core_session_t NULL, read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, + read_codec->implementation->number_of_channels, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error!\n"); if (caller_channel) { @@ -994,6 +1014,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_answer(switch_core_session_t teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback); ringback.ts.rate = read_codec->implementation->actual_samples_per_second; + ringback.channels = read_codec->implementation->number_of_channels; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data); if (teletone_run(&ringback.ts, ringback_data)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Playing Tone\n"); @@ -1107,6 +1128,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_answer(switch_core_session_t ringback.fh = NULL; } else if (ringback.audio_buffer) { teletone_destroy_session(&ringback.ts); + switch_safe_free(ringback.mux_buf); switch_buffer_destroy(&ringback.audio_buffer); } @@ -1238,22 +1260,22 @@ static switch_status_t setup_ringback(originate_global_t *oglobals, originate_st } else { switch_core_session_get_read_impl(oglobals->session, &peer_read_impl); } - + if (switch_core_codec_init(write_codec, "L16", NULL, NULL, peer_read_impl.actual_samples_per_second, peer_read_impl.microseconds_per_packet / 1000, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, + peer_read_impl.number_of_channels, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(oglobals->session)) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_DEBUG, - "Raw Codec Activation Success L16@%uhz 1 channel %dms\n", - peer_read_impl.actual_samples_per_second, peer_read_impl.microseconds_per_packet / 1000); + "Raw Codec Activation Success L16@%uhz %d channel %dms\n", + peer_read_impl.actual_samples_per_second, peer_read_impl.number_of_channels, peer_read_impl.microseconds_per_packet / 1000); write_frame->codec = write_codec; - write_frame->datalen = read_codec->implementation->decoded_bytes_per_packet; + write_frame->datalen = peer_read_impl.decoded_bytes_per_packet; write_frame->samples = write_frame->datalen / 2; memset(write_frame->data, 255, write_frame->datalen); switch_core_session_set_read_codec(oglobals->session, write_codec); @@ -1317,6 +1339,7 @@ static switch_status_t setup_ringback(originate_global_t *oglobals, originate_st teletone_init_session(&ringback->ts, 0, teletone_handler, ringback); ringback->ts.rate = read_codec->implementation->actual_samples_per_second; + ringback->channels = read_codec->implementation->number_of_channels; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data); /* ringback->ts.debug = 1; ringback->ts.debug_stream = switch_core_get_console(); */ @@ -1782,7 +1805,7 @@ static void *SWITCH_THREAD_FUNC early_thread_run(switch_thread_t *thread, void * NULL, read_impl.actual_samples_per_second, read_impl.microseconds_per_packet / 1000, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, + read_impl.number_of_channels, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error!\n"); } @@ -3772,6 +3795,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess ringback.fh = NULL; } else if (ringback.audio_buffer) { teletone_destroy_session(&ringback.ts); + switch_safe_free(ringback.mux_buf); switch_buffer_destroy(&ringback.audio_buffer); } diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 27a40f537c..968c7d031d 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1047,7 +1047,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_channel_t *channel = switch_core_session_get_channel(session); int16_t *abuf = NULL; switch_dtmf_t dtmf = { 0 }; - uint32_t interval = 0, samples = 0, framelen, sample_start = 0; + uint32_t interval = 0, samples = 0, framelen, sample_start = 0, channels = 1; uint32_t ilen = 0; switch_size_t olen = 0, llen = 0; switch_frame_t write_frame = { 0 }; @@ -1388,6 +1388,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess write_frame.codec = switch_core_session_get_read_codec(session); samples = read_impl.samples_per_packet; framelen = read_impl.encoded_bytes_per_packet; + channels = read_impl.number_of_channels; if (framelen == 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s cannot play or record native files with variable length data\n", switch_channel_get_name(channel)); @@ -1410,6 +1411,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess write_frame.codec = &codec; samples = codec.implementation->samples_per_packet; framelen = codec.implementation->decoded_bytes_per_packet; + channels = codec.implementation->number_of_channels; } last_native = test_native; @@ -1417,8 +1419,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess if (timer_name && !timer.samplecount) { uint32_t len; - len = samples * 2; - if (switch_core_timer_init(&timer, timer_name, interval, samples / codec.implementation->number_of_channels, pool) != SWITCH_STATUS_SUCCESS) { + len = samples * 2 * channels; + if (switch_core_timer_init(&timer, timer_name, interval, samples, pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Setup timer failed!\n"); switch_core_codec_destroy(&codec); switch_core_session_io_write_lock(session); @@ -1444,7 +1446,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_core_service_session(session); } - ilen = samples; + ilen = samples * channels; if (switch_event_create(&event, SWITCH_EVENT_PLAYBACK_START) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(channel, event); diff --git a/src/switch_jitterbuffer.c b/src/switch_jitterbuffer.c index 530db657e3..748a399f77 100644 --- a/src/switch_jitterbuffer.c +++ b/src/switch_jitterbuffer.c @@ -37,7 +37,7 @@ #define PERIOD_LEN 250 #define MAX_FRAME_PADDING 2 #define MAX_MISSING_SEQ 20 -#define jb_debug(_jb, _level, _format, ...) if (_jb->debug_level >= _level) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(_jb->session), SWITCH_LOG_ALERT, "JB:%p:%s lv:%d ln:%d sz:%u/%u/%u/%u c:%u %u/%u/%u/%u %.2f%% ->" _format, (void *) _jb, (jb->type == SJB_AUDIO ? "aud" : "vid"), _level, __LINE__, _jb->min_frame_len, _jb->max_frame_len, _jb->frame_len, _jb->visible_nodes, _jb->period_count, _jb->consec_good_count, _jb->period_good_count, _jb->consec_miss_count, _jb->period_miss_count, _jb->period_miss_pct, __VA_ARGS__) +#define jb_debug(_jb, _level, _format, ...) if (_jb->debug_level >= _level) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(_jb->session), SWITCH_LOG_ALERT, "JB:%p:%s lv:%d ln:%d sz:%u/%u/%u/%u c:%u %u/%u/%u/%u %.2f%% ->" _format, (void *) _jb, (jb->type == SJB_AUDIO ? "aud" : "vid"), _level, __LINE__, _jb->min_frame_len, _jb->max_frame_len, _jb->frame_len, _jb->complete_frames, _jb->period_count, _jb->consec_good_count, _jb->period_good_count, _jb->consec_miss_count, _jb->period_miss_count, _jb->period_miss_pct, __VA_ARGS__) //const char *TOKEN_1 = "ONE"; //const char *TOKEN_2 = "TWO"; @@ -96,6 +96,7 @@ struct switch_jb_s { switch_mutex_t *list_mutex; switch_memory_pool_t *pool; int free_pool; + int drop_flag; switch_jb_flag_t flags; switch_jb_type_t type; switch_core_session_t *session; @@ -364,6 +365,36 @@ static inline uint32_t jb_find_lowest_ts(switch_jb_t *jb) return lowest ? lowest->packet.header.ts : 0; } +static inline void thin_frames(switch_jb_t *jb, int freq, int max) +{ + switch_jb_node_t *node; + int i = -1; + int dropped = 0; + + switch_mutex_lock(jb->list_mutex); + node = jb->node_list; + + for (node = jb->node_list; node && jb->complete_frames > jb->max_frame_len && dropped < max; node = node->next) { + + if (node->visible) { + i++; + } else { + continue; + } + + if ((i % freq) == 0) { + drop_ts(jb, node->packet.header.ts); + node = jb->node_list; + dropped++; + } + } + + sort_free_nodes(jb); + switch_mutex_unlock(jb->list_mutex); +} + + + #if 0 static inline switch_jb_node_t *jb_find_highest_node(switch_jb_t *jb) { @@ -389,8 +420,6 @@ static inline uint32_t jb_find_highest_ts(switch_jb_t *jb) return highest ? highest->packet.header.ts : 0; } - - static inline switch_jb_node_t *jb_find_penultimate_node(switch_jb_t *jb) { switch_jb_node_t *np, *highest = NULL, *second_highest = NULL; @@ -527,6 +556,16 @@ static inline void drop_newest_frame(switch_jb_t *jb) drop_ts(jb, ts); jb_debug(jb, 1, "Dropping highest frame ts:%u\n", ntohl(ts)); } + +static inline void drop_second_newest_frame(switch_jb_t *jb) +{ + switch_jb_node_t *second_newest = jb_find_penultimate_node(jb); + + if (second_newest) { + drop_ts(jb, second_newest->packet.header.ts); + jb_debug(jb, 1, "Dropping second highest frame ts:%u\n", ntohl(second_newest->packet.header.ts)); + } +} #endif static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len) @@ -802,7 +841,7 @@ SWITCH_DECLARE(void) switch_jb_reset(switch_jb_t *jb) jb_debug(jb, 2, "%s", "RESET BUFFER\n"); - + jb->drop_flag = 0; jb->last_target_seq = 0; jb->target_seq = 0; jb->write_init = 0; @@ -1195,6 +1234,11 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp jb->period_miss_pct = ((double)jb->period_miss_count / jb->period_count) * 100; + if (jb->period_miss_pct > 40.0f) { + jb_debug(jb, 2, "Miss percent %02f too high, resetting buffer.\n", jb->period_miss_pct); + //switch_jb_reset(jb); + } + if ((status = jb_next_packet(jb, &node)) == SWITCH_STATUS_SUCCESS) { jb_debug(jb, 2, "Found next frame cur ts: %u seq: %u\n", htonl(node->packet.header.ts), htons(node->packet.header.seq)); @@ -1281,9 +1325,9 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp switch_mutex_unlock(jb->mutex); - if (status == SWITCH_STATUS_SUCCESS && jb->type == SJB_AUDIO) { + if (status == SWITCH_STATUS_SUCCESS) { if (jb->complete_frames > jb->max_frame_len) { - drop_oldest_frame(jb); + thin_frames(jb, 8, 25); } } diff --git a/src/switch_pcm.c b/src/switch_pcm.c index 7c5a98756e..cc034b6be7 100644 --- a/src/switch_pcm.c +++ b/src/switch_pcm.c @@ -321,7 +321,7 @@ static void mod_g711_load(switch_loadable_module_interface_t ** module_interface 48000, /* actual samples transferred per second */ 64000 * 6 * 2, /* bits transferred per second */ mpf * count, /* number of microseconds per frame */ - spf * count * 6 * 2, /* number of samples per frame */ + spf * count * 6, /* number of samples per frame */ bpf * count * 6 * 2, /* number of bytes per frame decompressed */ ebpf * count * 6 * 2, /* number of bytes per frame compressed */ 2, /* number of channels represented */ @@ -574,7 +574,7 @@ SWITCH_MODULE_LOAD_FUNCTION(core_pcm_load) 48000, /* actual samples transferred per second */ 768000 * 2, /* bits transferred per second */ ms_per_frame, /* number of microseconds per frame */ - samples_per_frame * 2, /* number of samples per frame */ + samples_per_frame, /* number of samples per frame */ bytes_per_frame * 2, /* number of bytes per frame decompressed */ bytes_per_frame * 2, /* number of bytes per frame compressed */ 2, /* number of channels represented */ @@ -764,7 +764,7 @@ SWITCH_MODULE_LOAD_FUNCTION(core_pcm_load) 48000, /* actual samples transferred per second */ 768000 * 2, /* bits transferred per second */ ms_per_frame, /* number of microseconds per frame */ - samples_per_frame * 2, /* number of samples per frame */ + samples_per_frame, /* number of samples per frame */ bytes_per_frame * 2, /* number of bytes per frame decompressed */ bytes_per_frame * 2, /* number of bytes per frame compressed */ 2, /* number of channels represented */ diff --git a/src/switch_rtp.c b/src/switch_rtp.c index ea5fc24504..92191335b7 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4018,7 +4018,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_video_buffer_size(switch_rtp_t *r //switch_rtp_flush(rtp_session); switch_core_session_request_video_refresh(rtp_session->session); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "Setting video buffer %u Frames.\n", frames); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Setting video buffer %u Frames.\n", frames); return SWITCH_STATUS_SUCCESS; } @@ -5082,8 +5082,10 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t rtp_session->has_rtp = (rtp_session->recv_msg.header.version == 2 || ntohl(*(int *)(b+4)) == ZRTP_MAGIC_COOKIE); if ((*b >= 20) && (*b <= 64)) { - rtp_session->dtls->bytes = *bytes; - rtp_session->dtls->data = (void *) &rtp_session->recv_msg; + if (rtp_session->dtls) { + rtp_session->dtls->bytes = *bytes; + rtp_session->dtls->data = (void *) &rtp_session->recv_msg; + } rtp_session->has_ice = 0; rtp_session->has_rtp = 0; rtp_session->has_rtcp = 0; @@ -5508,6 +5510,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)) { status = switch_jb_put_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, *bytes); @@ -5525,12 +5528,8 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t } if (rtp_session->jb && !rtp_session->pause_jb && jb_valid(rtp_session)) { - uint32_t read_ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc); - if (rtp_session->last_rtp_hdr.m && rtp_session->last_rtp_hdr.pt != rtp_session->recv_te && - !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && !(rtp_session->rtp_bugs & RTP_BUG_IGNORE_MARK_BIT)) { - switch_jb_reset(rtp_session->jb); - } else if (rtp_session->last_jb_read_ssrc && rtp_session->last_jb_read_ssrc != read_ssrc) { + if (rtp_session->last_jb_read_ssrc && rtp_session->last_jb_read_ssrc != read_ssrc) { switch_jb_reset(rtp_session->jb); } @@ -5553,6 +5552,13 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (!return_jb_packet) { return status; } + } else { + if (rtp_session->last_rtp_hdr.m && rtp_session->last_rtp_hdr.pt != rtp_session->recv_te && + !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && !(rtp_session->rtp_bugs & RTP_BUG_IGNORE_MARK_BIT)) { + switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH); + } else if (rtp_session->last_jb_read_ssrc && rtp_session->last_jb_read_ssrc != read_ssrc) { + switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH); + } } } diff --git a/src/switch_utils.c b/src/switch_utils.c index f1cd1e572f..056b28c7bb 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -146,6 +146,7 @@ static switch_frame_t *find_free_frame(switch_frame_buffer_t *fb, switch_frame_t if (orig->packet) { np->frame->packet = switch_core_alloc(fb->pool, SWITCH_RTP_MAX_BUF_LEN); } else { + np->frame->packet = NULL; np->frame->data = switch_core_alloc(fb->pool, SWITCH_RTP_MAX_BUF_LEN); np->frame->buflen = SWITCH_RTP_MAX_BUF_LEN; } @@ -174,6 +175,7 @@ static switch_frame_t *find_free_frame(switch_frame_buffer_t *fb, switch_frame_t np->frame->data = ((unsigned char *)np->frame->packet) + 12; np->frame->datalen = orig->datalen; } else { + np->frame->packet = NULL; np->frame->packetlen = 0; memcpy(np->frame->data, orig->data, orig->datalen); np->frame->datalen = orig->datalen; @@ -285,6 +287,7 @@ SWITCH_DECLARE(switch_status_t) switch_frame_dup(switch_frame_t *orig, switch_fr memcpy(new_frame->packet, orig->packet, orig->packetlen); new_frame->data = ((unsigned char *)new_frame->packet) + 12; } else { + new_frame->packet = NULL; new_frame->data = malloc(new_frame->buflen); switch_assert(new_frame->data); memcpy(new_frame->data, orig->data, orig->datalen); @@ -304,24 +307,32 @@ SWITCH_DECLARE(switch_status_t) switch_frame_dup(switch_frame_t *orig, switch_fr SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame) { - if (!frame || !*frame || !switch_test_flag((*frame), SFF_DYNAMIC)) { + switch_frame_t * f; + + if (!frame) { return SWITCH_STATUS_FALSE; } - if ((*frame)->img) { - switch_img_free(&(*frame)->img); + f = *frame; + + if (!f || !switch_test_flag(f, SFF_DYNAMIC)) { + return SWITCH_STATUS_FALSE; } - if ((*frame)->packet) { - free((*frame)->packet); - (*frame)->packet = NULL; - } else { - switch_safe_free((*frame)->data); - } - - free(*frame); *frame = NULL; + if (f->img) { + switch_img_free(&(f->img)); + } + + if (f->packet) { + switch_safe_free(f->packet); + } else { + switch_safe_free(f->data); + } + + free(f); + return SWITCH_STATUS_SUCCESS; } diff --git a/w32/Library/FreeSwitchCore.2015.vcxproj b/w32/Library/FreeSwitchCore.2015.vcxproj index 70c3a48dea..9a881458f2 100644 --- a/w32/Library/FreeSwitchCore.2015.vcxproj +++ b/w32/Library/FreeSwitchCore.2015.vcxproj @@ -231,7 +231,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs MaxSpeed ..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\sqlite-amalgamation-3080401;..\..\libs\pcre-8.34;..\..\libs\speex-1.2rc1\include;..\..\libs\curl-7.35.0\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-4.0.2\libtiff;..\..\libs\libzrtp\include;..\..\libs\libzrtp\third_party\bgaes;..\..\libs\libzrtp\third_party\bnlib;..\..\libs\libtpl-1.5\src;..\..\libs\libtpl-1.5\src\win;..\..\libs\openssl-$(OpenSSLVersion)\include;..\..\libs\sofia-sip\libsofia-sip-ua\sdp;..\..\libs\sofia-sip\libsofia-sip-ua\su;..\..\libs\sofia-sip\win32;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;ENABLE_ZRTP;LIBSOFIA_SIP_UA_STATIC;HAVE_OPENSSL;HAVE_OPENSSL_DTLS_SRTP;HAVE_OPENSSL_DTLS;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;ENABLE_ZRTP;TPL_NOLIB;LIBSOFIA_SIP_UA_STATIC;HAVE_OPENSSL;HAVE_OPENSSL_DTLS_SRTP;HAVE_OPENSSL_DTLS;%(PreprocessorDefinitions) MultiThreadedDLL Create switch.h