Merge branch 'signalwire:master' into master
This commit is contained in:
commit
8c2b2a2b11
|
@ -554,6 +554,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_switch_core_db", "test
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_switch_ivr_originate", "tests\unit\test_switch_ivr_originate.2017.vcxproj", "{69A7464A-9B0D-4804-A108-835229DACF58}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_switch_ivr_originate", "tests\unit\test_switch_ivr_originate.2017.vcxproj", "{69A7464A-9B0D-4804-A108-835229DACF58}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_switch_core_codec", "tests\unit\test_switch_core_codec.2017.vcxproj", "{589A07E7-5DE5-49FD-A62C-27795B806AFB}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
All|Win32 = All|Win32
|
All|Win32 = All|Win32
|
||||||
|
@ -2516,6 +2518,18 @@ Global
|
||||||
{69A7464A-9B0D-4804-A108-835229DACF58}.Release|Win32.Build.0 = Release|Win32
|
{69A7464A-9B0D-4804-A108-835229DACF58}.Release|Win32.Build.0 = Release|Win32
|
||||||
{69A7464A-9B0D-4804-A108-835229DACF58}.Release|x64.ActiveCfg = Release|x64
|
{69A7464A-9B0D-4804-A108-835229DACF58}.Release|x64.ActiveCfg = Release|x64
|
||||||
{69A7464A-9B0D-4804-A108-835229DACF58}.Release|x64.Build.0 = Release|x64
|
{69A7464A-9B0D-4804-A108-835229DACF58}.Release|x64.Build.0 = Release|x64
|
||||||
|
{589A07E7-5DE5-49FD-A62C-27795B806AFB}.All|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{589A07E7-5DE5-49FD-A62C-27795B806AFB}.All|Win32.Build.0 = Debug|Win32
|
||||||
|
{589A07E7-5DE5-49FD-A62C-27795B806AFB}.All|x64.ActiveCfg = Debug|x64
|
||||||
|
{589A07E7-5DE5-49FD-A62C-27795B806AFB}.All|x64.Build.0 = Debug|x64
|
||||||
|
{589A07E7-5DE5-49FD-A62C-27795B806AFB}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{589A07E7-5DE5-49FD-A62C-27795B806AFB}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{589A07E7-5DE5-49FD-A62C-27795B806AFB}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{589A07E7-5DE5-49FD-A62C-27795B806AFB}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{589A07E7-5DE5-49FD-A62C-27795B806AFB}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{589A07E7-5DE5-49FD-A62C-27795B806AFB}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{589A07E7-5DE5-49FD-A62C-27795B806AFB}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{589A07E7-5DE5-49FD-A62C-27795B806AFB}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -2714,6 +2728,7 @@ Global
|
||||||
{0B612F84-7533-4DEC-AEDD-5C9CBCF15EAC} = {31C2761D-20E0-4BF8-98B9-E32F0D8DD6E1}
|
{0B612F84-7533-4DEC-AEDD-5C9CBCF15EAC} = {31C2761D-20E0-4BF8-98B9-E32F0D8DD6E1}
|
||||||
{580675D7-C1C9-4197-AAC5-00F64FAFDE78} = {9388C266-C3FC-468A-92EF-0CBC35941412}
|
{580675D7-C1C9-4197-AAC5-00F64FAFDE78} = {9388C266-C3FC-468A-92EF-0CBC35941412}
|
||||||
{69A7464A-9B0D-4804-A108-835229DACF58} = {9388C266-C3FC-468A-92EF-0CBC35941412}
|
{69A7464A-9B0D-4804-A108-835229DACF58} = {9388C266-C3FC-468A-92EF-0CBC35941412}
|
||||||
|
{589A07E7-5DE5-49FD-A62C-27795B806AFB} = {9388C266-C3FC-468A-92EF-0CBC35941412}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {09840DE7-9208-45AA-9667-1A71EE93BD1E}
|
SolutionGuid = {09840DE7-9208-45AA-9667-1A71EE93BD1E}
|
||||||
|
|
|
@ -67,8 +67,8 @@ This is the place to get answers faster and chat with other users in real time.
|
||||||
Slack Community:
|
Slack Community:
|
||||||
* https://signalwire.community/
|
* https://signalwire.community/
|
||||||
|
|
||||||
Mailing list:
|
Mailing list (ARCHIVED):
|
||||||
|
|
||||||
* http://lists.freeswitch.org/mailman/listinfo/freeswitch-users
|
* http://lists.freeswitch.org/pipermail/freeswitch-users/
|
||||||
|
|
||||||
**Thank you for using FreeSWITCH!**
|
**Thank you for using FreeSWITCH!**
|
||||||
|
|
|
@ -110,7 +110,6 @@ event_handlers/mod_event_socket
|
||||||
#event_handlers/mod_json_cdr
|
#event_handlers/mod_json_cdr
|
||||||
#event_handlers/mod_radius_cdr
|
#event_handlers/mod_radius_cdr
|
||||||
#event_handlers/mod_odbc_cdr
|
#event_handlers/mod_odbc_cdr
|
||||||
#event_handlers/mod_kazoo
|
|
||||||
#event_handlers/mod_rayo
|
#event_handlers/mod_rayo
|
||||||
#event_handlers/mod_smpp
|
#event_handlers/mod_smpp
|
||||||
#event_handlers/mod_snmp
|
#event_handlers/mod_snmp
|
||||||
|
|
|
@ -104,7 +104,6 @@ event_handlers/mod_event_multicast
|
||||||
event_handlers/mod_event_socket
|
event_handlers/mod_event_socket
|
||||||
event_handlers/mod_format_cdr
|
event_handlers/mod_format_cdr
|
||||||
event_handlers/mod_json_cdr
|
event_handlers/mod_json_cdr
|
||||||
event_handlers/mod_kazoo
|
|
||||||
#event_handlers/mod_radius_cdr
|
#event_handlers/mod_radius_cdr
|
||||||
event_handlers/mod_odbc_cdr
|
event_handlers/mod_odbc_cdr
|
||||||
event_handlers/mod_rayo
|
event_handlers/mod_rayo
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1.10.10-dev
|
1.10.12-dev
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,215 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<configuration name="kazoo.conf" description="General purpose Erlang c-node produced to better fit the Kazoo project">
|
|
||||||
<settings>
|
|
||||||
<param name="listen-ip" value="0.0.0.0" />
|
|
||||||
<param name="listen-port" value="8031" />
|
|
||||||
<!--<param name="cookie-file" value="/etc/freeswitch/autoload_configs/.erlang.cookie" />-->
|
|
||||||
<param name="cookie" value="change_me" />
|
|
||||||
<param name="shortname" value="false" />
|
|
||||||
<param name="nodename" value="freeswitch" />
|
|
||||||
<param name="send-msg-batch-size" value="10" />
|
|
||||||
<param name="receive-timeout" value="1" />
|
|
||||||
<!--<param name="receive-msg-preallocate" value="0" />-->
|
|
||||||
<!--<param name="event-stream-preallocate" value="0" />-->
|
|
||||||
<!--<param name="event-stream-framing" value="2" />-->
|
|
||||||
<!--<param name="kazoo-var-prefix" value="ecallmgr" />-->
|
|
||||||
<!--<param name="compat-rel" value="12"/> -->
|
|
||||||
</settings>
|
|
||||||
<event-filter type="whitelist">
|
|
||||||
<header name="Acquired-UUID" />
|
|
||||||
<header name="action" />
|
|
||||||
<header name="Action" />
|
|
||||||
<header name="alt_event_type" />
|
|
||||||
<header name="Answer-State" />
|
|
||||||
<header name="Application" />
|
|
||||||
<header name="Application-Data" />
|
|
||||||
<header name="Application-Name" />
|
|
||||||
<header name="Application-Response" />
|
|
||||||
<header name="att_xfer_replaced_by" />
|
|
||||||
<header name="Auth-Method" />
|
|
||||||
<header name="Auth-Realm" />
|
|
||||||
<header name="Auth-User" />
|
|
||||||
<header name="Bridge-A-Unique-ID" />
|
|
||||||
<header name="Bridge-B-Unique-ID" />
|
|
||||||
<header name="Call-Direction" />
|
|
||||||
<header name="Caller-Callee-ID-Name" />
|
|
||||||
<header name="Caller-Callee-ID-Number" />
|
|
||||||
<header name="Caller-Caller-ID-Name" />
|
|
||||||
<header name="Caller-Caller-ID-Number" />
|
|
||||||
<header name="Caller-Context" />
|
|
||||||
<header name="Caller-Controls" />
|
|
||||||
<header name="Caller-Destination-Number" />
|
|
||||||
<header name="Caller-Dialplan" />
|
|
||||||
<header name="Caller-Network-Addr" />
|
|
||||||
<header name="Caller-Unique-ID" />
|
|
||||||
<header name="Call-ID" />
|
|
||||||
<header name="Channel-Call-State" />
|
|
||||||
<header name="Channel-Call-UUID" />
|
|
||||||
<header name="Channel-Presence-ID" />
|
|
||||||
<header name="Channel-State" />
|
|
||||||
<header name="Chat-Permissions" />
|
|
||||||
<header name="Conference-Name" />
|
|
||||||
<header name="Conference-Profile-Name" />
|
|
||||||
<header name="Conference-Unique-ID" />
|
|
||||||
<header name="Conference-Size" />
|
|
||||||
<header name="New-ID" />
|
|
||||||
<header name="Old-ID" />
|
|
||||||
<header name="Detected-Tone" />
|
|
||||||
<header name="dialog_state" />
|
|
||||||
<header name="direction" />
|
|
||||||
<header name="Distributed-From" />
|
|
||||||
<header name="DTMF-Digit" />
|
|
||||||
<header name="DTMF-Duration" />
|
|
||||||
<header name="Event-Date-Timestamp" />
|
|
||||||
<header name="Event-Name" />
|
|
||||||
<header name="Event-Subclass" />
|
|
||||||
<header name="Expires" />
|
|
||||||
<header name="Ext-SIP-IP" />
|
|
||||||
<header name="File" />
|
|
||||||
<header name="FreeSWITCH-Hostname" />
|
|
||||||
<header name="from" />
|
|
||||||
<header name="Hunt-Destination-Number" />
|
|
||||||
<header name="ip" />
|
|
||||||
<header name="Message-Account" />
|
|
||||||
<header name="metadata" />
|
|
||||||
<header name="old_node_channel_uuid" />
|
|
||||||
<header name="Other-Leg-Callee-ID-Name" />
|
|
||||||
<header name="Other-Leg-Callee-ID-Number" />
|
|
||||||
<header name="Other-Leg-Caller-ID-Name" />
|
|
||||||
<header name="Other-Leg-Caller-ID-Number" />
|
|
||||||
<header name="Other-Leg-Destination-Number" />
|
|
||||||
<header name="Other-Leg-Direction" />
|
|
||||||
<header name="Other-Leg-Unique-ID" />
|
|
||||||
<header name="Participant-Type" />
|
|
||||||
<header name="Path" />
|
|
||||||
<header name="profile_name" />
|
|
||||||
<header name="Profiles" />
|
|
||||||
<header name="proto-specific-event-name" />
|
|
||||||
<header name="Raw-Application-Data" />
|
|
||||||
<header name="Resigning-UUID" />
|
|
||||||
<header name="set" />
|
|
||||||
<header name="sip_auto_answer" />
|
|
||||||
<header name="sip_auth_method" />
|
|
||||||
<header name="sip_from_host" />
|
|
||||||
<header name="sip_from_user" />
|
|
||||||
<header name="sip_to_host" />
|
|
||||||
<header name="sip_to_user" />
|
|
||||||
<header name="sub-call-id" />
|
|
||||||
<header name="technology" />
|
|
||||||
<header name="to" />
|
|
||||||
<header name="Unique-ID" />
|
|
||||||
<header name="URL" />
|
|
||||||
<header name="variable_channel_is_moving" />
|
|
||||||
<header name="variable_collected_digits" />
|
|
||||||
<header name="variable_current_application" />
|
|
||||||
<header name="variable_current_application_data" />
|
|
||||||
<header name="variable_domain_name" />
|
|
||||||
<header name="variable_effective_caller_id_name" />
|
|
||||||
<header name="variable_effective_caller_id_number" />
|
|
||||||
<header name="variable_fax_bad_rows" />
|
|
||||||
<header name="variable_fax_document_total_pages" />
|
|
||||||
<header name="variable_fax_document_transferred_pages" />
|
|
||||||
<header name="variable_fax_ecm_used" />
|
|
||||||
<header name="variable_fax_result_code" />
|
|
||||||
<header name="variable_fax_result_text" />
|
|
||||||
<header name="variable_fax_success" />
|
|
||||||
<header name="variable_fax_transfer_rate" />
|
|
||||||
<header name="variable_holding_uuid" />
|
|
||||||
<header name="variable_hold_music" />
|
|
||||||
<header name="variable_media_group_id" />
|
|
||||||
<header name="variable_originate_disposition" />
|
|
||||||
<header name="variable_playback_terminator_used" />
|
|
||||||
<header name="variable_presence_id" />
|
|
||||||
<header name="variable_record_ms" />
|
|
||||||
<header name="variable_recovered" />
|
|
||||||
<header name="variable_silence_hits_exhausted" />
|
|
||||||
<header name="variable_sip_auth_realm" />
|
|
||||||
<header name="variable_sip_from_host" />
|
|
||||||
<header name="variable_sip_from_user" />
|
|
||||||
<header name="variable_sip_h_X-AUTH-IP" />
|
|
||||||
<header name="variable_sip_received_ip" />
|
|
||||||
<header name="variable_sip_to_host" />
|
|
||||||
<header name="variable_sip_to_user" />
|
|
||||||
<header name="variable_sofia_profile_name" />
|
|
||||||
<header name="variable_transfer_history" />
|
|
||||||
<header name="variable_user_name" />
|
|
||||||
<header name="variable_endpoint_disposition" />
|
|
||||||
<header name="variable_originate_disposition" />
|
|
||||||
<header name="variable_bridge_hangup_cause" />
|
|
||||||
<header name="variable_hangup_cause" />
|
|
||||||
<header name="variable_last_bridge_proto_specific_hangup_cause" />
|
|
||||||
<header name="variable_proto_specific_hangup_cause" />
|
|
||||||
<header name="VM-Call-ID" />
|
|
||||||
<header name="VM-sub-call-id" />
|
|
||||||
<header name="whistle_application_name" />
|
|
||||||
<header name="whistle_application_response" />
|
|
||||||
<header name="whistle_event_name" />
|
|
||||||
<header name="sip_auto_answer_notify" />
|
|
||||||
<header name="eavesdrop_group" />
|
|
||||||
<header name="origination_caller_id_name" />
|
|
||||||
<header name="origination_caller_id_number" />
|
|
||||||
<header name="origination_callee_id_name" />
|
|
||||||
<header name="origination_callee_id_number" />
|
|
||||||
<header name="sip_auth_username" />
|
|
||||||
<header name="sip_auth_password" />
|
|
||||||
<header name="effective_caller_id_name" />
|
|
||||||
<header name="effective_caller_id_number" />
|
|
||||||
<header name="effective_callee_id_name" />
|
|
||||||
<header name="effective_callee_id_number" />
|
|
||||||
|
|
||||||
<!-- Registrations -->
|
|
||||||
<header name="call-id" />
|
|
||||||
<header name="profile-name" />
|
|
||||||
<header name="from-user" />
|
|
||||||
<header name="from-host" />
|
|
||||||
<header name="presence-hosts" />
|
|
||||||
<header name="contact" />
|
|
||||||
<header name="rpid" />
|
|
||||||
<header name="status" />
|
|
||||||
<header name="expires" />
|
|
||||||
<header name="to-user" />
|
|
||||||
<header name="to-host" />
|
|
||||||
<header name="network-ip" />
|
|
||||||
<header name="network-port" />
|
|
||||||
<header name="username" />
|
|
||||||
<header name="realm" />
|
|
||||||
<header name="user-agent" />
|
|
||||||
|
|
||||||
<!-- CDR Headers -->
|
|
||||||
<header name="Hangup-Cause" />
|
|
||||||
<header name="Unique-ID" />
|
|
||||||
<header name="variable_switch_r_sdp" />
|
|
||||||
<header name="variable_sip_local_sdp_str" />
|
|
||||||
<header name="variable_sip_to_uri" />
|
|
||||||
<header name="variable_sip_from_uri" />
|
|
||||||
<header name="variable_effective_caller_id_number" />
|
|
||||||
<header name="Caller-Caller-ID-Number" />
|
|
||||||
<header name="variable_effective_caller_id_name" />
|
|
||||||
<header name="Caller-Caller-ID-Name" />
|
|
||||||
<header name="Caller-Callee-ID-Name" />
|
|
||||||
<header name="Caller-Callee-ID-Number" />
|
|
||||||
<header name="Other-Leg-Unique-ID" />
|
|
||||||
<header name="variable_sip_user_agent" />
|
|
||||||
<header name="variable_duration" />
|
|
||||||
<header name="variable_billsec" />
|
|
||||||
<header name="variable_progresssec" />
|
|
||||||
<header name="variable_progress_uepoch" />
|
|
||||||
<header name="variable_progress_media_uepoch" />
|
|
||||||
<header name="variable_start_uepoch" />
|
|
||||||
<header name="variable_digits_dialed" />
|
|
||||||
<header name="variable_sip_cid_type" />
|
|
||||||
|
|
||||||
<!-- Conference Headers -->
|
|
||||||
<header name="Hear" />
|
|
||||||
<header name="Speak" />
|
|
||||||
<header name="Video" />
|
|
||||||
<header name="Talking" />
|
|
||||||
<header name="Mute-Detect" />
|
|
||||||
<header name="Member-ID" />
|
|
||||||
<header name="Member-Type" />
|
|
||||||
<header name="Energy-Level" />
|
|
||||||
<header name="Current-Energy" />
|
|
||||||
<header name="Floor" />
|
|
||||||
|
|
||||||
</event-filter>
|
|
||||||
</configuration>
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,11 +9,11 @@
|
||||||
|
|
||||||
Before you start to modify this default please visit this wiki page:
|
Before you start to modify this default please visit this wiki page:
|
||||||
|
|
||||||
http://wiki.freeswitch.org/wiki/Getting_Started_Guide#Some_stuff_to_try_out.21
|
https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Configuration/Default-Configuration_6587388/#6-configuration-files
|
||||||
|
|
||||||
If all else fails you can read our FAQ located at:
|
If all else fails you can read our FAQ located at:
|
||||||
|
|
||||||
http://wiki.freeswitch.org/wiki/FreeSwitch_FAQ
|
https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Miscellaneous/FAQ/
|
||||||
|
|
||||||
NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
|
NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
|
||||||
-->
|
-->
|
||||||
|
|
59
configure.ac
59
configure.ac
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
# Must change all of the below together
|
# Must change all of the below together
|
||||||
# For a release, set revision for that tagged release as well and uncomment
|
# For a release, set revision for that tagged release as well and uncomment
|
||||||
AC_INIT([freeswitch], [1.10.10-dev], bugs@freeswitch.org)
|
AC_INIT([freeswitch], [1.10.12-dev], bugs@freeswitch.org)
|
||||||
AC_SUBST(SWITCH_VERSION_MAJOR, [1])
|
AC_SUBST(SWITCH_VERSION_MAJOR, [1])
|
||||||
AC_SUBST(SWITCH_VERSION_MINOR, [10])
|
AC_SUBST(SWITCH_VERSION_MINOR, [10])
|
||||||
AC_SUBST(SWITCH_VERSION_MICRO, [10-dev])
|
AC_SUBST(SWITCH_VERSION_MICRO, [12-dev])
|
||||||
AC_SUBST(SWITCH_VERSION_REVISION, [])
|
AC_SUBST(SWITCH_VERSION_REVISION, [])
|
||||||
AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, [])
|
AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, [])
|
||||||
|
|
||||||
|
@ -582,7 +582,7 @@ AC_SUBST(SYS_XMLRPC_CFLAGS)
|
||||||
AC_SUBST(SYS_XMLRPC_LDFLAGS)
|
AC_SUBST(SYS_XMLRPC_LDFLAGS)
|
||||||
AM_CONDITIONAL([SYSTEM_XMLRPCC],[test "${enable_xmlrpcc}" = "yes"])
|
AM_CONDITIONAL([SYSTEM_XMLRPCC],[test "${enable_xmlrpcc}" = "yes"])
|
||||||
|
|
||||||
for luaversion in luajit lua5.2 lua-5.2 lua52 lua5.1 lua-5.1 lua; do
|
for luaversion in luajit lua5.3 lua-5.3 lua53 lua5.2 lua-5.2 lua52 lua5.1 lua-5.1 lua; do
|
||||||
PKG_CHECK_MODULES([LUA],[${luaversion}],[have_lua=yes],[have_lua=no])
|
PKG_CHECK_MODULES([LUA],[${luaversion}],[have_lua=yes],[have_lua=no])
|
||||||
if test ${have_lua} = yes; then
|
if test ${have_lua} = yes; then
|
||||||
break
|
break
|
||||||
|
@ -716,7 +716,7 @@ PKG_CHECK_MODULES([SPANDSP], [spandsp >= 3.0],[
|
||||||
AC_MSG_ERROR([no usable spandsp; please install spandsp3 devel package or equivalent])
|
AC_MSG_ERROR([no usable spandsp; please install spandsp3 devel package or equivalent])
|
||||||
])
|
])
|
||||||
|
|
||||||
PKG_CHECK_MODULES([SOFIA_SIP], [sofia-sip-ua >= 1.13.14],[
|
PKG_CHECK_MODULES([SOFIA_SIP], [sofia-sip-ua >= 1.13.17],[
|
||||||
AM_CONDITIONAL([HAVE_SOFIA_SIP],[true])],[
|
AM_CONDITIONAL([HAVE_SOFIA_SIP],[true])],[
|
||||||
AC_MSG_ERROR([no usable sofia-sip; please install sofia-sip-ua devel package or equivalent])
|
AC_MSG_ERROR([no usable sofia-sip; please install sofia-sip-ua devel package or equivalent])
|
||||||
])
|
])
|
||||||
|
@ -1352,7 +1352,21 @@ PKG_CHECK_MODULES([MPG123], [libmpg123 >= 1.16.0],[
|
||||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_MPG123],[false])])
|
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_MPG123],[false])])
|
||||||
|
|
||||||
PKG_CHECK_MODULES([SHOUT], [shout >= 2.2.2],[
|
PKG_CHECK_MODULES([SHOUT], [shout >= 2.2.2],[
|
||||||
AM_CONDITIONAL([HAVE_SHOUT],[true])],[
|
AM_CONDITIONAL([HAVE_SHOUT],[true])
|
||||||
|
SHOUT_VERSION="`$PKG_CONFIG --modversion shout`"
|
||||||
|
SHOUT_MAJOR_VERSION="`echo $SHOUT_VERSION | cut -d. -f1`"
|
||||||
|
SHOUT_MINOR_VERSION="`echo $SHOUT_VERSION | cut -d. -f2`"
|
||||||
|
SHOUT_PATCH_VERSION="`echo $SHOUT_VERSION | cut -d. -f3`"
|
||||||
|
test -n "$SHOUT_PATCH_VERSION" || SHOUT_PATCH_VERSION=0
|
||||||
|
AC_MSG_NOTICE([SHOUT version: $SHOUT_VERSION])
|
||||||
|
AC_MSG_NOTICE([SHOUT major version: $SHOUT_MAJOR_VERSION])
|
||||||
|
AC_MSG_NOTICE([SHOUT minor version: $SHOUT_MINOR_VERSION])
|
||||||
|
AC_MSG_NOTICE([SHOUT patch version: $SHOUT_PATCH_VERSION])
|
||||||
|
AC_SUBST([SHOUT_VERSION])
|
||||||
|
AC_SUBST([SHOUT_MAJOR_VERSION])
|
||||||
|
AC_SUBST([SHOUT_MINOR_VERSION])
|
||||||
|
AC_SUBST([SHOUT_PATCH_VERSION])
|
||||||
|
],[
|
||||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_SHOUT],[false])])
|
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_SHOUT],[false])])
|
||||||
|
|
||||||
mp3lame=false
|
mp3lame=false
|
||||||
|
@ -1518,26 +1532,32 @@ PKG_CHECK_MODULES([V8FS_STATIC], [v8-6.1_static >= 6.1.298],[
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
PKG_CHECK_MODULES([KS], [libks >= 1.8.2],[
|
PKG_CHECK_MODULES([KS], [libks2 >= 2.0.0],[
|
||||||
AM_CONDITIONAL([HAVE_KS],[true])],[
|
AM_CONDITIONAL([HAVE_KS],[true])],[
|
||||||
if module_enabled mod_verto; then
|
PKG_CHECK_MODULES([KS], [libks >= 1.8.2],[
|
||||||
AC_MSG_ERROR([You need to either install libks or disable mod_verto in modules.conf])
|
AM_CONDITIONAL([HAVE_KS],[true])],[
|
||||||
else
|
if module_enabled mod_verto; then
|
||||||
if module_enabled mod_signalwire; then
|
AC_MSG_ERROR([You need to either install libks2 or libks or disable mod_verto in modules.conf])
|
||||||
AC_MSG_ERROR([You need to either install libks or disable mod_signalwire in modules.conf])
|
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_KS],[false])
|
if module_enabled mod_signalwire; then
|
||||||
|
AC_MSG_ERROR([You need to either install libks2 or libks or disable mod_signalwire in modules.conf])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_KS],[false])
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
PKG_CHECK_MODULES([SIGNALWIRE_CLIENT], [signalwire_client >= 1.0.0],[
|
PKG_CHECK_MODULES([SIGNALWIRE_CLIENT], [signalwire_client2 >= 2.0.0],[
|
||||||
AM_CONDITIONAL([HAVE_SIGNALWIRE_CLIENT],[true])],[
|
AM_CONDITIONAL([HAVE_SIGNALWIRE_CLIENT],[true])],[
|
||||||
if module_enabled mod_signalwire; then
|
PKG_CHECK_MODULES([SIGNALWIRE_CLIENT], [signalwire_client >= 1.0.0],[
|
||||||
AC_MSG_ERROR([You need to either install signalwire-client-c or disable mod_signalwire in modules.conf])
|
AM_CONDITIONAL([HAVE_SIGNALWIRE_CLIENT],[true])],[
|
||||||
else
|
if module_enabled mod_signalwire; then
|
||||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_SIGNALWIRE_CLIENT],[false])
|
AC_MSG_ERROR([You need to either install signalwire-client-c2 or signalwire-client-c or disable mod_signalwire in modules.conf])
|
||||||
fi
|
else
|
||||||
|
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_SIGNALWIRE_CLIENT],[false])
|
||||||
|
fi
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
PKG_CHECK_MODULES([AMQP], [librabbitmq >= 0.5.2],[
|
PKG_CHECK_MODULES([AMQP], [librabbitmq >= 0.5.2],[
|
||||||
|
@ -2188,7 +2208,6 @@ AC_CONFIG_FILES([Makefile
|
||||||
src/mod/event_handlers/mod_fail2ban/Makefile
|
src/mod/event_handlers/mod_fail2ban/Makefile
|
||||||
src/mod/event_handlers/mod_format_cdr/Makefile
|
src/mod/event_handlers/mod_format_cdr/Makefile
|
||||||
src/mod/event_handlers/mod_json_cdr/Makefile
|
src/mod/event_handlers/mod_json_cdr/Makefile
|
||||||
src/mod/event_handlers/mod_kazoo/Makefile
|
|
||||||
src/mod/event_handlers/mod_radius_cdr/Makefile
|
src/mod/event_handlers/mod_radius_cdr/Makefile
|
||||||
src/mod/event_handlers/mod_odbc_cdr/Makefile
|
src/mod/event_handlers/mod_odbc_cdr/Makefile
|
||||||
src/mod/event_handlers/mod_rayo/Makefile
|
src/mod/event_handlers/mod_rayo/Makefile
|
||||||
|
|
|
@ -29,7 +29,7 @@ conf_dir="../conf"
|
||||||
lang_dir="../conf/vanilla/lang"
|
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."
|
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="."
|
mod_build_depends="." mod_depends="." mod_recommends="." mod_suggests="."
|
||||||
supported_debian_distros="wheezy jessie stretch buster bullseye sid"
|
supported_debian_distros="wheezy jessie stretch buster bullseye bookworm sid"
|
||||||
supported_ubuntu_distros="trusty utopic xenial"
|
supported_ubuntu_distros="trusty utopic xenial"
|
||||||
supported_distros="$supported_debian_distros $supported_ubuntu_distros"
|
supported_distros="$supported_debian_distros $supported_ubuntu_distros"
|
||||||
avoid_mods=(
|
avoid_mods=(
|
||||||
|
@ -71,6 +71,9 @@ avoid_mods_sid=(
|
||||||
avoid_mods_jessie=(
|
avoid_mods_jessie=(
|
||||||
directories/mod_ldap
|
directories/mod_ldap
|
||||||
)
|
)
|
||||||
|
avoid_mods_bookworm=(
|
||||||
|
languages/mod_python
|
||||||
|
)
|
||||||
avoid_mods_wheezy=(
|
avoid_mods_wheezy=(
|
||||||
event_handlers/mod_amqp
|
event_handlers/mod_amqp
|
||||||
languages/mod_java
|
languages/mod_java
|
||||||
|
@ -325,14 +328,14 @@ Build-Depends:
|
||||||
# configure options
|
# configure options
|
||||||
libssl1.0-dev | libssl-dev, unixodbc-dev, libpq-dev,
|
libssl1.0-dev | libssl-dev, unixodbc-dev, libpq-dev,
|
||||||
libncurses5-dev, libjpeg62-turbo-dev | libjpeg-turbo8-dev | libjpeg62-dev | libjpeg8-dev,
|
libncurses5-dev, libjpeg62-turbo-dev | libjpeg-turbo8-dev | libjpeg62-dev | libjpeg8-dev,
|
||||||
python-dev | python-dev-is-python2, python3-dev, python-all-dev, python-support (>= 0.90) | dh-python, erlang-dev, libtpl-dev (>= 1.5),
|
python-dev | python-dev-is-python2 | python-dev-is-python3, python3-dev, python-all-dev | python3-all-dev, python-support (>= 0.90) | dh-python, erlang-dev, libtpl-dev (>= 1.5),
|
||||||
# documentation
|
# documentation
|
||||||
doxygen,
|
doxygen,
|
||||||
# for APR (not essential for build)
|
# for APR (not essential for build)
|
||||||
uuid-dev, libexpat1-dev, libgdbm-dev, libdb-dev,
|
uuid-dev, libexpat1-dev, libgdbm-dev, libdb-dev,
|
||||||
# used by many modules
|
# used by many modules
|
||||||
libcurl4-openssl-dev | libcurl4-gnutls-dev | libcurl-dev,
|
libcurl4-openssl-dev | libcurl4-gnutls-dev | libcurl-dev,
|
||||||
bison, zlib1g-dev, libsofia-sip-ua-dev (>= 1.13.14),
|
bison, zlib1g-dev, libsofia-sip-ua-dev (>= 1.13.17),
|
||||||
libspandsp3-dev,
|
libspandsp3-dev,
|
||||||
# used to format the private freeswitch apt-repo key properly
|
# used to format the private freeswitch apt-repo key properly
|
||||||
gnupg,
|
gnupg,
|
||||||
|
@ -371,7 +374,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch
|
||||||
|
|
||||||
Package: libfreeswitch1
|
Package: libfreeswitch1
|
||||||
Architecture: amd64 armhf
|
Architecture: amd64 armhf
|
||||||
Depends: \${shlibs:Depends}, \${misc:Depends}, libsofia-sip-ua0 (>= 1.13.14)
|
Depends: \${shlibs:Depends}, \${misc:Depends}, libsofia-sip-ua0 (>= 1.13.17)
|
||||||
Recommends:
|
Recommends:
|
||||||
Suggests: libfreeswitch1-dbg
|
Suggests: libfreeswitch1-dbg
|
||||||
Conflicts: freeswitch-all (<= 1.6.7)
|
Conflicts: freeswitch-all (<= 1.6.7)
|
||||||
|
@ -670,7 +673,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
|
||||||
freeswitch-mod-event-multicast (= \${binary:Version}),
|
freeswitch-mod-event-multicast (= \${binary:Version}),
|
||||||
freeswitch-mod-event-socket (= \${binary:Version}),
|
freeswitch-mod-event-socket (= \${binary:Version}),
|
||||||
freeswitch-mod-json-cdr (= \${binary:Version}),
|
freeswitch-mod-json-cdr (= \${binary:Version}),
|
||||||
freeswitch-mod-kazoo (= \${binary:Version}),
|
|
||||||
freeswitch-mod-snmp (= \${binary:Version}),
|
freeswitch-mod-snmp (= \${binary:Version}),
|
||||||
freeswitch-mod-local-stream (= \${binary:Version}),
|
freeswitch-mod-local-stream (= \${binary:Version}),
|
||||||
freeswitch-mod-native-file (= \${binary:Version}),
|
freeswitch-mod-native-file (= \${binary:Version}),
|
||||||
|
@ -907,7 +909,6 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
|
||||||
freeswitch-mod-event-multicast-dbg (= \${binary:Version}),
|
freeswitch-mod-event-multicast-dbg (= \${binary:Version}),
|
||||||
freeswitch-mod-event-socket-dbg (= \${binary:Version}),
|
freeswitch-mod-event-socket-dbg (= \${binary:Version}),
|
||||||
freeswitch-mod-json-cdr-dbg (= \${binary:Version}),
|
freeswitch-mod-json-cdr-dbg (= \${binary:Version}),
|
||||||
freeswitch-mod-kazoo-dbg (= \${binary:Version}),
|
|
||||||
freeswitch-mod-snmp-dbg (= \${binary:Version}),
|
freeswitch-mod-snmp-dbg (= \${binary:Version}),
|
||||||
freeswitch-mod-local-stream-dbg (= \${binary:Version}),
|
freeswitch-mod-local-stream-dbg (= \${binary:Version}),
|
||||||
freeswitch-mod-native-file-dbg (= \${binary:Version}),
|
freeswitch-mod-native-file-dbg (= \${binary:Version}),
|
||||||
|
|
|
@ -12,6 +12,7 @@ Module: applications/mod_av
|
||||||
Description: mod_av
|
Description: mod_av
|
||||||
Adds mod_av.
|
Adds mod_av.
|
||||||
Build-Depends: libavformat-dev, libswscale-dev, libavresample-dev
|
Build-Depends: libavformat-dev, libswscale-dev, libavresample-dev
|
||||||
|
Build-Depends-Bookworm: libavformat-dev, libswscale-dev, libswresample-dev
|
||||||
|
|
||||||
Module: applications/mod_avmd
|
Module: applications/mod_avmd
|
||||||
Description: Advanced voicemail detection
|
Description: Advanced voicemail detection
|
||||||
|
@ -209,7 +210,7 @@ Description: Adds mod_skel
|
||||||
Module: applications/mod_signalwire
|
Module: applications/mod_signalwire
|
||||||
Description: mod_signalwire
|
Description: mod_signalwire
|
||||||
Adds mod_signalwire.
|
Adds mod_signalwire.
|
||||||
Build-Depends: libks, signalwire-client-c
|
Build-Depends: libks2, signalwire-client-c2
|
||||||
|
|
||||||
Module: applications/mod_sms
|
Module: applications/mod_sms
|
||||||
Description: Astract SMS
|
Description: Astract SMS
|
||||||
|
@ -485,6 +486,7 @@ Description: Adds mod_verto.
|
||||||
Build-Depends: libperl-dev
|
Build-Depends: libperl-dev
|
||||||
Build-Depends-Buster: libperl-dev, libgdbm-compat-dev
|
Build-Depends-Buster: libperl-dev, libgdbm-compat-dev
|
||||||
Build-Depends-Bullseye: libperl-dev, libgdbm-compat-dev
|
Build-Depends-Bullseye: libperl-dev, libgdbm-compat-dev
|
||||||
|
Build-Depends-Bookworm: libperl-dev, libgdbm-compat-dev
|
||||||
|
|
||||||
## mod/event_handlers
|
## mod/event_handlers
|
||||||
|
|
||||||
|
@ -540,12 +542,6 @@ Module: event_handlers/mod_json_cdr
|
||||||
Description: mod_json_cdr
|
Description: mod_json_cdr
|
||||||
Adds mod_json_cdr.
|
Adds mod_json_cdr.
|
||||||
|
|
||||||
Module: event_handlers/mod_kazoo
|
|
||||||
Description: mod_kazoo
|
|
||||||
Adds mod_kazoo.
|
|
||||||
Build-Depends: erlang-dev
|
|
||||||
Depends: erlang
|
|
||||||
|
|
||||||
Module: event_handlers/mod_odbc_cdr
|
Module: event_handlers/mod_odbc_cdr
|
||||||
Description: mod_odbc_cdr
|
Description: mod_odbc_cdr
|
||||||
Adds mod_odbc_cdr.
|
Adds mod_odbc_cdr.
|
||||||
|
@ -647,6 +643,7 @@ Module: languages/mod_lua
|
||||||
Description: mod_lua
|
Description: mod_lua
|
||||||
Adds mod_lua.
|
Adds mod_lua.
|
||||||
Build-Depends: liblua5.2-dev | liblua5.1-dev
|
Build-Depends: liblua5.2-dev | liblua5.1-dev
|
||||||
|
Build-Depends-Bookworm: liblua5.3-dev | liblua5.2-dev | liblua5.1-dev
|
||||||
|
|
||||||
Module: languages/mod_managed
|
Module: languages/mod_managed
|
||||||
Description: mod_managed
|
Description: mod_managed
|
||||||
|
@ -659,6 +656,7 @@ Description: mod_perl
|
||||||
Build-Depends: libperl-dev
|
Build-Depends: libperl-dev
|
||||||
Build-Depends-Buster: libperl-dev, libgdbm-compat-dev
|
Build-Depends-Buster: libperl-dev, libgdbm-compat-dev
|
||||||
Build-Depends-Bullseye: libperl-dev, libgdbm-compat-dev
|
Build-Depends-Bullseye: libperl-dev, libgdbm-compat-dev
|
||||||
|
Build-Depends-Bookworm: libperl-dev, libgdbm-compat-dev
|
||||||
|
|
||||||
Module: languages/mod_python
|
Module: languages/mod_python
|
||||||
Description: mod_python
|
Description: mod_python
|
||||||
|
@ -669,6 +667,7 @@ Module: languages/mod_python3
|
||||||
Description: mod_python3
|
Description: mod_python3
|
||||||
Adds mod_python3.
|
Adds mod_python3.
|
||||||
Build-Depends: python3-dev
|
Build-Depends: python3-dev
|
||||||
|
Build-Depends-Bookworm: python3-dev, python3-setuptools
|
||||||
|
|
||||||
Module: languages/mod_v8
|
Module: languages/mod_v8
|
||||||
Description: mod_v8
|
Description: mod_v8
|
||||||
|
|
|
@ -46,6 +46,7 @@ find_distro () {
|
||||||
case "$1" in
|
case "$1" in
|
||||||
experimental) echo "sid";;
|
experimental) echo "sid";;
|
||||||
unstable) echo "sid";;
|
unstable) echo "sid";;
|
||||||
|
experimental) echo "bookworm";;
|
||||||
testing) echo "bullseye";;
|
testing) echo "bullseye";;
|
||||||
stable) echo "buster";;
|
stable) echo "buster";;
|
||||||
oldstable) echo "stretch";;
|
oldstable) echo "stretch";;
|
||||||
|
@ -56,6 +57,7 @@ find_distro () {
|
||||||
find_suite () {
|
find_suite () {
|
||||||
case "$1" in
|
case "$1" in
|
||||||
sid) echo "unstable";;
|
sid) echo "unstable";;
|
||||||
|
bookworm) echo "experimental";;
|
||||||
bullseye) echo "testing";;
|
bullseye) echo "testing";;
|
||||||
buster) echo "stable";;
|
buster) echo "stable";;
|
||||||
stretch) echo "oldstable";;
|
stretch) echo "oldstable";;
|
||||||
|
@ -133,50 +135,94 @@ get_nightly_revision_human () {
|
||||||
echo "git $(git rev-list -n1 --abbrev=7 --abbrev-commit HEAD) $(date -u '+%Y-%m-%d %H:%M:%SZ')"
|
echo "git $(git rev-list -n1 --abbrev=7 --abbrev-commit HEAD) $(date -u '+%Y-%m-%d %H:%M:%SZ')"
|
||||||
}
|
}
|
||||||
|
|
||||||
create_orig () {
|
prep_create_orig () {
|
||||||
{
|
{
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
local OPTIND OPTARG
|
local OPTIND OPTARG
|
||||||
local uver="" hrev="" bundle_deps=true modules_list="" zl=9e
|
local uver="" hrev="" bundle_deps=true
|
||||||
|
|
||||||
while getopts 'bm:nv:z:' o "$@"; do
|
while getopts 'bm:nv:z:' o "$@"; do
|
||||||
case "$o" in
|
case "$o" in
|
||||||
m) modules_list="$OPTARG";;
|
b) ;;
|
||||||
|
m) ;;
|
||||||
n) uver="nightly";;
|
n) uver="nightly";;
|
||||||
v) uver="$OPTARG";;
|
v) uver="$OPTARG";;
|
||||||
z) zl="$OPTARG";;
|
z) ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
shift $(($OPTIND-1))
|
shift $(($OPTIND-1))
|
||||||
|
|
||||||
if [ -z "$uver" ] || [ "$uver" = "nightly" ]; then
|
if [ -z "$uver" ] || [ "$uver" = "nightly" ]; then
|
||||||
uver="$(get_nightly_version)"
|
uver="$(get_nightly_version)"
|
||||||
hrev="$(get_nightly_revision_human)"
|
hrev="$(get_nightly_revision_human)"
|
||||||
fi
|
fi
|
||||||
local treeish="$1" dver="$(mk_dver "$uver")"
|
|
||||||
local orig="../freeswitch_$dver~$(lsb_release -sc).orig.tar.xz"
|
local treeish="$1"
|
||||||
[ -n "$treeish" ] || treeish="HEAD"
|
[ -n "$treeish" ] || treeish="HEAD"
|
||||||
|
|
||||||
check_repo_clean
|
check_repo_clean
|
||||||
git reset --hard "$treeish"
|
git reset --hard "$treeish"
|
||||||
|
|
||||||
|
if $bundle_deps; then
|
||||||
|
(cd libs && getlibs)
|
||||||
|
fi
|
||||||
|
|
||||||
|
./build/set-fs-version.sh "$uver" "$hrev" # ToDo: Handle empty $hrev
|
||||||
|
|
||||||
|
echo "$uver" > .version
|
||||||
|
} 1>&2
|
||||||
|
echo "$uver"
|
||||||
|
}
|
||||||
|
|
||||||
|
create_orig () {
|
||||||
|
{
|
||||||
|
set -e
|
||||||
|
|
||||||
|
local OPTIND OPTARG
|
||||||
|
local bundle_deps=true modules_list="" zl=9e
|
||||||
|
|
||||||
|
local uver="$(prep_create_orig "$@")"
|
||||||
|
|
||||||
|
while getopts 'bm:nv:z:' o "$@"; do
|
||||||
|
case "$o" in
|
||||||
|
b) ;;
|
||||||
|
m) modules_list="$OPTARG";;
|
||||||
|
n) ;;
|
||||||
|
v) ;;
|
||||||
|
z) zl="$OPTARG";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $(($OPTIND-1))
|
||||||
|
|
||||||
|
local dver="$(mk_dver "$uver")"
|
||||||
|
local orig="../freeswitch_$dver~$(lsb_release -sc).orig.tar.xz"
|
||||||
|
|
||||||
mv .gitattributes .gitattributes.orig
|
mv .gitattributes .gitattributes.orig
|
||||||
|
|
||||||
local -a args=(-e '\bdebian-ignore\b')
|
local -a args=(-e '\bdebian-ignore\b')
|
||||||
test "$modules_list" = "non-dfsg" || args+=(-e '\bdfsg-nonfree\b')
|
test "$modules_list" = "non-dfsg" || args+=(-e '\bdfsg-nonfree\b')
|
||||||
grep .gitattributes.orig "${args[@]}" \
|
grep .gitattributes.orig "${args[@]}" \
|
||||||
| while xread l; do
|
| while xread l; do
|
||||||
echo "$l export-ignore" >> .gitattributes
|
echo "$l export-ignore" >> .gitattributes
|
||||||
done
|
done
|
||||||
|
|
||||||
if $bundle_deps; then
|
if $bundle_deps; then
|
||||||
(cd libs && getlibs)
|
|
||||||
git add -f libs
|
git add -f libs
|
||||||
fi
|
fi
|
||||||
./build/set-fs-version.sh "$uver" "$hrev" && git add configure.ac
|
|
||||||
echo "$uver" > .version && git add -f .version
|
git add -f configure.ac .version
|
||||||
git commit --allow-empty -m "nightly v$uver"
|
git commit --allow-empty -m "nightly v$uver"
|
||||||
|
|
||||||
git archive -v \
|
git archive -v \
|
||||||
--worktree-attributes \
|
--worktree-attributes \
|
||||||
--format=tar \
|
--format=tar \
|
||||||
--prefix=freeswitch-$uver/ \
|
--prefix=freeswitch-$uver/ \
|
||||||
HEAD \
|
HEAD \
|
||||||
| xz -c -${zl}v > $orig
|
| xz -c -${zl}v > $orig
|
||||||
|
|
||||||
mv .gitattributes.orig .gitattributes
|
mv .gitattributes.orig .gitattributes
|
||||||
|
|
||||||
git reset --hard HEAD^ && git clean -fdx
|
git reset --hard HEAD^ && git clean -fdx
|
||||||
} 1>&2
|
} 1>&2
|
||||||
echo $orig
|
echo $orig
|
||||||
|
@ -188,11 +234,12 @@ applications/mod_commands
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
create_dsc () {
|
prep_create_dsc () {
|
||||||
{
|
{
|
||||||
set -e
|
set -e
|
||||||
local OPTIND OPTARG modules_conf="" modules_list="" speed="normal" suite_postfix="" suite_postfix_p=false zl=9
|
|
||||||
local modules_add=""
|
local OPTIND OPTARG modules_conf="" modules_add="" modules_list="" speed="normal"
|
||||||
|
|
||||||
while getopts 'a:f:m:p:s:u:z:' o "$@"; do
|
while getopts 'a:f:m:p:s:u:z:' o "$@"; do
|
||||||
case "$o" in
|
case "$o" in
|
||||||
a) avoid_mods_arch="$OPTARG";;
|
a) avoid_mods_arch="$OPTARG";;
|
||||||
|
@ -200,46 +247,87 @@ create_dsc () {
|
||||||
m) modules_list="$OPTARG";;
|
m) modules_list="$OPTARG";;
|
||||||
p) modules_add="$modules_add $OPTARG";;
|
p) modules_add="$modules_add $OPTARG";;
|
||||||
s) speed="$OPTARG";;
|
s) speed="$OPTARG";;
|
||||||
u) suite_postfix="$OPTARG"; suite_postfix_p=true;;
|
u) ;;
|
||||||
z) zl="$OPTARG";;
|
z) ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
shift $(($OPTIND-1))
|
shift $(($OPTIND-1))
|
||||||
local distro="$(find_distro $1)" orig="$2"
|
|
||||||
local suite="$(find_suite $distro)"
|
local distro="$(find_distro $1)"
|
||||||
local orig_ver="$(echo "$orig" | sed -e 's/^.*_//' -e 's/\.orig\.tar.*$//')"
|
|
||||||
local dver="${orig_ver}-1~${distro}+1"
|
|
||||||
$suite_postfix_p && { suite="${distro}${suite_postfix}"; }
|
|
||||||
[ -x "$(which dch)" ] \
|
|
||||||
|| err "package devscripts isn't installed"
|
|
||||||
if [ -n "$modules_conf" ]; then
|
if [ -n "$modules_conf" ]; then
|
||||||
cp $modules_conf debian/modules.conf
|
cp $modules_conf debian/modules.conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local bootstrap_args=""
|
local bootstrap_args=""
|
||||||
|
|
||||||
if [ -n "$modules_list" ]; then
|
if [ -n "$modules_list" ]; then
|
||||||
if [ "$modules_list" = "non-dfsg" ]; then
|
if [ "$modules_list" = "non-dfsg" ]; then
|
||||||
bootstrap_args="-mnon-dfsg"
|
bootstrap_args="-mnon-dfsg"
|
||||||
else set_modules_${modules_list}; fi
|
else
|
||||||
|
set_modules_${modules_list}
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -n "$modules_add"; then
|
if test -n "$modules_add"; then
|
||||||
for x in $modules_add; do
|
for x in $modules_add; do
|
||||||
bootstrap_args="$bootstrap_args -p${x}"
|
bootstrap_args="$bootstrap_args -p${x}"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
(cd debian && ./bootstrap.sh -a "$avoid_mods_arch" -c $distro $bootstrap_args)
|
(cd debian && ./bootstrap.sh -a "$avoid_mods_arch" -c $distro $bootstrap_args)
|
||||||
|
|
||||||
case "$speed" in
|
case "$speed" in
|
||||||
paranoid) sed -i ./debian/rules \
|
paranoid) sed -i ./debian/rules \
|
||||||
-e '/\.stamp-bootstrap:/{:l2 n; /\.\/bootstrap.sh -j/{s/ -j//; :l3 n; b l3}; b l2};' ;;
|
-e '/\.stamp-bootstrap:/{:l2 n; /\.\/bootstrap.sh -j/{s/ -j//; :l3 n; b l3}; b l2};' ;;
|
||||||
reckless) sed -i ./debian/rules \
|
reckless) sed -i ./debian/rules \
|
||||||
-e '/\.stamp-build:/{:l2 n; /make/{s/$/ -j/; :l3 n; b l3}; b l2};' ;;
|
-e '/\.stamp-build:/{:l2 n; /make/{s/$/ -j/; :l3 n; b l3}; b l2};' ;;
|
||||||
esac
|
esac
|
||||||
|
} 1>&2
|
||||||
|
}
|
||||||
|
|
||||||
|
create_dsc () {
|
||||||
|
{
|
||||||
|
set -e
|
||||||
|
|
||||||
|
prep_create_dsc "$@"
|
||||||
|
|
||||||
|
local OPTIND OPTARG suite_postfix="" suite_postfix_p=false zl=9
|
||||||
|
|
||||||
|
while getopts 'a:f:m:p:s:u:z:' o "$@"; do
|
||||||
|
case "$o" in
|
||||||
|
a) ;;
|
||||||
|
f) ;;
|
||||||
|
m) ;;
|
||||||
|
p) ;;
|
||||||
|
s) ;;
|
||||||
|
u) suite_postfix="$OPTARG"; suite_postfix_p=true;;
|
||||||
|
z) zl="$OPTARG";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $(($OPTIND-1))
|
||||||
|
|
||||||
|
local distro="$(find_distro $1)" orig="$2"
|
||||||
|
local suite="$(find_suite $distro)"
|
||||||
|
local orig_ver="$(echo "$orig" | sed -e 's/^.*_//' -e 's/\.orig\.tar.*$//')"
|
||||||
|
local dver="${orig_ver}-1~${distro}+1"
|
||||||
|
|
||||||
|
$suite_postfix_p && { suite="${distro}${suite_postfix}"; }
|
||||||
|
|
||||||
|
[ -x "$(which dch)" ] \
|
||||||
|
|| err "package devscripts isn't installed"
|
||||||
|
|
||||||
[ "$zl" -ge "1" ] || zl=1
|
[ "$zl" -ge "1" ] || zl=1
|
||||||
git add debian/rules
|
|
||||||
dch -b -m -v "$dver" --force-distribution -D "$suite" "Nightly build."
|
dch -b -m -v "$dver" --force-distribution -D "$suite" "Nightly build."
|
||||||
git add debian/changelog && git commit -m "nightly v$orig_ver"
|
|
||||||
|
git add debian/rules debian/changelog && git commit -m "nightly v$orig_ver"
|
||||||
|
|
||||||
dpkg-source -i.* -Zxz -z${zl} -b .
|
dpkg-source -i.* -Zxz -z${zl} -b .
|
||||||
dpkg-genchanges -S > ../$(dsc_base)_source.changes
|
dpkg-genchanges -S > ../$(dsc_base)_source.changes
|
||||||
|
|
||||||
local dsc="../$(dsc_base).dsc"
|
local dsc="../$(dsc_base).dsc"
|
||||||
|
|
||||||
git reset --hard HEAD^ && git clean -fdx
|
git reset --hard HEAD^ && git clean -fdx
|
||||||
} 1>&2
|
} 1>&2
|
||||||
echo $dsc
|
echo $dsc
|
||||||
|
@ -586,7 +674,7 @@ commands:
|
||||||
|
|
||||||
create-dbg-pkgs
|
create-dbg-pkgs
|
||||||
|
|
||||||
create-dsc <distro> <orig-file>
|
create-dsc <distro> <orig-file> (same for 'prep-create-dsc')
|
||||||
|
|
||||||
-f <modules.conf>
|
-f <modules.conf>
|
||||||
Build only modules listed in this file
|
Build only modules listed in this file
|
||||||
|
@ -600,7 +688,7 @@ commands:
|
||||||
Specify a custom suite postfix
|
Specify a custom suite postfix
|
||||||
-z Set compression level
|
-z Set compression level
|
||||||
|
|
||||||
create-orig <treeish>
|
create-orig <treeish> (same for 'prep_create_orig')
|
||||||
|
|
||||||
-m [ quicktest | non-dfsg ]
|
-m [ quicktest | non-dfsg ]
|
||||||
Choose custom list of modules to build
|
Choose custom list of modules to build
|
||||||
|
@ -627,7 +715,9 @@ case "$cmd" in
|
||||||
build-all) build_all "$@" ;;
|
build-all) build_all "$@" ;;
|
||||||
build-debs) build_debs "$@" ;;
|
build-debs) build_debs "$@" ;;
|
||||||
create-dbg-pkgs) create_dbg_pkgs ;;
|
create-dbg-pkgs) create_dbg_pkgs ;;
|
||||||
|
prep-create-dsc) prep_create_dsc "$@" ;;
|
||||||
create-dsc) create_dsc "$@" ;;
|
create-dsc) create_dsc "$@" ;;
|
||||||
|
prep-create-orig) prep_create_orig "$@" ;;
|
||||||
create-orig) create_orig "$@" ;;
|
create-orig) create_orig "$@" ;;
|
||||||
*) usage ;;
|
*) usage ;;
|
||||||
esac
|
esac
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
These are the official Docker files for master branch and the current release packages.
|
These are the official Docker files for master branch and the current release packages.
|
||||||
|
|
||||||
## Volumes
|
## Volumes
|
||||||
These containers are setup so that you can mount your freeswitch configuration form a host or data volume container.
|
These containers are set up so that you can mount your freeswitch configuration from a host or data volume container.
|
||||||
|
|
||||||
To mount freeswitch Configuration
|
To mount freeswitch Configuration
|
||||||
```
|
```
|
||||||
|
@ -16,17 +16,19 @@ To mount tmp directory for storing recordings, etc
|
||||||
|
|
||||||
The container also has a healthcheck where it does a fs_cli status check to make sure the freeswitch service is still running.
|
The container also has a healthcheck where it does a fs_cli status check to make sure the freeswitch service is still running.
|
||||||
|
|
||||||
# Ports
|
## Ports
|
||||||
|
|
||||||
The container exposes the following ports:
|
The container should be run with host networking using `docker run --network host ...`.
|
||||||
|
|
||||||
- 5060/tcp 5060/udp 5080/tcp 5080/udp as SIP Signaling ports.
|
If you prefer to (or for some reason must) publish individual ports via `--publish/-p`, refer to this [issue](https://github.com/moby/moby/issues/11185) and this [potential workaround](https://hub.docker.com/r/bettervoice/freeswitch-container/) regarding using docker with large port ranges.
|
||||||
- 5066/tcp 7443/tcp as WebSocket Signaling ports.
|
|
||||||
- 8021/tcp as Event Socket port.
|
|
||||||
- 64535-65535/udp as media ports.
|
|
||||||
- 16384-32768/udp
|
|
||||||
|
|
||||||
|
The following ports will be used, depending upon your specific configuration:
|
||||||
|
|
||||||
|
- 5060/tcp, 5060/udp, 5080/tcp, 5080/udp - SIP signaling
|
||||||
|
- 5061/tcp, 5081/tcp - SIPS signaling
|
||||||
|
- 5066/tcp, 7443/tcp - WebSocket signaling
|
||||||
|
- 8021/tcp - the Event Socket
|
||||||
|
- 16384-32768/udp, 64535-65535/udp - media
|
||||||
|
|
||||||
|
|
||||||
If you wish to help improve these please submit a pull request at:
|
If you wish to help improve these please submit a pull request at:
|
||||||
|
|
|
@ -1,56 +1,63 @@
|
||||||
# vim:set ft=dockerfile:
|
# vim:set ft=dockerfile:
|
||||||
ARG DEBIAN_VERSION=buster
|
ARG DEBIAN_VERSION=bookworm
|
||||||
FROM debian:${DEBIAN_VERSION}
|
FROM debian:${DEBIAN_VERSION}
|
||||||
|
|
||||||
|
# ARGs are cleared after every FROM
|
||||||
|
# see: https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
|
||||||
|
ARG DEBIAN_VERSION
|
||||||
ARG TOKEN
|
ARG TOKEN
|
||||||
|
|
||||||
|
# By default, install the full set of FreeSWITCH packages. Specify an alternative with:
|
||||||
|
# --build-arg="FS_META_PACKAGE=freeswitch-meta-vanilla"
|
||||||
|
# alternatives include:
|
||||||
|
# freeswitch-meta-bare
|
||||||
|
# freeswitch-meta-vanilla
|
||||||
|
# freeswitch-meta-sorbet
|
||||||
|
# freeswitch-meta-all-dbg
|
||||||
|
ARG FS_META_PACKAGE=freeswitch-meta-all
|
||||||
|
|
||||||
# Source Dockerfile:
|
# Source Dockerfile:
|
||||||
# https://github.com/docker-library/postgres/blob/master/9.4/Dockerfile
|
# https://github.com/docker-library/postgres/blob/master/9.4/Dockerfile
|
||||||
|
|
||||||
# explicitly set user/group IDs
|
# explicitly set user/group IDs
|
||||||
RUN groupadd -r freeswitch --gid=999 && useradd -r -g freeswitch --uid=999 freeswitch
|
ARG FREESWITCH_UID=499
|
||||||
|
ARG FREESWITCH_GID=499
|
||||||
# grab gosu for easy step-down from root
|
RUN groupadd -r freeswitch --gid=${FREESWITCH_GID} && useradd -r -g freeswitch --uid=${FREESWITCH_UID} freeswitch
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends dirmngr gnupg2 ca-certificates wget \
|
|
||||||
&& gpg2 --keyserver hkp://keyserver.ubuntu.com --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
|
|
||||||
&& gpg2 --keyserver hkp://keyserver.ubuntu.com --recv-keys 655DA1341B5207915210AFE936B4249FA7B0FB03 \
|
|
||||||
&& gpg2 --output /usr/share/keyrings/signalwire-freeswitch-repo.gpg --export 655DA1341B5207915210AFE936B4249FA7B0FB03 \
|
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
|
||||||
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.2/gosu-$(dpkg --print-architecture)" \
|
|
||||||
&& wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/1.2/gosu-$(dpkg --print-architecture).asc" \
|
|
||||||
&& gpg --verify /usr/local/bin/gosu.asc \
|
|
||||||
&& rm /usr/local/bin/gosu.asc \
|
|
||||||
&& chmod +x /usr/local/bin/gosu \
|
|
||||||
&& apt-get purge -y --auto-remove ca-certificates wget dirmngr gnupg2
|
|
||||||
|
|
||||||
# make the "en_US.UTF-8" locale so freeswitch will be utf-8 enabled by default
|
# make the "en_US.UTF-8" locale so freeswitch will be utf-8 enabled by default
|
||||||
RUN apt-get update && apt-get install -y locales && rm -rf /var/lib/apt/lists/* \
|
RUN apt-get update -qq \
|
||||||
|
&& apt-get install -y --no-install-recommends ca-certificates gnupg2 gosu locales wget \
|
||||||
&& localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
|
&& localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
|
||||||
ENV LANG en_US.utf8
|
ENV LANG en_US.utf8
|
||||||
|
|
||||||
# https://freeswitch.org/confluence/display/FREESWITCH/Debian
|
# https://freeswitch.org/confluence/display/FREESWITCH/Debian
|
||||||
|
# https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Installation/Linux/Debian_67240088/
|
||||||
|
|
||||||
RUN apt-get update && apt-get install ca-certificates lsb-release -y --no-install-recommends \
|
RUN wget --no-verbose --http-user=signalwire --http-password=${TOKEN} \
|
||||||
|
-O /usr/share/keyrings/signalwire-freeswitch-repo.gpg \
|
||||||
|
https://freeswitch.signalwire.com/repo/deb/debian-release/signalwire-freeswitch-repo.gpg \
|
||||||
&& echo "machine freeswitch.signalwire.com login signalwire password ${TOKEN}" > /etc/apt/auth.conf \
|
&& echo "machine freeswitch.signalwire.com login signalwire password ${TOKEN}" > /etc/apt/auth.conf \
|
||||||
&& echo "deb [signed-by=/usr/share/keyrings/signalwire-freeswitch-repo.gpg] https://freeswitch.signalwire.com/repo/deb/debian-release/ `lsb_release -sc` main" > /etc/apt/sources.list.d/freeswitch.list \
|
&& echo "deb [signed-by=/usr/share/keyrings/signalwire-freeswitch-repo.gpg] https://freeswitch.signalwire.com/repo/deb/debian-release/ ${DEBIAN_VERSION} main" > /etc/apt/sources.list.d/freeswitch.list \
|
||||||
&& apt-get update && apt-get install -y freeswitch-all \
|
&& apt-get -qq update \
|
||||||
&& apt-get purge -y --auto-remove ca-certificates lsb-release \
|
&& apt-get install -y ${FS_META_PACKAGE} \
|
||||||
|
&& apt-get purge -y --auto-remove \
|
||||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY docker-entrypoint.sh /
|
COPY docker-entrypoint.sh /
|
||||||
# Add anything else here
|
# Add anything else here
|
||||||
|
|
||||||
## Ports
|
## Ports
|
||||||
# Open the container up to the world.
|
# Document ports used by this container
|
||||||
### 8021 fs_cli, 5060 5061 5080 5081 sip and sips, 64535-65535 rtp
|
### 8021 fs_cli, 5060 5061 5080 5081 sip and sips, 5066 ws, 7443 wss, 8081 8082 verto, 16384-32768, 64535-65535 rtp
|
||||||
EXPOSE 8021/tcp
|
EXPOSE 8021/tcp
|
||||||
EXPOSE 5060/tcp 5060/udp 5080/tcp 5080/udp
|
EXPOSE 5060/tcp 5060/udp 5080/tcp 5080/udp
|
||||||
EXPOSE 5061/tcp 5061/udp 5081/tcp 5081/udp
|
EXPOSE 5061/tcp 5061/udp 5081/tcp 5081/udp
|
||||||
|
EXPOSE 5066/tcp
|
||||||
EXPOSE 7443/tcp
|
EXPOSE 7443/tcp
|
||||||
EXPOSE 5070/udp 5070/tcp
|
EXPOSE 8081/tcp 8082/tcp
|
||||||
EXPOSE 64535-65535/udp
|
EXPOSE 64535-65535/udp
|
||||||
EXPOSE 16384-32768/udp
|
EXPOSE 16384-32768/udp
|
||||||
|
|
||||||
|
|
||||||
# Volumes
|
# Volumes
|
||||||
## Freeswitch Configuration
|
## Freeswitch Configuration
|
||||||
VOLUME ["/etc/freeswitch"]
|
VOLUME ["/etc/freeswitch"]
|
||||||
|
@ -61,11 +68,9 @@ VOLUME ["/tmp"]
|
||||||
COPY build/freeswitch.limits.conf /etc/security/limits.d/
|
COPY build/freeswitch.limits.conf /etc/security/limits.d/
|
||||||
|
|
||||||
# Healthcheck to make sure the service is running
|
# Healthcheck to make sure the service is running
|
||||||
SHELL ["/bin/bash"]
|
SHELL ["/bin/bash", "-c"]
|
||||||
HEALTHCHECK --interval=15s --timeout=5s \
|
HEALTHCHECK --interval=15s --timeout=5s \
|
||||||
CMD fs_cli -x status | grep -q ^UP || exit 1
|
CMD fs_cli -x status | grep -q ^UP || exit 1
|
||||||
|
|
||||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||||
|
|
||||||
|
|
||||||
CMD ["freeswitch"]
|
CMD ["freeswitch"]
|
||||||
|
|
|
@ -140,7 +140,7 @@ BuildRequires: curl-devel >= 7.19
|
||||||
BuildRequires: gcc-c++
|
BuildRequires: gcc-c++
|
||||||
BuildRequires: libtool >= 1.5.17
|
BuildRequires: libtool >= 1.5.17
|
||||||
BuildRequires: openssl-devel >= 1.0.1e
|
BuildRequires: openssl-devel >= 1.0.1e
|
||||||
BuildRequires: sofia-sip-devel >= 1.13.14
|
BuildRequires: sofia-sip-devel >= 1.13.17
|
||||||
BuildRequires: spandsp3-devel >= 3.0
|
BuildRequires: spandsp3-devel >= 3.0
|
||||||
BuildRequires: pcre-devel
|
BuildRequires: pcre-devel
|
||||||
BuildRequires: speex-devel
|
BuildRequires: speex-devel
|
||||||
|
@ -497,7 +497,7 @@ the entries aloud via a TTS engine
|
||||||
Summary: FreeSWITCH mod_signalwire
|
Summary: FreeSWITCH mod_signalwire
|
||||||
Group: System/Libraries
|
Group: System/Libraries
|
||||||
Requires: %{name} = %{version}-%{release}
|
Requires: %{name} = %{version}-%{release}
|
||||||
BuildRequires: libks signalwire-client-c
|
BuildRequires: libks2 signalwire-client-c2
|
||||||
|
|
||||||
%description application-signalwire
|
%description application-signalwire
|
||||||
Provides FreeSWITCH mod_signalwire
|
Provides FreeSWITCH mod_signalwire
|
||||||
|
@ -952,16 +952,6 @@ Requires: %{name} = %{version}-%{release}
|
||||||
%description event-format-cdr
|
%description event-format-cdr
|
||||||
JSON and XML Logger for the FreeSWITCH open source telephony platform
|
JSON and XML Logger for the FreeSWITCH open source telephony platform
|
||||||
|
|
||||||
%package kazoo
|
|
||||||
Summary: Kazoo Module for the FreeSWITCH open source telephony platform
|
|
||||||
Group: System/Libraries
|
|
||||||
Requires: %{name} = %{version}-%{release}
|
|
||||||
Requires: erlang
|
|
||||||
BuildRequires: erlang
|
|
||||||
|
|
||||||
%description kazoo
|
|
||||||
Kazoo Module for FreeSWITCH.
|
|
||||||
|
|
||||||
%package event-multicast
|
%package event-multicast
|
||||||
Summary: Multicast Event System for the FreeSWITCH open source telephony platform
|
Summary: Multicast Event System for the FreeSWITCH open source telephony platform
|
||||||
Group: System/Libraries
|
Group: System/Libraries
|
||||||
|
@ -1480,7 +1470,7 @@ ENDPOINTS_MODULES=" \
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
EVENT_HANDLERS_MODULES="event_handlers/mod_cdr_csv event_handlers/mod_cdr_pg_csv event_handlers/mod_cdr_sqlite \
|
EVENT_HANDLERS_MODULES="event_handlers/mod_cdr_csv event_handlers/mod_cdr_pg_csv event_handlers/mod_cdr_sqlite \
|
||||||
event_handlers/mod_cdr_mongodb event_handlers/mod_format_cdr event_handlers/mod_erlang_event event_handlers/mod_event_multicast \
|
event_handlers/mod_cdr_mongodb event_handlers/mod_format_cdr event_handlers/mod_erlang_event event_handlers/mod_event_multicast \
|
||||||
event_handlers/mod_event_socket event_handlers/mod_json_cdr event_handlers/mod_kazoo event_handlers/mod_radius_cdr \
|
event_handlers/mod_event_socket event_handlers/mod_json_cdr event_handlers/mod_radius_cdr \
|
||||||
event_handlers/mod_snmp"
|
event_handlers/mod_snmp"
|
||||||
%if %{build_mod_rayo}
|
%if %{build_mod_rayo}
|
||||||
EVENT_HANDLERS_MODULES+=" event_handlers/mod_rayo"
|
EVENT_HANDLERS_MODULES+=" event_handlers/mod_rayo"
|
||||||
|
@ -1916,7 +1906,6 @@ fi
|
||||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/http_cache.conf.xml
|
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/http_cache.conf.xml
|
||||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/ivr.conf.xml
|
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/ivr.conf.xml
|
||||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/java.conf.xml
|
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/java.conf.xml
|
||||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/kazoo.conf.xml
|
|
||||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/lcr.conf.xml
|
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/lcr.conf.xml
|
||||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/local_stream.conf.xml
|
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/local_stream.conf.xml
|
||||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/logfile.conf.xml
|
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/logfile.conf.xml
|
||||||
|
@ -2286,9 +2275,6 @@ fi
|
||||||
%files event-json-cdr
|
%files event-json-cdr
|
||||||
%{MODINSTDIR}/mod_json_cdr.so*
|
%{MODINSTDIR}/mod_json_cdr.so*
|
||||||
|
|
||||||
%files kazoo
|
|
||||||
%{MODINSTDIR}/mod_kazoo.so*
|
|
||||||
|
|
||||||
%files event-radius-cdr
|
%files event-radius-cdr
|
||||||
%{MODINSTDIR}/mod_radius_cdr.so*
|
%{MODINSTDIR}/mod_radius_cdr.so*
|
||||||
|
|
||||||
|
|
|
@ -1447,6 +1447,11 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) {
|
||||||
last_h = cpi->oxcf.Height;
|
last_h = cpi->oxcf.Height;
|
||||||
prev_number_of_layers = cpi->oxcf.number_of_layers;
|
prev_number_of_layers = cpi->oxcf.number_of_layers;
|
||||||
|
|
||||||
|
if (cpi->initial_width) {
|
||||||
|
// TODO(https://crbug.com/1486441): Allow changing thread counts; the
|
||||||
|
// allocation is done once in vp8_create_compressor().
|
||||||
|
oxcf->multi_threaded = cpi->oxcf.multi_threaded;
|
||||||
|
}
|
||||||
cpi->oxcf = *oxcf;
|
cpi->oxcf = *oxcf;
|
||||||
|
|
||||||
switch (cpi->oxcf.Mode) {
|
switch (cpi->oxcf.Mode) {
|
||||||
|
|
|
@ -123,12 +123,6 @@ int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) {
|
||||||
if (cm->alloc_mi(cm, new_mi_size)) goto fail;
|
if (cm->alloc_mi(cm, new_mi_size)) goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cm->seg_map_alloc_size < cm->mi_rows * cm->mi_cols) {
|
|
||||||
// Create the segmentation map structure and set to 0.
|
|
||||||
free_seg_map(cm);
|
|
||||||
if (alloc_seg_map(cm, cm->mi_rows * cm->mi_cols)) goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cm->above_context_alloc_cols < cm->mi_cols) {
|
if (cm->above_context_alloc_cols < cm->mi_cols) {
|
||||||
vpx_free(cm->above_context);
|
vpx_free(cm->above_context);
|
||||||
cm->above_context = (ENTROPY_CONTEXT *)vpx_calloc(
|
cm->above_context = (ENTROPY_CONTEXT *)vpx_calloc(
|
||||||
|
@ -143,6 +137,12 @@ int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) {
|
||||||
cm->above_context_alloc_cols = cm->mi_cols;
|
cm->above_context_alloc_cols = cm->mi_cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cm->seg_map_alloc_size < cm->mi_rows * cm->mi_cols) {
|
||||||
|
// Create the segmentation map structure and set to 0.
|
||||||
|
free_seg_map(cm);
|
||||||
|
if (alloc_seg_map(cm, cm->mi_rows * cm->mi_cols)) goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
if (vp9_alloc_loop_filter(cm)) goto fail;
|
if (vp9_alloc_loop_filter(cm)) goto fail;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1915,6 +1915,17 @@ static void alloc_copy_partition_data(VP9_COMP *cpi) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void free_copy_partition_data(VP9_COMP *cpi) {
|
||||||
|
vpx_free(cpi->prev_partition);
|
||||||
|
cpi->prev_partition = NULL;
|
||||||
|
vpx_free(cpi->prev_segment_id);
|
||||||
|
cpi->prev_segment_id = NULL;
|
||||||
|
vpx_free(cpi->prev_variance_low);
|
||||||
|
cpi->prev_variance_low = NULL;
|
||||||
|
vpx_free(cpi->copied_frame_cnt);
|
||||||
|
cpi->copied_frame_cnt = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
|
void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
|
||||||
VP9_COMMON *const cm = &cpi->common;
|
VP9_COMMON *const cm = &cpi->common;
|
||||||
RATE_CONTROL *const rc = &cpi->rc;
|
RATE_CONTROL *const rc = &cpi->rc;
|
||||||
|
@ -1999,6 +2010,8 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
|
||||||
new_mi_size = cm->mi_stride * calc_mi_size(cm->mi_rows);
|
new_mi_size = cm->mi_stride * calc_mi_size(cm->mi_rows);
|
||||||
if (cm->mi_alloc_size < new_mi_size) {
|
if (cm->mi_alloc_size < new_mi_size) {
|
||||||
vp9_free_context_buffers(cm);
|
vp9_free_context_buffers(cm);
|
||||||
|
vp9_free_pc_tree(&cpi->td);
|
||||||
|
vpx_free(cpi->mbmi_ext_base);
|
||||||
alloc_compressor_data(cpi);
|
alloc_compressor_data(cpi);
|
||||||
realloc_segmentation_maps(cpi);
|
realloc_segmentation_maps(cpi);
|
||||||
cpi->initial_width = cpi->initial_height = 0;
|
cpi->initial_width = cpi->initial_height = 0;
|
||||||
|
@ -2014,8 +2027,18 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
|
||||||
update_frame_size(cpi);
|
update_frame_size(cpi);
|
||||||
|
|
||||||
if (last_w != cpi->oxcf.width || last_h != cpi->oxcf.height) {
|
if (last_w != cpi->oxcf.width || last_h != cpi->oxcf.height) {
|
||||||
memset(cpi->consec_zero_mv, 0,
|
vpx_free(cpi->consec_zero_mv);
|
||||||
cm->mi_rows * cm->mi_cols * sizeof(*cpi->consec_zero_mv));
|
CHECK_MEM_ERROR(
|
||||||
|
cm, cpi->consec_zero_mv,
|
||||||
|
vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(*cpi->consec_zero_mv)));
|
||||||
|
|
||||||
|
vpx_free(cpi->skin_map);
|
||||||
|
CHECK_MEM_ERROR(
|
||||||
|
cm, cpi->skin_map,
|
||||||
|
vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(cpi->skin_map[0])));
|
||||||
|
|
||||||
|
free_copy_partition_data(cpi);
|
||||||
|
alloc_copy_partition_data(cpi);
|
||||||
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
|
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
|
||||||
vp9_cyclic_refresh_reset_resize(cpi);
|
vp9_cyclic_refresh_reset_resize(cpi);
|
||||||
rc->rc_1_frame = 0;
|
rc->rc_1_frame = 0;
|
||||||
|
|
|
@ -582,7 +582,7 @@ typedef void (*ARGBBlendRow)(const uint8_t* src_argb0,
|
||||||
|
|
||||||
// Get function to Alpha Blend ARGB pixels and store to destination.
|
// Get function to Alpha Blend ARGB pixels and store to destination.
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
ARGBBlendRow GetARGBBlend();
|
ARGBBlendRow GetARGBBlend(void);
|
||||||
|
|
||||||
// Alpha Blend ARGB images and store to destination.
|
// Alpha Blend ARGB images and store to destination.
|
||||||
// Source is pre-multiplied by alpha using ARGBAttenuate.
|
// Source is pre-multiplied by alpha using ARGBAttenuate.
|
||||||
|
|
|
@ -1185,7 +1185,7 @@ int ARGBMirror(const uint8_t* src_argb,
|
||||||
// As there are 6 blenders to choose from, the caller should try to use
|
// As there are 6 blenders to choose from, the caller should try to use
|
||||||
// the same blend function for all pixels if possible.
|
// the same blend function for all pixels if possible.
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
ARGBBlendRow GetARGBBlend() {
|
ARGBBlendRow GetARGBBlend(void) {
|
||||||
void (*ARGBBlendRow)(const uint8_t* src_argb, const uint8_t* src_argb1,
|
void (*ARGBBlendRow)(const uint8_t* src_argb, const uint8_t* src_argb1,
|
||||||
uint8_t* dst_argb, int width) = ARGBBlendRow_C;
|
uint8_t* dst_argb, int width) = ARGBBlendRow_C;
|
||||||
#if defined(HAS_ARGBBLENDROW_SSSE3)
|
#if defined(HAS_ARGBBLENDROW_SSSE3)
|
||||||
|
|
|
@ -679,7 +679,6 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
|
||||||
char * descXML;
|
char * descXML;
|
||||||
int descXMLsize = 0;
|
int descXMLsize = 0;
|
||||||
struct UPNPDev * dev;
|
struct UPNPDev * dev;
|
||||||
int ndev = 0;
|
|
||||||
int state; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
|
int state; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
|
||||||
if(!devlist)
|
if(!devlist)
|
||||||
{
|
{
|
||||||
|
@ -698,7 +697,6 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
|
||||||
lanaddr, lanaddrlen);
|
lanaddr, lanaddrlen);
|
||||||
if(descXML)
|
if(descXML)
|
||||||
{
|
{
|
||||||
ndev++;
|
|
||||||
memset(data, 0, sizeof(struct IGDdatas));
|
memset(data, 0, sizeof(struct IGDdatas));
|
||||||
memset(urls, 0, sizeof(struct UPNPUrls));
|
memset(urls, 0, sizeof(struct UPNPUrls));
|
||||||
parserootdesc(descXML, descXMLsize, data);
|
parserootdesc(descXML, descXMLsize, data);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -260,7 +260,9 @@
|
||||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
#define inline
|
#ifndef _WIN32
|
||||||
|
#define inline /* Do not define inline for Windows to avoid warnings/errors with winsock2.h usage of inline within the latest Windows SDKs */
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _MSC_VER >= 1900
|
#if _MSC_VER >= 1900
|
||||||
|
|
|
@ -3,7 +3,12 @@
|
||||||
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <strings.h>
|
||||||
|
#else
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "xmlrpc_config.h"
|
#include "xmlrpc_config.h"
|
||||||
#include "c_util.h"
|
#include "c_util.h"
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
/* Copyright information is at end of file */
|
/* Copyright information is at end of file */
|
||||||
|
|
||||||
#define _XOPEN_SOURCE 600 /* Make sure strdup() is in <string.h> */
|
#define _XOPEN_SOURCE 600 /* Make sure strdup() is in <string.h> */
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#define _DARWIN_C_SOURCE
|
||||||
|
#endif
|
||||||
#define _BSD_SOURCE /* Make sure setgroups()is in <grp.h> */
|
#define _BSD_SOURCE /* Make sure setgroups()is in <grp.h> */
|
||||||
#ifndef _DEFAULT_SOURCE
|
#ifndef _DEFAULT_SOURCE
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
|
|
|
@ -3,7 +3,11 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#else
|
||||||
#include <wait.h>
|
#include <wait.h>
|
||||||
|
#endif
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include "xmlrpc_config.h"
|
#include "xmlrpc_config.h"
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
#define _XOPEN_SOURCE 600 /* Make sure strdup() is in <string.h> */
|
#define _XOPEN_SOURCE 600 /* Make sure strdup() is in <string.h> */
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#define _DARWIN_C_SOURCE
|
||||||
|
#endif
|
||||||
#ifndef _GNU_SOURCE
|
#ifndef _GNU_SOURCE
|
||||||
#define _GNU_SOURCE /* But only when HAVE_ASPRINTF */
|
#define _GNU_SOURCE /* But only when HAVE_ASPRINTF */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
local https = require("socket.http")
|
||||||
|
local ip = os.getenv("LOCAL_IPV4")
|
||||||
|
local response_body = {}
|
||||||
|
-- jitter buffer stats
|
||||||
|
local size_max_ms = session:getVariable("rtp_jb_size_max_ms");
|
||||||
|
local size_est_ms = session:getVariable("rtp_jb_size_est_ms");
|
||||||
|
local acceleration_ms = session:getVariable("rtp_jb_acceleration_ms");
|
||||||
|
local expand_ms = session:getVariable("rtp_jb_expand_ms");
|
||||||
|
local jitter_max_ms = session:getVariable("rtp_jb_jitter_max_ms");
|
||||||
|
local jitter_est_ms = session:getVariable("rtp_jb_jitter_est_ms");
|
||||||
|
|
||||||
|
local reset_count = session:getVariable("rtp_jb_reset_count");
|
||||||
|
local reset_too_big = session:getVariable("rtp_jb_reset_too_big");
|
||||||
|
local reset_missing_frames = session:getVariable("rtp_jb_reset_missing_frames");
|
||||||
|
local reset_ts_jump = session:getVariable("rtp_jb_reset_ts_jump");
|
||||||
|
local reset_error = session:getVariable("rtp_jb_reset_error");
|
||||||
|
local call_id = session:getVariable("sip_call_id");
|
||||||
|
local out_call_id = session:getVariable("last_bridge_to");
|
||||||
|
|
||||||
|
if size_max_ms == nil or size_est_ms == nil or acceleration_ms == nil or expand_ms == nil or jitter_max_ms == nil or jitter_est_ms == nil then
|
||||||
|
session:consoleLog("info", "[metrics] jitter no data\n");
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local request_body = '{"in_call_id": "'..call_id..'", "out_call_id": "'..out_call_id..'", "jb":{"size_max_ms":'..size_max_ms..
|
||||||
|
',"size_est_ms":'..size_est_ms..',"acceleration_ms":'..acceleration_ms..',"expand_ms":'..expand_ms..
|
||||||
|
',"jitter_max_ms":'..jitter_max_ms..',"jitter_est_ms":'..jitter_est_ms..',"reset":'..reset_count
|
||||||
|
-- if reset_too_big ~= "0" then
|
||||||
|
request_body = request_body .. ',"reset_too_big":'..reset_too_big
|
||||||
|
-- end
|
||||||
|
if reset_missing_frames ~= "0" then
|
||||||
|
request_body = request_body .. ',"reset_missing_frames":'..reset_missing_frames
|
||||||
|
end
|
||||||
|
if reset_ts_jump ~= "0" then
|
||||||
|
request_body = request_body .. ',"reset_ts_jump":'..reset_ts_jump
|
||||||
|
end
|
||||||
|
if reset_error ~= "0" then
|
||||||
|
request_body = request_body .. ',"reset_error":'..reset_error
|
||||||
|
end
|
||||||
|
|
||||||
|
local v = request_body .. '}}';
|
||||||
|
|
||||||
|
local r, c, h, s = https.request{
|
||||||
|
method = 'POST',
|
||||||
|
url = "http://"..ip..":80/freeswitch_metrics",
|
||||||
|
headers = {
|
||||||
|
["Content-Type"] = "application/json",
|
||||||
|
["Content-Length"] = string.len(v)
|
||||||
|
},
|
||||||
|
source = ltn12.source.string(v),
|
||||||
|
sink = ltn12.sink.table(response_body)
|
||||||
|
}
|
||||||
|
-- print('statusCode ', c)
|
||||||
|
session:consoleLog("info", "[metrics] jitter:".. v .. "\n");
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
my $remote_version = `wget --quiet https://data.iana.org/time-zones/tzdb/version --output-document -` =~ s/\n//r;
|
||||||
|
my $local_version;
|
||||||
|
|
||||||
|
if ( open my $in, "<data/version" ) {
|
||||||
|
$local_version = do { local $/; <$in> };
|
||||||
|
close $in;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $up_to_date = defined($local_version) && $local_version eq $remote_version;
|
||||||
|
|
||||||
|
if ( ! $up_to_date ) {
|
||||||
|
open my $out, ">data/version";
|
||||||
|
print $out $remote_version;
|
||||||
|
close $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
$local_version = $remote_version;
|
||||||
|
|
||||||
|
`wget --quiet --timestamping --directory-prefix=data https://data.iana.org/time-zones/tzdb-latest.tar.lz`;
|
||||||
|
`tar --extract --file=data/tzdb-latest.tar.lz --directory=data`;
|
||||||
|
`make DESTDIR=../ TZDIR=zones-$local_version --directory=data/tzdb-$local_version posix_only`;
|
||||||
|
|
||||||
|
print("Yay. Now you can run\n ./timezone-gen.pl --base=data/zones-$local_version --output=timezones-$local_version.conf.xml")
|
|
@ -0,0 +1,4 @@
|
||||||
|
tzdb-*
|
||||||
|
zones-*
|
||||||
|
version
|
||||||
|
tzdb-latest.tar.lz
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
sub fixTzstr {
|
||||||
|
# switch_time.c expects POSIX-style TZ rule, but it won't process quoted TZ
|
||||||
|
# rules that look like this: <-04>4 or <-04>4<-03>
|
||||||
|
# See https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03
|
||||||
|
|
||||||
|
# Instead it defaults to UTC for these values. Here we process the quoted
|
||||||
|
# values and convert them into letters. If the zone name has "GMT", we use
|
||||||
|
# that as the replacement prefix, otherwise a default "STD" is used. Zones
|
||||||
|
# that have a quoted suffix have their suffix replaced with "DST".
|
||||||
|
|
||||||
|
my ($tzstr, $name) = @_;
|
||||||
|
|
||||||
|
if ( $tzstr =~ /(<(?<std>[^>]+)>)([^<]+)(?<dst><.+>)?(?<rest>.+)?/ ) {
|
||||||
|
my ($tzprefix, $tzsuffix, $tzrest, $offset, $offsetprefix) = ("") x 5;
|
||||||
|
|
||||||
|
if ( defined($+{std}) ) {
|
||||||
|
my $std = $+{std};
|
||||||
|
|
||||||
|
if ( lc($name) =~ m/gmt/) {
|
||||||
|
$tzprefix = "GMT";
|
||||||
|
} else {
|
||||||
|
$tzprefix = "STD";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $std =~ m/\+/ ) {
|
||||||
|
$offset = sprintf "%d", $std =~ s/\+//r;
|
||||||
|
$offsetprefix = "-";
|
||||||
|
} else {
|
||||||
|
$offset = sprintf "%d", $std =~ s/\-//r;
|
||||||
|
}
|
||||||
|
|
||||||
|
my @chars = split(//, $offset);
|
||||||
|
if ( @chars > 2 ) {
|
||||||
|
my $hours = $chars[-3];
|
||||||
|
if ( defined( $chars[-4] ) ) {
|
||||||
|
$hours = $chars[-4].$hours;
|
||||||
|
}
|
||||||
|
|
||||||
|
$offset = $hours.":".$chars[-2].$chars[-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$offset = $offsetprefix.$offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( defined($+{dst}) ) {
|
||||||
|
$tzsuffix = "DST";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( defined($+{rest}) ) {
|
||||||
|
$tzrest = $+{rest};
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tzprefix.$offset.$tzsuffix.$tzrest;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tzstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
|
@ -0,0 +1,65 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
=pod
|
||||||
|
Tests to verify that the provided modifications to timezone formats produce
|
||||||
|
the correct results. The first set of tests verify the fixTzstr subroutine
|
||||||
|
converts the quoted values to something that won't make FreeSWITCH default to
|
||||||
|
UTC.
|
||||||
|
|
||||||
|
The second set of tests confirms that those timezone changes actually produce
|
||||||
|
the correct timestamps.
|
||||||
|
|
||||||
|
Make sure FreeSWITCH already has already loaded the timezones.conf.xml that you
|
||||||
|
want to test.
|
||||||
|
|
||||||
|
To run tests:
|
||||||
|
|
||||||
|
TIMEZONES_XML_PATH=path/to/timezones.conf.xml prove tests.pl
|
||||||
|
=cut
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Test::More;
|
||||||
|
use ESL;
|
||||||
|
use XML::LibXML::Reader;
|
||||||
|
|
||||||
|
require "./fix-tzstr.pl";
|
||||||
|
|
||||||
|
use Env qw(TIMEZONES_XML_PATH);
|
||||||
|
die "The TIMEZONES_XML_PATH environment variable must be set to test timezones." unless ( defined($TIMEZONES_XML_PATH) );
|
||||||
|
|
||||||
|
ok( fixTzstr("<-02>2", "doesntmatterhere") eq "STD2" );
|
||||||
|
ok( fixTzstr("EST5EDT,M3.2.0,M11.1.0", "US/Eastern") eq "EST5EDT,M3.2.0,M11.1.0" );
|
||||||
|
ok( fixTzstr("<+11>-11", "GMT-11") eq "GMT-11" );
|
||||||
|
ok( fixTzstr("<-02>2<-01>,M3.5.0/-1,M10.5.0/0", "America/Godthab") eq "STD2DST,M3.5.0/-1,M10.5.0/0" );
|
||||||
|
|
||||||
|
my $test_count = 4;
|
||||||
|
|
||||||
|
my $tz_fmt = "%Y-%m-%d %H:%M:%S";
|
||||||
|
my $c = new ESL::ESLconnection("127.0.0.1", "8021", "ClueCon");
|
||||||
|
$c->api("reloadxml")->getBody();
|
||||||
|
my $epoch = $c->api("strepoch")->getBody();
|
||||||
|
run_tests($epoch);
|
||||||
|
run_tests("1699613236"); # testing DST, add more epochs as needed
|
||||||
|
|
||||||
|
sub run_tests {
|
||||||
|
my $epoch = shift;
|
||||||
|
my $reader = XML::LibXML::Reader->new(location => $TIMEZONES_XML_PATH);
|
||||||
|
while ($reader->read) {
|
||||||
|
my $tag = $reader;
|
||||||
|
if ( $tag->name eq "zone" && $tag->hasAttributes() ) {
|
||||||
|
my $zn = $tag->getAttribute("name");
|
||||||
|
|
||||||
|
my $cmd = `TZ='$zn' date +'$tz_fmt' --date='\@$epoch'`;
|
||||||
|
my $sys_time = $cmd =~ s/\n//r;
|
||||||
|
my $fs_time = $c->api("strftime_tz $zn $epoch|$tz_fmt")->getBody();
|
||||||
|
|
||||||
|
ok ( $sys_time eq $fs_time, $zn ) or diag(
|
||||||
|
" (sys) $sys_time\t(fs) $fs_time"
|
||||||
|
);
|
||||||
|
|
||||||
|
$test_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done_testing($test_count);
|
|
@ -1,10 +1,12 @@
|
||||||
#!/usr/bin/perl
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
|
use warnings;
|
||||||
use Getopt::Long;
|
use Getopt::Long;
|
||||||
use XML::Entities;
|
use XML::Entities;
|
||||||
use HTML::Entities;
|
use HTML::Entities;
|
||||||
|
|
||||||
|
require "./fix-tzstr.pl";
|
||||||
|
|
||||||
my $base = "/usr/share/zoneinfo";
|
my $base = "/usr/share/zoneinfo";
|
||||||
my $output = "timezones.conf.xml";
|
my $output = "timezones.conf.xml";
|
||||||
|
@ -18,7 +20,7 @@ my $res = GetOptions(
|
||||||
"base=s" => \$base,
|
"base=s" => \$base,
|
||||||
"debug+" => \$debug,
|
"debug+" => \$debug,
|
||||||
"help" => \$help,
|
"help" => \$help,
|
||||||
"output" => \$output
|
"output=s" => \$output
|
||||||
);
|
);
|
||||||
if ( !$res || $help ) {
|
if ( !$res || $help ) {
|
||||||
print "$0 [--base=/usr/share/zoneinfo] [--output=timezones.conf.xml] [--debug] [--help]\n";
|
print "$0 [--base=/usr/share/zoneinfo] [--output=timezones.conf.xml] [--debug] [--help]\n";
|
||||||
|
@ -64,7 +66,9 @@ foreach my $name ( sort( keys(%name_to_file) ) ) {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
$zones{$name} = pop(@strings);
|
my $tzstr = fixTzstr( pop(@strings), $name );
|
||||||
|
|
||||||
|
$zones{$name} = $tzstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
open( my $out, ">$output" );
|
open( my $out, ">$output" );
|
||||||
|
@ -83,7 +87,7 @@ foreach my $zone ( sort( keys(%zones) ) ) {
|
||||||
}
|
}
|
||||||
$lastprefix = $newprefix;
|
$lastprefix = $newprefix;
|
||||||
|
|
||||||
print $out "\t<zone name=\"$zone\" value=\"$str\" />\n";
|
print $out " " x 8, "<zone name=\"$zone\" value=\"$str\" />\n";
|
||||||
}
|
}
|
||||||
print $out " " x 4, "</timezones>\n";
|
print $out " " x 4, "</timezones>\n";
|
||||||
print $out "</configuration>\n";
|
print $out "</configuration>\n";
|
44
src/cJSON.c
44
src/cJSON.c
|
@ -1104,34 +1104,32 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i
|
||||||
buffer->length = default_buffer_size;
|
buffer->length = default_buffer_size;
|
||||||
buffer->format = format;
|
buffer->format = format;
|
||||||
buffer->hooks = *hooks;
|
buffer->hooks = *hooks;
|
||||||
if (buffer->buffer == NULL)
|
|
||||||
{
|
if (buffer->buffer == NULL) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print the value */
|
/* print the value */
|
||||||
if (!print_value(item, buffer))
|
if (!print_value(item, buffer)) {
|
||||||
{
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_offset(buffer);
|
update_offset(buffer);
|
||||||
|
|
||||||
/* check if reallocate is available */
|
/* check if reallocate is available */
|
||||||
if (hooks->reallocate != NULL)
|
if (hooks->reallocate != NULL) {
|
||||||
{
|
|
||||||
printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
|
printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
|
||||||
if (printed == NULL) {
|
if (printed == NULL) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer->buffer = NULL;
|
buffer->buffer = NULL;
|
||||||
}
|
} else { /* otherwise copy the JSON over to a new buffer */
|
||||||
else /* otherwise copy the JSON over to a new buffer */
|
|
||||||
{
|
|
||||||
printed = (unsigned char*) hooks->allocate(buffer->offset + 1);
|
printed = (unsigned char*) hooks->allocate(buffer->offset + 1);
|
||||||
if (printed == NULL)
|
if (printed == NULL) {
|
||||||
{
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));
|
memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));
|
||||||
printed[buffer->offset] = '\0'; /* just to be sure */
|
printed[buffer->offset] = '\0'; /* just to be sure */
|
||||||
|
|
||||||
|
@ -1142,16 +1140,10 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i
|
||||||
return printed;
|
return printed;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (buffer->buffer != NULL)
|
if (buffer->buffer != NULL) {
|
||||||
{
|
|
||||||
hooks->deallocate(buffer->buffer);
|
hooks->deallocate(buffer->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (printed != NULL)
|
|
||||||
{
|
|
||||||
hooks->deallocate(printed);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1942,33 +1934,41 @@ static cJSON_bool add_item_to_object(cJSON * const object, const char * const st
|
||||||
|
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
|
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
|
||||||
{
|
{
|
||||||
add_item_to_object(object, string, item, &global_hooks, false);
|
cJSON_bool res = add_item_to_object(object, string, item, &global_hooks, false);
|
||||||
|
(void)res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add an item to an object with constant string as key */
|
/* Add an item to an object with constant string as key */
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
|
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
|
||||||
{
|
{
|
||||||
add_item_to_object(object, string, item, &global_hooks, true);
|
cJSON_bool res = add_item_to_object(object, string, item, &global_hooks, true);
|
||||||
|
(void)res;
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
|
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
|
||||||
{
|
{
|
||||||
|
cJSON_bool res;
|
||||||
|
|
||||||
if (array == NULL)
|
if (array == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_item_to_array(array, create_reference(item, &global_hooks));
|
res = add_item_to_array(array, create_reference(item, &global_hooks));
|
||||||
|
(void)res;
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
|
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
|
||||||
{
|
{
|
||||||
|
cJSON_bool res;
|
||||||
|
|
||||||
if ((object == NULL) || (string == NULL))
|
if ((object == NULL) || (string == NULL))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);
|
res = add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);
|
||||||
|
(void)res;
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name)
|
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name)
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
#pragma warning (disable:167)
|
#pragma warning (disable:167)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void fs_encode_cleanup()
|
static void fs_encode_cleanup(void)
|
||||||
{
|
{
|
||||||
switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir);
|
switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir);
|
||||||
switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir);
|
switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir);
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
#pragma warning (disable:167)
|
#pragma warning (disable:167)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void fs_tts_cleanup()
|
static void fs_tts_cleanup(void)
|
||||||
{
|
{
|
||||||
switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir);
|
switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir);
|
||||||
switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir);
|
switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir);
|
||||||
|
|
|
@ -325,6 +325,24 @@ SWITCH_DECLARE(switch_status_t) switch_channel_get_scope_variables(switch_channe
|
||||||
SWITCH_DECLARE(const char *) switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup, int idx);
|
SWITCH_DECLARE(const char *) switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup, int idx);
|
||||||
#define switch_channel_get_variable(_c, _v) switch_channel_get_variable_dup(_c, _v, SWITCH_TRUE, -1)
|
#define switch_channel_get_variable(_c, _v) switch_channel_get_variable_dup(_c, _v, SWITCH_TRUE, -1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Retrieve a copy of a variable from a given channel. switch_safe_free() call will be required.
|
||||||
|
\param channel channel to retrieve variable from
|
||||||
|
\param varname the name of the variable
|
||||||
|
\return a strdup copy the value of the requested variable without using a memory pool.
|
||||||
|
*/
|
||||||
|
SWITCH_DECLARE(const char *) switch_channel_get_variable_strdup(switch_channel_t *channel, const char *varname);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Retrieve a variable from a given channel to a pre-allocated buffer without using a memory pool.
|
||||||
|
\param channel channel to retrieve variable from
|
||||||
|
\param varname the name of the variable
|
||||||
|
\param buf a pre allocated buffer to put the value to
|
||||||
|
\param buflen size of the buffer
|
||||||
|
\return SWITCH_STATUS_SUCCESS if the value was copied to the buffer and it is not NULL, SWITCH_STATUS_FALSE otherwise.
|
||||||
|
*/
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_channel_get_variable_buf(switch_channel_t *channel, const char *varname, char *buf, switch_size_t buflen);
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_channel_get_variables(switch_channel_t *channel, switch_event_t **event);
|
SWITCH_DECLARE(switch_status_t) switch_channel_get_variables(switch_channel_t *channel, switch_event_t **event);
|
||||||
SWITCH_DECLARE(switch_status_t) switch_channel_get_variables_prefix(switch_channel_t *channel, const char *prefix, switch_event_t **event);
|
SWITCH_DECLARE(switch_status_t) switch_channel_get_variables_prefix(switch_channel_t *channel, const char *prefix, switch_event_t **event);
|
||||||
SWITCH_DECLARE(switch_status_t) switch_channel_pass_callee_id(switch_channel_t *channel, switch_channel_t *other_channel);
|
SWITCH_DECLARE(switch_status_t) switch_channel_pass_callee_id(switch_channel_t *channel, switch_channel_t *other_channel);
|
||||||
|
|
|
@ -399,6 +399,10 @@ SWITCH_DECLARE(void) switch_core_media_set_smode(switch_core_session_t *session,
|
||||||
SWITCH_DECLARE(void) switch_core_media_set_resolveice(switch_bool_t resolve_ice);
|
SWITCH_DECLARE(void) switch_core_media_set_resolveice(switch_bool_t resolve_ice);
|
||||||
SWITCH_DECLARE(switch_bool_t) switch_core_media_has_resolveice(void);
|
SWITCH_DECLARE(switch_bool_t) switch_core_media_has_resolveice(void);
|
||||||
|
|
||||||
|
typedef struct switch_rtp_engine_s switch_rtp_engine_t;
|
||||||
|
SWITCH_DECLARE(switch_rtp_engine_t *) switch_core_media_get_engine(switch_core_session_t *session, int media_type);
|
||||||
|
SWITCH_DECLARE(switch_codec_t*) switch_core_media_get_codec(switch_core_session_t *session, switch_media_type_t type);
|
||||||
|
|
||||||
SWITCH_END_EXTERN_C
|
SWITCH_END_EXTERN_C
|
||||||
#endif
|
#endif
|
||||||
/* For Emacs:
|
/* For Emacs:
|
||||||
|
|
|
@ -40,6 +40,9 @@ typedef int switch_CURLINFO;
|
||||||
typedef int switch_CURLcode;
|
typedef int switch_CURLcode;
|
||||||
typedef int switch_CURLoption;
|
typedef int switch_CURLoption;
|
||||||
|
|
||||||
|
#define HAVE_SWITCH_CURL_MIME
|
||||||
|
typedef void switch_curl_mime;
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_CURL *) switch_curl_easy_init(void);
|
SWITCH_DECLARE(switch_CURL *) switch_curl_easy_init(void);
|
||||||
SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_perform(switch_CURL *handle);
|
SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_perform(switch_CURL *handle);
|
||||||
SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_getinfo(switch_CURL *curl, switch_CURLINFO info, ... );
|
SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_getinfo(switch_CURL *curl, switch_CURLINFO info, ... );
|
||||||
|
@ -50,7 +53,9 @@ SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_setopt(CURL *handle, switch_CUR
|
||||||
SWITCH_DECLARE(const char *) switch_curl_easy_strerror(switch_CURLcode errornum );
|
SWITCH_DECLARE(const char *) switch_curl_easy_strerror(switch_CURLcode errornum );
|
||||||
SWITCH_DECLARE(void) switch_curl_init(void);
|
SWITCH_DECLARE(void) switch_curl_init(void);
|
||||||
SWITCH_DECLARE(void) switch_curl_destroy(void);
|
SWITCH_DECLARE(void) switch_curl_destroy(void);
|
||||||
SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_event_t *event, switch_CURL *curl_handle, struct curl_httppost **formpostp);
|
SWITCH_DECLARE(switch_status_t) switch_curl_process_mime(switch_event_t *event, switch_CURL *curl_handle, switch_curl_mime **mimep);
|
||||||
|
SWITCH_DECLARE(void) switch_curl_mime_free(switch_curl_mime **mimep);
|
||||||
|
SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_setopt_mime(switch_CURL *curl_handle, switch_curl_mime *mime);
|
||||||
#define switch_curl_easy_setopt curl_easy_setopt
|
#define switch_curl_easy_setopt curl_easy_setopt
|
||||||
|
|
||||||
SWITCH_END_EXTERN_C
|
SWITCH_END_EXTERN_C
|
||||||
|
|
|
@ -61,6 +61,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||||
SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb);
|
SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb);
|
||||||
SWITCH_DECLARE(switch_status_t) switch_jb_get_packet_by_seq(switch_jb_t *jb, uint16_t seq, switch_rtp_packet_t *packet, switch_size_t *len);
|
SWITCH_DECLARE(switch_status_t) switch_jb_get_packet_by_seq(switch_jb_t *jb, uint16_t seq, switch_rtp_packet_t *packet, switch_size_t *len);
|
||||||
SWITCH_DECLARE(void) switch_jb_set_session(switch_jb_t *jb, switch_core_session_t *session);
|
SWITCH_DECLARE(void) switch_jb_set_session(switch_jb_t *jb, switch_core_session_t *session);
|
||||||
|
SWITCH_DECLARE(void) switch_jb_set_jitter_estimator(switch_jb_t *jb, double *jitter, uint32_t samples_per_frame, uint32_t samples_per_second);
|
||||||
SWITCH_DECLARE(void) switch_jb_ts_mode(switch_jb_t *jb, uint32_t samples_per_frame, uint32_t samples_per_second);
|
SWITCH_DECLARE(void) switch_jb_ts_mode(switch_jb_t *jb, uint32_t samples_per_frame, uint32_t samples_per_second);
|
||||||
SWITCH_DECLARE(void) switch_jb_set_flag(switch_jb_t *jb, switch_jb_flag_t flag);
|
SWITCH_DECLARE(void) switch_jb_set_flag(switch_jb_t *jb, switch_jb_flag_t flag);
|
||||||
SWITCH_DECLARE(void) switch_jb_clear_flag(switch_jb_t *jb, switch_jb_flag_t flag);
|
SWITCH_DECLARE(void) switch_jb_clear_flag(switch_jb_t *jb, switch_jb_flag_t flag);
|
||||||
|
|
|
@ -676,8 +676,14 @@ struct switch_codec_fmtp {
|
||||||
int bits_per_second;
|
int bits_per_second;
|
||||||
/*! number of microseconds of media in one packet (ptime * 1000) */
|
/*! number of microseconds of media in one packet (ptime * 1000) */
|
||||||
int microseconds_per_packet;
|
int microseconds_per_packet;
|
||||||
/*! stereo */
|
/*! maximum ptime in ms */
|
||||||
int stereo;
|
int max_ptime;
|
||||||
|
/*! minimum ptime in ms */
|
||||||
|
int min_ptime;
|
||||||
|
/*! stereo, typically bidirectional */
|
||||||
|
int stereo;
|
||||||
|
/* sender properties (stereo) */
|
||||||
|
int sprop_stereo;
|
||||||
/*! private data for the codec module to store handle specific info */
|
/*! private data for the codec module to store handle specific info */
|
||||||
void *private_info;
|
void *private_info;
|
||||||
|
|
||||||
|
|
|
@ -103,15 +103,18 @@ typedef struct icand_s {
|
||||||
switch_port_t rport;
|
switch_port_t rport;
|
||||||
char *generation;
|
char *generation;
|
||||||
uint8_t ready;
|
uint8_t ready;
|
||||||
|
uint8_t responsive;
|
||||||
|
uint8_t use_candidate;
|
||||||
} icand_t;
|
} icand_t;
|
||||||
|
|
||||||
#define MAX_CAND 50
|
#define MAX_CAND 50
|
||||||
|
#define MAX_CAND_IDX_COUNT 2
|
||||||
typedef struct ice_s {
|
typedef struct ice_s {
|
||||||
|
|
||||||
icand_t cands[MAX_CAND][2];
|
icand_t cands[MAX_CAND][MAX_CAND_IDX_COUNT];
|
||||||
int cand_idx[2];
|
int cand_idx[MAX_CAND_IDX_COUNT];
|
||||||
int chosen[2];
|
int chosen[MAX_CAND_IDX_COUNT];
|
||||||
int is_chosen[2];
|
int is_chosen[MAX_CAND_IDX_COUNT];
|
||||||
char *ufrag;
|
char *ufrag;
|
||||||
char *pwd;
|
char *pwd;
|
||||||
char *options;
|
char *options;
|
||||||
|
|
|
@ -2249,7 +2249,8 @@ typedef enum {
|
||||||
SWITCH_CAUSE_BAD_IDENTITY_INFO = 821,
|
SWITCH_CAUSE_BAD_IDENTITY_INFO = 821,
|
||||||
SWITCH_CAUSE_UNSUPPORTED_CERTIFICATE = 822,
|
SWITCH_CAUSE_UNSUPPORTED_CERTIFICATE = 822,
|
||||||
SWITCH_CAUSE_INVALID_IDENTITY = 823,
|
SWITCH_CAUSE_INVALID_IDENTITY = 823,
|
||||||
SWITCH_CAUSE_STALE_DATE = 824
|
SWITCH_CAUSE_STALE_DATE = 824,
|
||||||
|
SWITCH_CAUSE_REJECT_ALL = 825
|
||||||
} switch_call_cause_t;
|
} switch_call_cause_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -2424,6 +2425,7 @@ typedef enum {
|
||||||
SCC_VIDEO_RESET,
|
SCC_VIDEO_RESET,
|
||||||
SCC_AUDIO_PACKET_LOSS,
|
SCC_AUDIO_PACKET_LOSS,
|
||||||
SCC_AUDIO_ADJUST_BITRATE,
|
SCC_AUDIO_ADJUST_BITRATE,
|
||||||
|
SCC_AUDIO_VAD,
|
||||||
SCC_DEBUG,
|
SCC_DEBUG,
|
||||||
SCC_CODEC_SPECIFIC
|
SCC_CODEC_SPECIFIC
|
||||||
} switch_codec_control_command_t;
|
} switch_codec_control_command_t;
|
||||||
|
@ -2654,10 +2656,12 @@ struct switch_live_array_s;
|
||||||
typedef struct switch_live_array_s switch_live_array_t;
|
typedef struct switch_live_array_s switch_live_array_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SDP_TYPE_REQUEST,
|
SDP_OFFER,
|
||||||
SDP_TYPE_RESPONSE
|
SDP_ANSWER
|
||||||
} switch_sdp_type_t;
|
} switch_sdp_type_t;
|
||||||
|
|
||||||
|
#define SDP_TYPE_REQUEST SDP_OFFER
|
||||||
|
#define SDP_TYPE_RESPONSE SDP_ANSWER
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
AEAD_AES_256_GCM_8,
|
AEAD_AES_256_GCM_8,
|
||||||
|
|
|
@ -498,6 +498,14 @@ SWITCH_DECLARE(switch_size_t) switch_fp_read_dline(FILE *fd, char **buf, switch_
|
||||||
SWITCH_DECLARE(switch_status_t) switch_frame_alloc(switch_frame_t **frame, switch_size_t size);
|
SWITCH_DECLARE(switch_status_t) switch_frame_alloc(switch_frame_t **frame, switch_size_t size);
|
||||||
SWITCH_DECLARE(switch_status_t) switch_frame_dup(switch_frame_t *orig, switch_frame_t **clone);
|
SWITCH_DECLARE(switch_status_t) switch_frame_dup(switch_frame_t *orig, switch_frame_t **clone);
|
||||||
SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame);
|
SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame);
|
||||||
|
|
||||||
|
/*! \brief Check if a 32 bit unsigned number is in a range.
|
||||||
|
* \param str string to check. Should not contain non-digit characters.
|
||||||
|
* \param from start of range including this number
|
||||||
|
* \param to end of range including this number
|
||||||
|
* \return true or false
|
||||||
|
*/
|
||||||
|
SWITCH_DECLARE(switch_bool_t) switch_is_uint_in_range(const char *str, unsigned int from, unsigned int to);
|
||||||
SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str);
|
SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str);
|
||||||
SWITCH_DECLARE(switch_bool_t) switch_is_leading_number(const char *str);
|
SWITCH_DECLARE(switch_bool_t) switch_is_leading_number(const char *str);
|
||||||
SWITCH_DECLARE(char *) switch_find_parameter(const char *str, const char *param, switch_memory_pool_t *pool);
|
SWITCH_DECLARE(char *) switch_find_parameter(const char *str, const char *param, switch_memory_pool_t *pool);
|
||||||
|
|
|
@ -255,7 +255,7 @@ fctstr_safe_cpy(char *dst, char const *src, size_t num)
|
||||||
#if defined(WIN32) && _MSC_VER >= 1400
|
#if defined(WIN32) && _MSC_VER >= 1400
|
||||||
strncpy_s(dst, num, src, _TRUNCATE);
|
strncpy_s(dst, num, src, _TRUNCATE);
|
||||||
#else
|
#else
|
||||||
strncpy(dst, src, num);
|
strncpy(dst, src, num - 1);
|
||||||
#endif
|
#endif
|
||||||
dst[num-1] = '\0';
|
dst[num-1] = '\0';
|
||||||
}
|
}
|
||||||
|
@ -760,6 +760,7 @@ fct_nlist__init2(fct_nlist_t *list, size_t start_sz)
|
||||||
list->itm_list = (void**)malloc(sizeof(void*)*start_sz);
|
list->itm_list = (void**)malloc(sizeof(void*)*start_sz);
|
||||||
if ( list->itm_list == NULL )
|
if ( list->itm_list == NULL )
|
||||||
{
|
{
|
||||||
|
list->used_itm_num = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
* Seven Du <dujinfang@gmail.com>
|
* Seven Du <dujinfang@gmail.com>
|
||||||
* Anthony Minessale <anthm@freeswitch.org>
|
* Anthony Minessale <anthm@freeswitch.org>
|
||||||
* Emmanuel Schmidbauer <eschmidbauer@gmail.com>
|
* Emmanuel Schmidbauer <eschmidbauer@gmail.com>
|
||||||
|
* Jakub Karolczyk <jakub.karolczyk@signalwire.com>
|
||||||
*
|
*
|
||||||
* mod_avcodec -- Codec with libav.org and ffmpeg
|
* mod_avcodec -- Codec with libav.org and ffmpeg
|
||||||
*
|
*
|
||||||
|
@ -34,6 +35,9 @@
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include "mod_av.h"
|
#include "mod_av.h"
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <libavcodec/version.h> /* LIBAVCODEC_VERSION_INT */
|
||||||
|
#endif
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
#include <libavutil/opt.h>
|
#include <libavutil/opt.h>
|
||||||
#include <libavutil/imgutils.h>
|
#include <libavutil/imgutils.h>
|
||||||
|
@ -373,8 +377,13 @@ typedef struct our_h264_nalu_s {
|
||||||
|
|
||||||
typedef struct h264_codec_context_s {
|
typedef struct h264_codec_context_s {
|
||||||
switch_buffer_t *nalu_buffer;
|
switch_buffer_t *nalu_buffer;
|
||||||
|
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||||
AVCodec *decoder;
|
AVCodec *decoder;
|
||||||
AVCodec *encoder;
|
AVCodec *encoder;
|
||||||
|
#else
|
||||||
|
const AVCodec *decoder;
|
||||||
|
const AVCodec *encoder;
|
||||||
|
#endif
|
||||||
AVCodecContext *decoder_ctx;
|
AVCodecContext *decoder_ctx;
|
||||||
int got_pps; /* if pps packet received */
|
int got_pps; /* if pps packet received */
|
||||||
int64_t pts;
|
int64_t pts;
|
||||||
|
@ -393,12 +402,13 @@ typedef struct h264_codec_context_s {
|
||||||
switch_codec_settings_t codec_settings;
|
switch_codec_settings_t codec_settings;
|
||||||
AVCodecContext *encoder_ctx;
|
AVCodecContext *encoder_ctx;
|
||||||
AVFrame *encoder_avframe;
|
AVFrame *encoder_avframe;
|
||||||
AVPacket encoder_avpacket;
|
AVPacket *encoder_avpacket;
|
||||||
AVFrame *decoder_avframe;
|
AVFrame *decoder_avframe;
|
||||||
our_h264_nalu_t nalus[MAX_NALUS];
|
our_h264_nalu_t nalus[MAX_NALUS];
|
||||||
enum AVCodecID av_codec_id;
|
enum AVCodecID av_codec_id;
|
||||||
uint16_t last_seq; // last received frame->seq
|
uint16_t last_seq; // last received frame->seq
|
||||||
int hw_encoder;
|
int hw_encoder;
|
||||||
|
switch_packetizer_t *packetizer;
|
||||||
} h264_codec_context_t;
|
} h264_codec_context_t;
|
||||||
|
|
||||||
#ifndef AV_INPUT_BUFFER_PADDING_SIZE
|
#ifndef AV_INPUT_BUFFER_PADDING_SIZE
|
||||||
|
@ -825,7 +835,11 @@ static void fs_rtp_parse_h263_rfc2190(h264_codec_context_t *context, AVPacket *p
|
||||||
const uint8_t *p = buf;
|
const uint8_t *p = buf;
|
||||||
const uint8_t *buf_base = buf;
|
const uint8_t *buf_base = buf;
|
||||||
uint32_t code = (ntohl(*(uint32_t *)buf) & 0xFFFFFC00) >> 10;
|
uint32_t code = (ntohl(*(uint32_t *)buf) & 0xFFFFFC00) >> 10;
|
||||||
|
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||||
int mb_info_size = 0;
|
int mb_info_size = 0;
|
||||||
|
#else
|
||||||
|
switch_size_t mb_info_size = 0;
|
||||||
|
#endif
|
||||||
int mb_info_pos = 0, mb_info_count = 0;
|
int mb_info_pos = 0, mb_info_count = 0;
|
||||||
const uint8_t *mb_info;
|
const uint8_t *mb_info;
|
||||||
|
|
||||||
|
@ -889,7 +903,11 @@ static void fs_rtp_parse_h263_rfc2190(h264_codec_context_t *context, AVPacket *p
|
||||||
"Unable to split H263 packet! mb_info_pos=%d mb_info_count=%d pos=%d max=%"SWITCH_SIZE_T_FMT"\n", mb_info_pos, mb_info_count, pos, (switch_size_t)(end - buf_base));
|
"Unable to split H263 packet! mb_info_pos=%d mb_info_count=%d pos=%d max=%"SWITCH_SIZE_T_FMT"\n", mb_info_pos, mb_info_count, pos, (switch_size_t)(end - buf_base));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%d\n", mb_info_pos, mb_info_count, mb_info_size);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%d\n", mb_info_pos, mb_info_count, mb_info_size);
|
||||||
|
#else
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%ld\n", mb_info_pos, mb_info_count, mb_info_size);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1033,7 +1051,7 @@ static switch_status_t consume_h263_bitstream(h264_codec_context_t *context, swi
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!context->nalus[context->nalu_current_index].len) {
|
if (!context->nalus[context->nalu_current_index].len) {
|
||||||
av_packet_unref(&context->encoder_avpacket);
|
av_packet_unref(context->encoder_avpacket);
|
||||||
frame->m = 1;
|
frame->m = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1081,81 +1099,27 @@ static switch_status_t consume_h263p_bitstream(h264_codec_context_t *context, sw
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (frame->m) {
|
if (frame->m) {
|
||||||
av_packet_unref(&context->encoder_avpacket);
|
av_packet_unref(context->encoder_avpacket);
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_MORE_DATA;
|
return SWITCH_STATUS_MORE_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static switch_status_t consume_h264_bitstream(h264_codec_context_t *context, switch_frame_t *frame)
|
|
||||||
{
|
|
||||||
AVPacket *pkt = &context->encoder_avpacket;
|
|
||||||
our_h264_nalu_t *nalu = &context->nalus[context->nalu_current_index];
|
|
||||||
uint8_t nalu_hdr = *(uint8_t *)(nalu->start);
|
|
||||||
uint8_t nalu_type = nalu_hdr & 0x1f;
|
|
||||||
uint8_t nri = nalu_hdr & 0x60;
|
|
||||||
int left = nalu->len - (nalu->eat - nalu->start);
|
|
||||||
uint8_t *p = frame->data;
|
|
||||||
uint8_t start = nalu->start == nalu->eat ? 0x80 : 0;
|
|
||||||
int n = nalu->len / SLICE_SIZE;
|
|
||||||
int slice_size = nalu->len / (n + 1) + 1 + 2;
|
|
||||||
|
|
||||||
if (nalu->len <= SLICE_SIZE) {
|
|
||||||
memcpy(frame->data, nalu->start, nalu->len);
|
|
||||||
frame->datalen = nalu->len;
|
|
||||||
context->nalu_current_index++;
|
|
||||||
|
|
||||||
if (context->nalus[context->nalu_current_index].len) {
|
|
||||||
frame->m = 0;
|
|
||||||
return SWITCH_STATUS_MORE_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pkt->size > 0) av_packet_unref(pkt);
|
|
||||||
|
|
||||||
switch_clear_flag(frame, SFF_CNG);
|
|
||||||
frame->m = 1;
|
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (left <= (slice_size - 2)) {
|
|
||||||
p[0] = nri | 28; // FU-A
|
|
||||||
p[1] = 0x40 | nalu_type;
|
|
||||||
memcpy(p+2, nalu->eat, left);
|
|
||||||
nalu->eat += left;
|
|
||||||
frame->datalen = left + 2;
|
|
||||||
context->nalu_current_index++;
|
|
||||||
|
|
||||||
if (!context->nalus[context->nalu_current_index].len) {
|
|
||||||
if (pkt->size > 0) av_packet_unref(pkt);
|
|
||||||
frame->m = 1;
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SWITCH_STATUS_MORE_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
p[0] = nri | 28; // FU-A
|
|
||||||
p[1] = start | nalu_type;
|
|
||||||
if (start) nalu->eat++;
|
|
||||||
memcpy(p+2, nalu->eat, slice_size - 2);
|
|
||||||
nalu->eat += (slice_size - 2);
|
|
||||||
frame->datalen = slice_size;
|
|
||||||
frame->m = 0;
|
|
||||||
return SWITCH_STATUS_MORE_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_t *frame)
|
static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_t *frame)
|
||||||
{
|
{
|
||||||
AVPacket *pkt = &context->encoder_avpacket;
|
AVPacket *pkt = context->encoder_avpacket;
|
||||||
our_h264_nalu_t *nalu = &context->nalus[context->nalu_current_index];
|
our_h264_nalu_t *nalu = &context->nalus[context->nalu_current_index];
|
||||||
|
|
||||||
if (!nalu->len) {
|
if (!nalu->len) {
|
||||||
frame->datalen = 0;
|
frame->datalen = 0;
|
||||||
frame->m = 0;
|
frame->m = 0;
|
||||||
if (pkt->size > 0) av_packet_unref(pkt);
|
if (pkt->size > 0) {
|
||||||
|
av_packet_unref(pkt);
|
||||||
|
}
|
||||||
|
|
||||||
context->nalu_current_index = 0;
|
context->nalu_current_index = 0;
|
||||||
|
|
||||||
return SWITCH_STATUS_NOTFOUND;
|
return SWITCH_STATUS_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1167,7 +1131,9 @@ static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_
|
||||||
return consume_h263p_bitstream(context, frame);
|
return consume_h263p_bitstream(context, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
return consume_h264_bitstream(context, frame);
|
switch_assert(0);
|
||||||
|
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_h264_private_data(h264_codec_context_t *context, avcodec_profile_t *profile)
|
static void set_h264_private_data(h264_codec_context_t *context, avcodec_profile_t *profile)
|
||||||
|
@ -1342,9 +1308,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||||
set_h264_private_data(context, aprofile);
|
set_h264_private_data(context, aprofile);
|
||||||
}
|
}
|
||||||
|
|
||||||
GCC_DIAG_OFF(deprecated-declarations)
|
|
||||||
avcodec_string(codec_string, sizeof(codec_string), context->encoder_ctx, 0);
|
avcodec_string(codec_string, sizeof(codec_string), context->encoder_ctx, 0);
|
||||||
GCC_DIAG_ON(deprecated-declarations)
|
|
||||||
|
|
||||||
dump_encoder_ctx(context->encoder_ctx);
|
dump_encoder_ctx(context->encoder_ctx);
|
||||||
|
|
||||||
|
@ -1436,6 +1400,16 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (context->av_codec_id) {
|
||||||
|
case AV_CODEC_ID_H264:
|
||||||
|
context->packetizer = switch_packetizer_create(SPT_H264_BITSTREAM, SLICE_SIZE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
context->encoder_avpacket = av_packet_alloc();
|
||||||
|
|
||||||
switch_buffer_create_dynamic(&(context->nalu_buffer), H264_NALU_BUFFER_SIZE, H264_NALU_BUFFER_SIZE * 8, 0);
|
switch_buffer_create_dynamic(&(context->nalu_buffer), H264_NALU_BUFFER_SIZE, H264_NALU_BUFFER_SIZE * 8, 0);
|
||||||
codec->private_info = context;
|
codec->private_info = context;
|
||||||
|
|
||||||
|
@ -1460,7 +1434,7 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
||||||
int ret;
|
int ret;
|
||||||
int *got_output = &context->got_encoded_output;
|
int *got_output = &context->got_encoded_output;
|
||||||
AVFrame *avframe = NULL;
|
AVFrame *avframe = NULL;
|
||||||
AVPacket *pkt = &context->encoder_avpacket;
|
AVPacket **pkt = &context->encoder_avpacket;
|
||||||
uint32_t width = 0;
|
uint32_t width = 0;
|
||||||
uint32_t height = 0;
|
uint32_t height = 0;
|
||||||
switch_image_t *img = frame->img;
|
switch_image_t *img = frame->img;
|
||||||
|
@ -1480,6 +1454,16 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame->flags & SFF_SAME_IMAGE) {
|
if (frame->flags & SFF_SAME_IMAGE) {
|
||||||
|
if (context->packetizer) {
|
||||||
|
switch_status_t status = switch_packetizer_read(context->packetizer, frame);
|
||||||
|
|
||||||
|
if (status == SWITCH_STATUS_SUCCESS && (*pkt)->size > 0) {
|
||||||
|
av_packet_unref(*pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
// read from nalu buffer
|
// read from nalu buffer
|
||||||
return consume_nalu(context, frame);
|
return consume_nalu(context, frame);
|
||||||
}
|
}
|
||||||
|
@ -1489,6 +1473,7 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
||||||
if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) {
|
if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
avctx = context->encoder_ctx;
|
avctx = context->encoder_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1498,6 +1483,7 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
||||||
if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) {
|
if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
avctx = context->encoder_ctx;
|
avctx = context->encoder_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1507,13 +1493,13 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
||||||
if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) {
|
if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
avctx = context->encoder_ctx;
|
avctx = context->encoder_ctx;
|
||||||
switch_set_flag(frame, SFF_WAIT_KEY_FRAME);
|
switch_set_flag(frame, SFF_WAIT_KEY_FRAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
av_init_packet(pkt);
|
av_packet_unref(*pkt);
|
||||||
pkt->data = NULL; // packet data will be allocated by the encoder
|
/* packet data will be allocated by the encoder */
|
||||||
pkt->size = 0;
|
|
||||||
|
|
||||||
avframe = context->encoder_avframe;
|
avframe = context->encoder_avframe;
|
||||||
|
|
||||||
|
@ -1578,14 +1564,42 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
||||||
/* encode the image */
|
/* encode the image */
|
||||||
memset(context->nalus, 0, sizeof(context->nalus));
|
memset(context->nalus, 0, sizeof(context->nalus));
|
||||||
context->nalu_current_index = 0;
|
context->nalu_current_index = 0;
|
||||||
|
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||||
GCC_DIAG_OFF(deprecated-declarations)
|
GCC_DIAG_OFF(deprecated-declarations)
|
||||||
ret = avcodec_encode_video2(avctx, pkt, avframe, got_output);
|
ret = avcodec_encode_video2(avctx, *pkt, avframe, got_output);
|
||||||
GCC_DIAG_ON(deprecated-declarations)
|
GCC_DIAG_ON(deprecated-declarations)
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoding Error %d\n", ret);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoding Error %d\n", ret);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
ret = avcodec_send_frame(avctx, avframe);
|
||||||
|
|
||||||
|
if (ret == AVERROR_EOF) {
|
||||||
|
ret = 0;
|
||||||
|
} else if (ret == AVERROR(EAGAIN)) {
|
||||||
|
/* we fully drain all the output in each encode call, so this should not ever happen */
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending frame to encoder - BUG, should never happen\n");
|
||||||
|
ret = AVERROR_BUG;
|
||||||
|
goto error;
|
||||||
|
} else if (ret < 0) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending frame to encoder\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ret >= 0) {
|
||||||
|
ret = avcodec_receive_packet(avctx, *pkt);
|
||||||
|
if (ret == AVERROR(EAGAIN)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video packets at the moment\n");
|
||||||
|
} else if (ret == AVERROR_EOF) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video packets at all\n");
|
||||||
|
} else if (ret < 0) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoding error\n");
|
||||||
|
av_packet_unref(*pkt);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (context->need_key_frame && avframe->key_frame == 1) {
|
if (context->need_key_frame && avframe->key_frame == 1) {
|
||||||
avframe->pict_type = 0;
|
avframe->pict_type = 0;
|
||||||
|
@ -1595,81 +1609,78 @@ GCC_DIAG_ON(deprecated-declarations)
|
||||||
|
|
||||||
// process:
|
// process:
|
||||||
|
|
||||||
|
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||||
if (*got_output) {
|
if (*got_output) {
|
||||||
const uint8_t *p = pkt->data;
|
#else
|
||||||
int i = 0;
|
if (ret >= 0) {
|
||||||
|
#endif
|
||||||
|
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||||
|
|
||||||
*got_output = 0;
|
*got_output = 0;
|
||||||
|
|
||||||
if (context->av_codec_id == AV_CODEC_ID_H263) {
|
if (context->av_codec_id == AV_CODEC_ID_H263) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5,
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5,
|
||||||
"Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) [0x%02x 0x%02x 0x%02x 0x%02x] got_output: %d slices: %d\n",
|
"Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) [0x%02x 0x%02x 0x%02x 0x%02x] got_output: %d slices: %d\n",
|
||||||
context->pts, pkt->size, *((uint8_t *)pkt->data), *((uint8_t *)(pkt->data + 1)), *((uint8_t *)(pkt->data + 2)),
|
context->pts, (*pkt)->size, *((uint8_t *)(*pkt)->data), *((uint8_t *)((*pkt)->data + 1)), *((uint8_t *)((*pkt)->data + 2)),
|
||||||
*((uint8_t *)(pkt->data + 3)), *got_output, avctx->slices);
|
*((uint8_t *)((*pkt)->data + 3)), *got_output, avctx->slices);
|
||||||
|
|
||||||
#ifdef H263_MODE_B
|
#ifdef H263_MODE_B
|
||||||
fs_rtp_parse_h263_rfc2190(context, pkt);
|
fs_rtp_parse_h263_rfc2190(context, *pkt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
context->nalu_current_index = 0;
|
context->nalu_current_index = 0;
|
||||||
|
|
||||||
return consume_nalu(context, frame);
|
return consume_nalu(context, frame);
|
||||||
} else if (context->av_codec_id == AV_CODEC_ID_H263P){
|
} else if (context->av_codec_id == AV_CODEC_ID_H263P){
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5,
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5,
|
||||||
"Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) [0x%02x 0x%02x 0x%02x 0x%02x] got_output: %d slices: %d\n",
|
"Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) [0x%02x 0x%02x 0x%02x 0x%02x] got_output: %d slices: %d\n",
|
||||||
context->pts, pkt->size, *((uint8_t *)pkt->data), *((uint8_t *)(pkt->data + 1)), *((uint8_t *)(pkt->data + 2)),
|
context->pts, (*pkt)->size, *((uint8_t *)(*pkt)->data), *((uint8_t *)((*pkt)->data + 1)), *((uint8_t *)((*pkt)->data + 2)),
|
||||||
*((uint8_t *)(pkt->data + 3)), *got_output, avctx->slices);
|
*((uint8_t *)((*pkt)->data + 3)), *got_output, avctx->slices);
|
||||||
fs_rtp_parse_h263_rfc4629(context, pkt);
|
fs_rtp_parse_h263_rfc4629(context, *pkt);
|
||||||
context->nalu_current_index = 0;
|
context->nalu_current_index = 0;
|
||||||
|
|
||||||
return consume_nalu(context, frame);
|
return consume_nalu(context, frame);
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5,
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5,
|
||||||
"Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) nalu_type=0x%x %d\n",
|
"Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) nalu_type=0x%x %d\n",
|
||||||
context->pts, pkt->size, *((uint8_t *)pkt->data +4), *got_output);
|
context->pts, (*pkt)->size, *((uint8_t *)(*pkt)->data +4), *got_output);
|
||||||
}
|
|
||||||
/* split into nalus */
|
|
||||||
memset(context->nalus, 0, sizeof(context->nalus));
|
|
||||||
|
|
||||||
while ((p = fs_avc_find_startcode(p, pkt->data+pkt->size)) < (pkt->data + pkt->size)) {
|
|
||||||
if (!context->nalus[i].start) {
|
|
||||||
while (!(*p++)) ; /* eat the sync bytes, what ever 0 0 1 or 0 0 0 1 */
|
|
||||||
context->nalus[i].start = p;
|
|
||||||
context->nalus[i].eat = p;
|
|
||||||
|
|
||||||
if ((*p & 0x1f) == 7) { // Got Keyframe
|
|
||||||
// prevent to generate key frame too frequently
|
|
||||||
context->last_keyframe_request = switch_time_now();
|
|
||||||
if (mod_av_globals.debug) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "KEY FRAME GENERATED\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
context->nalus[i].len = p - context->nalus[i].start;
|
|
||||||
while (!(*p++)) ; /* eat the sync bytes, what ever 0 0 1 or 0 0 0 1 */
|
|
||||||
i++;
|
|
||||||
context->nalus[i].start = p;
|
|
||||||
context->nalus[i].eat = p;
|
|
||||||
}
|
|
||||||
if (i >= MAX_NALUS - 2) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TOO MANY SLICES!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context->nalus[i].len = p - context->nalus[i].start;
|
status = switch_packetizer_feed(context->packetizer, (*pkt)->data, (*pkt)->size);
|
||||||
context->nalu_current_index = 0;
|
if (status != SWITCH_STATUS_SUCCESS) {
|
||||||
return consume_nalu(context, frame);
|
if ((*pkt)->size > 0) {
|
||||||
|
av_packet_unref(*pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = switch_packetizer_read(context->packetizer, frame);
|
||||||
|
if (status == SWITCH_STATUS_SUCCESS && (*pkt)->size > 0) {
|
||||||
|
av_packet_unref(*pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
error:
|
error:
|
||||||
frame->datalen = 0;
|
frame->datalen = 0;
|
||||||
|
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t *frame)
|
static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t *frame)
|
||||||
{
|
{
|
||||||
h264_codec_context_t *context = (h264_codec_context_t *)codec->private_info;
|
h264_codec_context_t *context = (h264_codec_context_t *)codec->private_info;
|
||||||
AVCodecContext *avctx= context->decoder_ctx;
|
|
||||||
switch_status_t status;
|
switch_status_t status;
|
||||||
|
#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V)
|
||||||
|
int ret = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch_assert(frame);
|
switch_assert(frame);
|
||||||
|
|
||||||
|
@ -1702,27 +1713,57 @@ static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t
|
||||||
|
|
||||||
if (frame->m) {
|
if (frame->m) {
|
||||||
uint32_t size = switch_buffer_inuse(context->nalu_buffer);
|
uint32_t size = switch_buffer_inuse(context->nalu_buffer);
|
||||||
AVPacket pkt = { 0 };
|
AVPacket *pkt = NULL;
|
||||||
AVFrame *picture;
|
AVFrame *picture;
|
||||||
|
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||||
int got_picture = 0;
|
int got_picture = 0;
|
||||||
int decoded_len;
|
int decoded_len;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
av_init_packet(&pkt);
|
pkt = av_packet_alloc();
|
||||||
switch_buffer_zero_fill(context->nalu_buffer, AV_INPUT_BUFFER_PADDING_SIZE);
|
switch_buffer_zero_fill(context->nalu_buffer, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
switch_buffer_peek_zerocopy(context->nalu_buffer, (const void **)&pkt.data);
|
switch_buffer_peek_zerocopy(context->nalu_buffer, (const void **)&pkt->data);
|
||||||
pkt.size = size;
|
pkt->size = size;
|
||||||
|
|
||||||
if (!context->decoder_avframe) context->decoder_avframe = av_frame_alloc();
|
if (!context->decoder_avframe) context->decoder_avframe = av_frame_alloc();
|
||||||
picture = context->decoder_avframe;
|
picture = context->decoder_avframe;
|
||||||
switch_assert(picture);
|
switch_assert(picture);
|
||||||
|
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||||
GCC_DIAG_OFF(deprecated-declarations)
|
GCC_DIAG_OFF(deprecated-declarations)
|
||||||
decoded_len = avcodec_decode_video2(avctx, picture, &got_picture, &pkt);
|
decoded_len = avcodec_decode_video2(context->decoder_ctx, picture, &got_picture, pkt);
|
||||||
GCC_DIAG_ON(deprecated-declarations)
|
GCC_DIAG_ON(deprecated-declarations)
|
||||||
|
#else
|
||||||
|
ret = avcodec_send_packet(context->decoder_ctx, pkt);
|
||||||
|
|
||||||
|
if (ret == AVERROR_EOF) {
|
||||||
|
ret = 0;
|
||||||
|
} else if (ret == AVERROR(EAGAIN)) {
|
||||||
|
/* we fully drain all the output in each decode call, so this should not ever happen */
|
||||||
|
ret = AVERROR_BUG;
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Error sending packet to decoder BUG, should never happen\n");
|
||||||
|
} else if (ret < 0) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Error sending packet to decoder\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ret >= 0) {
|
||||||
|
ret = avcodec_receive_frame(context->decoder_ctx, picture);
|
||||||
|
if (ret == AVERROR(EAGAIN)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video frames at the moment\n");
|
||||||
|
} else if (ret == AVERROR_EOF) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video frames at all\n");
|
||||||
|
} else if (ret < 0) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Video decoding error\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffer: %d got pic: %d len: %d [%dx%d]\n", size, got_picture, decoded_len, picture->width, picture->height);
|
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffer: %d got pic: %d len: %d [%dx%d]\n", size, got_picture, decoded_len, picture->width, picture->height);
|
||||||
|
|
||||||
|
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||||
if (got_picture && decoded_len > 0) {
|
if (got_picture && decoded_len > 0) {
|
||||||
|
#else
|
||||||
|
if (ret >= 0) {
|
||||||
|
#endif
|
||||||
int width = picture->width;
|
int width = picture->width;
|
||||||
int height = picture->height;
|
int height = picture->height;
|
||||||
|
|
||||||
|
@ -1744,7 +1785,15 @@ GCC_DIAG_ON(deprecated-declarations)
|
||||||
frame->img = context->img;
|
frame->img = context->img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V)
|
||||||
|
if (ret < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
av_frame_unref(picture);
|
av_frame_unref(picture);
|
||||||
|
av_packet_free(&pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_buffer_zero(context->nalu_buffer);
|
switch_buffer_zero(context->nalu_buffer);
|
||||||
|
@ -1825,6 +1874,10 @@ static switch_status_t switch_h264_destroy(switch_codec_t *codec)
|
||||||
av_free(context->encoder_ctx);
|
av_free(context->encoder_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context->packetizer) {
|
||||||
|
switch_packetizer_close(&context->packetizer);
|
||||||
|
}
|
||||||
|
|
||||||
if (context->encoder_avframe) {
|
if (context->encoder_avframe) {
|
||||||
av_frame_free(&context->encoder_avframe);
|
av_frame_free(&context->encoder_avframe);
|
||||||
}
|
}
|
||||||
|
@ -1833,6 +1886,10 @@ static switch_status_t switch_h264_destroy(switch_codec_t *codec)
|
||||||
av_frame_free(&context->decoder_avframe);
|
av_frame_free(&context->decoder_avframe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context->encoder_avpacket) {
|
||||||
|
av_packet_free(&context->encoder_avpacket);
|
||||||
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1860,8 +1917,10 @@ static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev,
|
||||||
#endif
|
#endif
|
||||||
if (prev->id == id &&
|
if (prev->id == id &&
|
||||||
(encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev)))
|
(encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev)))
|
||||||
|
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2208,7 +2267,7 @@ static void parse_codecs(avcodec_profile_t *aprofile, switch_xml_t codecs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void load_config()
|
static void load_config(void)
|
||||||
{
|
{
|
||||||
switch_xml_t cfg = NULL, xml = NULL;
|
switch_xml_t cfg = NULL, xml = NULL;
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -25,6 +25,7 @@
|
||||||
*
|
*
|
||||||
* Seven Du <dujinfang@gmail.com>
|
* Seven Du <dujinfang@gmail.com>
|
||||||
* Anthony Minessale <anthm@freeswitch.org>
|
* Anthony Minessale <anthm@freeswitch.org>
|
||||||
|
* Jakub Karolczyk <jakub.karolczyk@signalwire.com>
|
||||||
*
|
*
|
||||||
* mod_av -- FS Video Codec / File Format using libav.org
|
* mod_av -- FS Video Codec / File Format using libav.org
|
||||||
*
|
*
|
||||||
|
@ -33,7 +34,13 @@
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include "mod_av.h"
|
#include "mod_av.h"
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <libavcodec/version.h> /* LIBAVCODEC_VERSION_INT */
|
||||||
|
#endif
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <libavformat/version.h> /* LIBAVFORMAT_VERSION_INT */
|
||||||
|
#endif
|
||||||
|
|
||||||
SWITCH_MODULE_LOAD_FUNCTION(mod_avformat_load);
|
SWITCH_MODULE_LOAD_FUNCTION(mod_avformat_load);
|
||||||
SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load);
|
SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load);
|
||||||
|
@ -49,6 +56,7 @@ typedef struct av_mutex_helper_s {
|
||||||
switch_memory_pool_t *pool;
|
switch_memory_pool_t *pool;
|
||||||
} av_mutex_helper_t;
|
} av_mutex_helper_t;
|
||||||
|
|
||||||
|
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||||
int mod_av_lockmgr_cb(void **m, enum AVLockOp op)
|
int mod_av_lockmgr_cb(void **m, enum AVLockOp op)
|
||||||
{
|
{
|
||||||
av_mutex_helper_t *context = NULL;
|
av_mutex_helper_t *context = NULL;
|
||||||
|
@ -93,6 +101,7 @@ int mod_av_lockmgr_cb(void **m, enum AVLockOp op)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef AV_LOG_TRACE
|
#ifndef AV_LOG_TRACE
|
||||||
#define AV_LOG_TRACE 96
|
#define AV_LOG_TRACE 96
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
|
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
|
||||||
* Raymond Chandler <intralanman@gmail.com>
|
* Raymond Chandler <intralanman@gmail.com>
|
||||||
* Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
|
* Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
|
||||||
|
* Jakub Karolczyk <jakub.karolczyk@signalwire.com>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* mod_av.h -- LibAV mod
|
* mod_av.h -- LibAV mod
|
||||||
|
@ -39,6 +40,10 @@
|
||||||
#ifndef MOD_AV_H
|
#ifndef MOD_AV_H
|
||||||
#define MOD_AV_H
|
#define MOD_AV_H
|
||||||
|
|
||||||
|
#define LIBAVCODEC_V 59
|
||||||
|
#define LIBAVFORMAT_V 59
|
||||||
|
#define LIBAVUTIL_V 57
|
||||||
|
|
||||||
struct mod_av_globals {
|
struct mod_av_globals {
|
||||||
int debug;
|
int debug;
|
||||||
};
|
};
|
||||||
|
|
|
@ -86,7 +86,6 @@ typedef union {
|
||||||
static uint32_t index_from_float(float f);
|
static uint32_t index_from_float(float f);
|
||||||
static float float_from_index(uint32_t d);
|
static float float_from_index(uint32_t d);
|
||||||
static float *acos_table = NULL;
|
static float *acos_table = NULL;
|
||||||
static int acos_fd = -1;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef FAST_ACOSF_TESTING
|
#ifdef FAST_ACOSF_TESTING
|
||||||
|
@ -112,6 +111,10 @@ extern int compute_table(void)
|
||||||
|
|
||||||
acos_table_file = fopen(ACOS_TABLE_FILENAME, "w");
|
acos_table_file = fopen(ACOS_TABLE_FILENAME, "w");
|
||||||
|
|
||||||
|
if (!acos_table_file) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < ACOS_TABLE_LENGTH; i++) {
|
for (i = 0; i < ACOS_TABLE_LENGTH; i++) {
|
||||||
f = acosf(float_from_index(i));
|
f = acosf(float_from_index(i));
|
||||||
res = fwrite(&f, sizeof(f), 1, acos_table_file);
|
res = fwrite(&f, sizeof(f), 1, acos_table_file);
|
||||||
|
@ -124,10 +127,12 @@ extern int compute_table(void)
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
fclose(acos_table_file);
|
fclose(acos_table_file);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,8 +149,9 @@ extern int init_fast_acosf(void)
|
||||||
* or some other error occured */
|
* or some other error occured */
|
||||||
errsv = errno;
|
errsv = errno;
|
||||||
strerror_r(errsv, err, 150);
|
strerror_r(errsv, err, 150);
|
||||||
if (errsv != ENOENT) return -1;
|
if (errsv != ENOENT) {
|
||||||
else {
|
return -1;
|
||||||
|
} else {
|
||||||
switch_log_printf(
|
switch_log_printf(
|
||||||
SWITCH_CHANNEL_LOG,
|
SWITCH_CHANNEL_LOG,
|
||||||
SWITCH_LOG_NOTICE,
|
SWITCH_LOG_NOTICE,
|
||||||
|
@ -166,10 +172,10 @@ extern int init_fast_acosf(void)
|
||||||
acos_fp = fopen(ACOS_TABLE_FILENAME, "r");
|
acos_fp = fopen(ACOS_TABLE_FILENAME, "r");
|
||||||
if (acos_fp == NULL) return -3;
|
if (acos_fp == NULL) return -3;
|
||||||
/* can't fail */
|
/* can't fail */
|
||||||
acos_fd = fileno(acos_fp);
|
|
||||||
acos_table = (float *) mmap(
|
acos_table = (float *) mmap(
|
||||||
NULL, /* kernel chooses the address at which to create the mapping */
|
NULL, /* kernel chooses the address at which to create the mapping */
|
||||||
ACOS_TABLE_LENGTH * sizeof(float), PROT_READ, MAP_SHARED, acos_fd, 0);
|
ACOS_TABLE_LENGTH * sizeof(float), PROT_READ, MAP_SHARED, fileno(acos_fp), 0);
|
||||||
|
fclose(acos_fp);
|
||||||
if (acos_table == MAP_FAILED) return -4;
|
if (acos_table == MAP_FAILED) return -4;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -178,9 +184,7 @@ extern int init_fast_acosf(void)
|
||||||
extern int destroy_fast_acosf(void)
|
extern int destroy_fast_acosf(void)
|
||||||
{
|
{
|
||||||
if (munmap(acos_table, ACOS_TABLE_LENGTH) == -1) return -1;
|
if (munmap(acos_table, ACOS_TABLE_LENGTH) == -1) return -1;
|
||||||
if (acos_fd != -1) {
|
|
||||||
if (close(acos_fd) == -1) return -2;
|
|
||||||
}
|
|
||||||
/* disable use of fast arc cosine file */
|
/* disable use of fast arc cosine file */
|
||||||
acos_table = NULL;
|
acos_table = NULL;
|
||||||
|
|
||||||
|
|
|
@ -1138,6 +1138,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load) {
|
||||||
|
|
||||||
switch_application_interface_t *app_interface;
|
switch_application_interface_t *app_interface;
|
||||||
switch_api_interface_t *api_interface;
|
switch_api_interface_t *api_interface;
|
||||||
|
|
||||||
|
if (pool == NULL) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No memory pool assigned!\n");
|
||||||
|
|
||||||
|
return SWITCH_STATUS_TERM;
|
||||||
|
}
|
||||||
|
|
||||||
/* connect my internal structure to the blank pointer passed to me */
|
/* connect my internal structure to the blank pointer passed to me */
|
||||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||||
|
|
||||||
|
@ -1147,10 +1154,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load) {
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&avmd_globals, 0, sizeof(avmd_globals));
|
memset(&avmd_globals, 0, sizeof(avmd_globals));
|
||||||
if (pool == NULL) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No memory pool assigned!\n");
|
|
||||||
return SWITCH_STATUS_TERM;
|
|
||||||
}
|
|
||||||
switch_mutex_init(&avmd_globals.mutex, SWITCH_MUTEX_NESTED, pool);
|
switch_mutex_init(&avmd_globals.mutex, SWITCH_MUTEX_NESTED, pool);
|
||||||
avmd_globals.pool = pool;
|
avmd_globals.pool = pool;
|
||||||
|
|
||||||
|
@ -1622,9 +1625,6 @@ SWITCH_STANDARD_APP(avmd_start_function) {
|
||||||
|
|
||||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown) {
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown) {
|
||||||
size_t session_n;
|
size_t session_n;
|
||||||
#ifndef WIN32
|
|
||||||
int res;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch_mutex_lock(avmd_globals.mutex);
|
switch_mutex_lock(avmd_globals.mutex);
|
||||||
|
|
||||||
|
@ -1638,18 +1638,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown) {
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
if (avmd_globals.settings.fast_math == 1) {
|
if (avmd_globals.settings.fast_math == 1) {
|
||||||
res = destroy_fast_acosf();
|
if (destroy_fast_acosf()) {
|
||||||
if (res != 0) {
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed unmap arc cosine table\n");
|
||||||
switch (res) {
|
|
||||||
case -1:
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed unmap arc cosine table\n");
|
|
||||||
break;
|
|
||||||
case -2:
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed closing arc cosine table\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1658,6 +1648,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown) {
|
||||||
switch_mutex_unlock(avmd_globals.mutex);
|
switch_mutex_unlock(avmd_globals.mutex);
|
||||||
switch_mutex_destroy(avmd_globals.mutex);
|
switch_mutex_destroy(avmd_globals.mutex);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Advanced voicemail detection disabled\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Advanced voicemail detection disabled\n");
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -347,7 +347,7 @@ static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||||
return realsize;
|
return realsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, char **response, const char *query, struct curl_httppost *post,
|
static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, char **response, const char *query, switch_curl_mime *post,
|
||||||
switch_curl_slist_t *headers, int timeout)
|
switch_curl_slist_t *headers, int timeout)
|
||||||
{
|
{
|
||||||
switch_time_t start_time = switch_micro_time_now();
|
switch_time_t start_time = switch_micro_time_now();
|
||||||
|
@ -373,7 +373,7 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
|
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
|
||||||
}
|
}
|
||||||
if (post) {
|
if (post) {
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPPOST, post);
|
switch_curl_easy_setopt_mime(curl_handle, post);
|
||||||
} else {
|
} else {
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 1);
|
switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3225,6 +3225,7 @@ SWITCH_STANDARD_API(uuid_capture_text)
|
||||||
} else {
|
} else {
|
||||||
if ((tsession = switch_core_session_locate(uuid))) {
|
if ((tsession = switch_core_session_locate(uuid))) {
|
||||||
switch_ivr_capture_text(tsession, switch_true(onoff));
|
switch_ivr_capture_text(tsession, switch_true(onoff));
|
||||||
|
switch_core_session_rwunlock(tsession);
|
||||||
} else {
|
} else {
|
||||||
stream->write_function(stream, "-ERR No such channel %s!\n", uuid);
|
stream->write_function(stream, "-ERR No such channel %s!\n", uuid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4087,7 +4087,6 @@ switch_status_t conference_api_sub_set(conference_obj_t *conference,
|
||||||
|
|
||||||
switch_status_t conference_api_sub_xml_list(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
|
switch_status_t conference_api_sub_xml_list(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
|
||||||
{
|
{
|
||||||
int count = 0;
|
|
||||||
switch_hash_index_t *hi;
|
switch_hash_index_t *hi;
|
||||||
void *val;
|
void *val;
|
||||||
switch_xml_t x_conference, x_conferences;
|
switch_xml_t x_conference, x_conferences;
|
||||||
|
@ -4106,7 +4105,6 @@ switch_status_t conference_api_sub_xml_list(conference_obj_t *conference, switch
|
||||||
x_conference = switch_xml_add_child_d(x_conferences, "conference", off++);
|
x_conference = switch_xml_add_child_d(x_conferences, "conference", off++);
|
||||||
switch_assert(conference);
|
switch_assert(conference);
|
||||||
|
|
||||||
count++;
|
|
||||||
conference_xlist(conference, x_conference, off);
|
conference_xlist(conference, x_conference, off);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4114,7 +4112,7 @@ switch_status_t conference_api_sub_xml_list(conference_obj_t *conference, switch
|
||||||
} else {
|
} else {
|
||||||
x_conference = switch_xml_add_child_d(x_conferences, "conference", off++);
|
x_conference = switch_xml_add_child_d(x_conferences, "conference", off++);
|
||||||
switch_assert(conference);
|
switch_assert(conference);
|
||||||
count++;
|
|
||||||
conference_xlist(conference, x_conference, off);
|
conference_xlist(conference, x_conference, off);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -662,6 +662,9 @@ void conference_cdr_render(conference_obj_t *conference)
|
||||||
x_tag = switch_xml_add_child_d(x_flags, "end_conference", flag_off++);
|
x_tag = switch_xml_add_child_d(x_flags, "end_conference", flag_off++);
|
||||||
switch_xml_set_txt_d(x_tag, conference_cdr_test_mflag(np, MFLAG_ENDCONF) ? "true" : "false");
|
switch_xml_set_txt_d(x_tag, conference_cdr_test_mflag(np, MFLAG_ENDCONF) ? "true" : "false");
|
||||||
|
|
||||||
|
x_tag = switch_xml_add_child_d(x_flags, "mandatory_member_end_conference", flag_off++);
|
||||||
|
switch_xml_set_txt_d(x_tag, conference_cdr_test_mflag(np, MFLAG_MANDATORY_MEMBER_ENDCONF) ? "true" : "false");
|
||||||
|
|
||||||
x_tag = switch_xml_add_child_d(x_flags, "was_kicked", flag_off++);
|
x_tag = switch_xml_add_child_d(x_flags, "was_kicked", flag_off++);
|
||||||
switch_xml_set_txt_d(x_tag, conference_cdr_test_mflag(np, MFLAG_KICKED) ? "true" : "false");
|
switch_xml_set_txt_d(x_tag, conference_cdr_test_mflag(np, MFLAG_KICKED) ? "true" : "false");
|
||||||
|
|
||||||
|
@ -737,7 +740,7 @@ void conference_cdr_render(conference_obj_t *conference)
|
||||||
#endif
|
#endif
|
||||||
int wrote;
|
int wrote;
|
||||||
wrote = write(fd, xml_text, (unsigned) strlen(xml_text));
|
wrote = write(fd, xml_text, (unsigned) strlen(xml_text));
|
||||||
wrote++;
|
(void)wrote;
|
||||||
close(fd);
|
close(fd);
|
||||||
} else {
|
} else {
|
||||||
char ebuf[512] = { 0 };
|
char ebuf[512] = { 0 };
|
||||||
|
|
|
@ -75,7 +75,7 @@ struct _mapping control_mappings[] = {
|
||||||
{"deaf off", conference_loop_deaf_off}
|
{"deaf off", conference_loop_deaf_off}
|
||||||
};
|
};
|
||||||
|
|
||||||
int conference_loop_mapping_len()
|
int conference_loop_mapping_len(void)
|
||||||
{
|
{
|
||||||
return (sizeof(control_mappings)/sizeof(control_mappings[0]));
|
return (sizeof(control_mappings)/sizeof(control_mappings[0]));
|
||||||
}
|
}
|
||||||
|
@ -1316,15 +1316,15 @@ void conference_loop_output(conference_member_t *member)
|
||||||
uint32_t flush_len;
|
uint32_t flush_len;
|
||||||
uint32_t low_count, bytes;
|
uint32_t low_count, bytes;
|
||||||
call_list_t *call_list, *cp;
|
call_list_t *call_list, *cp;
|
||||||
switch_codec_implementation_t read_impl = { 0 }, real_read_impl = { 0 };
|
switch_codec_implementation_t real_read_impl = { 0 };
|
||||||
int sanity;
|
int sanity;
|
||||||
|
|
||||||
switch_core_session_get_read_impl(member->session, &read_impl);
|
switch_core_session_get_read_impl(member->session, &member->read_impl);
|
||||||
switch_core_session_get_real_read_impl(member->session, &real_read_impl);
|
switch_core_session_get_real_read_impl(member->session, &real_read_impl);
|
||||||
|
|
||||||
|
|
||||||
channel = switch_core_session_get_channel(member->session);
|
channel = switch_core_session_get_channel(member->session);
|
||||||
interval = read_impl.microseconds_per_packet / 1000;
|
interval = member->read_impl.microseconds_per_packet / 1000;
|
||||||
samples = switch_samples_per_packet(member->conference->rate, interval);
|
samples = switch_samples_per_packet(member->conference->rate, interval);
|
||||||
//csamples = samples;
|
//csamples = samples;
|
||||||
tsamples = real_read_impl.samples_per_packet;
|
tsamples = real_read_impl.samples_per_packet;
|
||||||
|
|
|
@ -766,7 +766,12 @@ switch_status_t conference_member_add(conference_obj_t *conference, conference_m
|
||||||
conference->count++;
|
conference->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (conference_utils_member_test_flag(member, MFLAG_ENDCONF)) {
|
if (conference_utils_member_test_flag(member, MFLAG_ENDCONF)) {
|
||||||
|
conference->endconference_time = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conference_utils_member_test_flag(member, MFLAG_MANDATORY_MEMBER_ENDCONF)) {
|
||||||
if (conference->end_count++) {
|
if (conference->end_count++) {
|
||||||
conference->endconference_time = 0;
|
conference->endconference_time = 0;
|
||||||
}
|
}
|
||||||
|
@ -1314,9 +1319,14 @@ switch_status_t conference_member_del(conference_obj_t *conference, conference_m
|
||||||
|
|
||||||
conference_video_check_flush(member, SWITCH_FALSE);
|
conference_video_check_flush(member, SWITCH_FALSE);
|
||||||
|
|
||||||
|
/* End conference when any member with "endconf" flag disconnects */
|
||||||
if (conference_utils_member_test_flag(member, MFLAG_ENDCONF)) {
|
if (conference_utils_member_test_flag(member, MFLAG_ENDCONF)) {
|
||||||
|
conference_utils_set_flag_locked(conference, CFLAG_DESTRUCT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End conference only if all mandatory members have disconnected */
|
||||||
|
if (conference_utils_member_test_flag(member, MFLAG_MANDATORY_MEMBER_ENDCONF)) {
|
||||||
if (!--conference->end_count) {
|
if (!--conference->end_count) {
|
||||||
//conference_utils_set_flag_locked(conference, CFLAG_DESTRUCT);
|
|
||||||
conference->endconference_time = switch_epoch_time_now(NULL);
|
conference->endconference_time = switch_epoch_time_now(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,8 @@ void conference_utils_set_mflags(const char *flags, member_flag_t *f)
|
||||||
f[MFLAG_NOMOH] = 1;
|
f[MFLAG_NOMOH] = 1;
|
||||||
} else if (!strcasecmp(argv[i], "endconf")) {
|
} else if (!strcasecmp(argv[i], "endconf")) {
|
||||||
f[MFLAG_ENDCONF] = 1;
|
f[MFLAG_ENDCONF] = 1;
|
||||||
|
} else if (!strcasecmp(argv[i], "mandatory_member_endconf")) {
|
||||||
|
f[MFLAG_MANDATORY_MEMBER_ENDCONF] = 1;
|
||||||
} else if (!strcasecmp(argv[i], "mintwo")) {
|
} else if (!strcasecmp(argv[i], "mintwo")) {
|
||||||
f[MFLAG_MINTWO] = 1;
|
f[MFLAG_MINTWO] = 1;
|
||||||
} else if (!strcasecmp(argv[i], "talk-data-events")) {
|
} else if (!strcasecmp(argv[i], "talk-data-events")) {
|
||||||
|
|
|
@ -1347,6 +1347,9 @@ void conference_xlist(conference_obj_t *conference, switch_xml_t x_conference, i
|
||||||
x_tag = switch_xml_add_child_d(x_flags, "end_conference", count++);
|
x_tag = switch_xml_add_child_d(x_flags, "end_conference", count++);
|
||||||
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_ENDCONF) ? "true" : "false");
|
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_ENDCONF) ? "true" : "false");
|
||||||
|
|
||||||
|
x_tag = switch_xml_add_child_d(x_flags, "mandatory_member_end_conference", count++);
|
||||||
|
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_MANDATORY_MEMBER_ENDCONF) ? "true" : "false");
|
||||||
|
|
||||||
x_tag = switch_xml_add_child_d(x_flags, "is_ghost", count++);
|
x_tag = switch_xml_add_child_d(x_flags, "is_ghost", count++);
|
||||||
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_GHOST) ? "true" : "false");
|
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_GHOST) ? "true" : "false");
|
||||||
|
|
||||||
|
@ -1360,7 +1363,7 @@ void conference_xlist(conference_obj_t *conference, switch_xml_t x_conference, i
|
||||||
void conference_jlist(conference_obj_t *conference, cJSON *json_conferences)
|
void conference_jlist(conference_obj_t *conference, cJSON *json_conferences)
|
||||||
{
|
{
|
||||||
conference_member_t *member = NULL;
|
conference_member_t *member = NULL;
|
||||||
static cJSON *json_conference, *json_conference_variables, *json_conference_members, *json_conference_member, *json_conference_member_flags;
|
cJSON *json_conference, *json_conference_variables, *json_conference_members, *json_conference_member, *json_conference_member_flags;
|
||||||
switch_event_header_t *hp;
|
switch_event_header_t *hp;
|
||||||
|
|
||||||
switch_assert(conference != NULL);
|
switch_assert(conference != NULL);
|
||||||
|
@ -1456,6 +1459,7 @@ void conference_jlist(conference_obj_t *conference, cJSON *json_conferences)
|
||||||
ADDBOOL(json_conference_member_flags, "has_floor", member->id == member->conference->floor_holder);
|
ADDBOOL(json_conference_member_flags, "has_floor", member->id == member->conference->floor_holder);
|
||||||
ADDBOOL(json_conference_member_flags, "is_moderator", conference_utils_member_test_flag(member, MFLAG_MOD));
|
ADDBOOL(json_conference_member_flags, "is_moderator", conference_utils_member_test_flag(member, MFLAG_MOD));
|
||||||
ADDBOOL(json_conference_member_flags, "end_conference", conference_utils_member_test_flag(member, MFLAG_ENDCONF));
|
ADDBOOL(json_conference_member_flags, "end_conference", conference_utils_member_test_flag(member, MFLAG_ENDCONF));
|
||||||
|
ADDBOOL(json_conference_member_flags, "mandatory_member_end_conference", conference_utils_member_test_flag(member, MFLAG_MANDATORY_MEMBER_ENDCONF));
|
||||||
ADDBOOL(json_conference_member_flags, "pass_digits", conference_utils_member_test_flag(member, MFLAG_DIST_DTMF));
|
ADDBOOL(json_conference_member_flags, "pass_digits", conference_utils_member_test_flag(member, MFLAG_DIST_DTMF));
|
||||||
}
|
}
|
||||||
switch_mutex_unlock(conference->member_mutex);
|
switch_mutex_unlock(conference->member_mutex);
|
||||||
|
|
|
@ -178,6 +178,7 @@ typedef enum {
|
||||||
MFLAG_NO_MINIMIZE_ENCODING,
|
MFLAG_NO_MINIMIZE_ENCODING,
|
||||||
MFLAG_FLUSH_BUFFER,
|
MFLAG_FLUSH_BUFFER,
|
||||||
MFLAG_ENDCONF,
|
MFLAG_ENDCONF,
|
||||||
|
MFLAG_MANDATORY_MEMBER_ENDCONF,
|
||||||
MFLAG_HAS_AUDIO,
|
MFLAG_HAS_AUDIO,
|
||||||
MFLAG_TALKING,
|
MFLAG_TALKING,
|
||||||
MFLAG_RESTART,
|
MFLAG_RESTART,
|
||||||
|
@ -1123,7 +1124,7 @@ void conference_video_canvas_del_fnode_layer(conference_obj_t *conference, confe
|
||||||
void conference_video_canvas_set_fnode_layer(mcu_canvas_t *canvas, conference_file_node_t *fnode, int idx);
|
void conference_video_canvas_set_fnode_layer(mcu_canvas_t *canvas, conference_file_node_t *fnode, int idx);
|
||||||
void conference_list(conference_obj_t *conference, switch_stream_handle_t *stream, char *delim);
|
void conference_list(conference_obj_t *conference, switch_stream_handle_t *stream, char *delim);
|
||||||
const char *conference_utils_combine_flag_var(switch_core_session_t *session, const char *var_name);
|
const char *conference_utils_combine_flag_var(switch_core_session_t *session, const char *var_name);
|
||||||
int conference_loop_mapping_len();
|
int conference_loop_mapping_len(void);
|
||||||
void conference_api_set_agc(conference_member_t *member, const char *data);
|
void conference_api_set_agc(conference_member_t *member, const char *data);
|
||||||
|
|
||||||
switch_status_t conference_outcall(conference_obj_t *conference,
|
switch_status_t conference_outcall(conference_obj_t *conference,
|
||||||
|
|
|
@ -104,8 +104,13 @@ struct http_sendfile_data_obj {
|
||||||
char *extrapost_elements;
|
char *extrapost_elements;
|
||||||
switch_CURL *curl_handle;
|
switch_CURL *curl_handle;
|
||||||
char *cacert;
|
char *cacert;
|
||||||
|
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
|
||||||
|
curl_mime *mime;
|
||||||
|
curl_mimepart *part;
|
||||||
|
#else
|
||||||
struct curl_httppost *formpost;
|
struct curl_httppost *formpost;
|
||||||
struct curl_httppost *lastptr;
|
struct curl_httppost *lastptr;
|
||||||
|
#endif
|
||||||
uint8_t flags; /* This is for where to send output of the curl_sendfile commands */
|
uint8_t flags; /* This is for where to send output of the curl_sendfile commands */
|
||||||
switch_stream_handle_t *stream;
|
switch_stream_handle_t *stream;
|
||||||
char *sendfile_response;
|
char *sendfile_response;
|
||||||
|
@ -456,8 +461,19 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data)
|
||||||
curl_easy_setopt(http_data->curl_handle, CURLOPT_WRITEFUNCTION, http_sendfile_response_callback);
|
curl_easy_setopt(http_data->curl_handle, CURLOPT_WRITEFUNCTION, http_sendfile_response_callback);
|
||||||
curl_easy_setopt(http_data->curl_handle, CURLOPT_WRITEDATA, (void *) http_data);
|
curl_easy_setopt(http_data->curl_handle, CURLOPT_WRITEDATA, (void *) http_data);
|
||||||
|
|
||||||
|
/* Initial http_data->mime */
|
||||||
|
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
|
||||||
|
http_data->mime = curl_mime_init(http_data->curl_handle);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Add the file to upload as a POST form field */
|
/* Add the file to upload as a POST form field */
|
||||||
|
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
|
||||||
|
http_data->part = curl_mime_addpart(http_data->mime);
|
||||||
|
curl_mime_name(http_data->part, http_data->filename_element_name);
|
||||||
|
curl_mime_filedata(http_data->part, http_data->filename_element);
|
||||||
|
#else
|
||||||
curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, http_data->filename_element_name, CURLFORM_FILE, http_data->filename_element, CURLFORM_END);
|
curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, http_data->filename_element_name, CURLFORM_FILE, http_data->filename_element, CURLFORM_END);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!zstr(http_data->extrapost_elements))
|
if(!zstr(http_data->extrapost_elements))
|
||||||
{
|
{
|
||||||
|
@ -476,16 +492,32 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data)
|
||||||
if(argc2 == 2) {
|
if(argc2 == 2) {
|
||||||
switch_url_decode(argv2[0]);
|
switch_url_decode(argv2[0]);
|
||||||
switch_url_decode(argv2[1]);
|
switch_url_decode(argv2[1]);
|
||||||
|
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
|
||||||
|
http_data->part = curl_mime_addpart(http_data->mime);
|
||||||
|
curl_mime_name(http_data->part, argv2[0]);
|
||||||
|
curl_mime_data(http_data->part, argv2[1], CURL_ZERO_TERMINATED);
|
||||||
|
#else
|
||||||
curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, argv2[0], CURLFORM_COPYCONTENTS, argv2[1], CURLFORM_END);
|
curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, argv2[0], CURLFORM_COPYCONTENTS, argv2[1], CURLFORM_END);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill in the submit field too, even if this isn't really needed */
|
/* Fill in the submit field too, even if this isn't really needed */
|
||||||
|
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
|
||||||
|
http_data->part = curl_mime_addpart(http_data->mime);
|
||||||
|
curl_mime_name(http_data->part, "submit");
|
||||||
|
curl_mime_data(http_data->part, "or_die", CURL_ZERO_TERMINATED);
|
||||||
|
#else
|
||||||
curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, "submit", CURLFORM_COPYCONTENTS, "or_die", CURLFORM_END);
|
curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, "submit", CURLFORM_COPYCONTENTS, "or_die", CURLFORM_END);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* what URL that receives this POST */
|
/* what URL that receives this POST */
|
||||||
|
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
|
||||||
|
curl_easy_setopt(http_data->curl_handle, CURLOPT_MIMEPOST, http_data->mime);
|
||||||
|
#else
|
||||||
curl_easy_setopt(http_data->curl_handle, CURLOPT_HTTPPOST, http_data->formpost);
|
curl_easy_setopt(http_data->curl_handle, CURLOPT_HTTPPOST, http_data->formpost);
|
||||||
|
#endif
|
||||||
|
|
||||||
// This part actually fires off the curl, captures the HTTP response code, and then frees up the handle.
|
// This part actually fires off the curl, captures the HTTP response code, and then frees up the handle.
|
||||||
curl_easy_perform(http_data->curl_handle);
|
curl_easy_perform(http_data->curl_handle);
|
||||||
|
@ -494,7 +526,11 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data)
|
||||||
curl_easy_cleanup(http_data->curl_handle);
|
curl_easy_cleanup(http_data->curl_handle);
|
||||||
|
|
||||||
// Clean up the form data from POST
|
// Clean up the form data from POST
|
||||||
|
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
|
||||||
|
curl_mime_free(http_data->mime);
|
||||||
|
#else
|
||||||
curl_formfree(http_data->formpost);
|
curl_formfree(http_data->formpost);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static switch_status_t http_sendfile_test_file_open(http_sendfile_data_t *http_data, switch_event_t *event)
|
static switch_status_t http_sendfile_test_file_open(http_sendfile_data_t *http_data, switch_event_t *event)
|
||||||
|
|
|
@ -280,7 +280,7 @@ static switch_xml_config_item_t config_settings[] = {
|
||||||
SWITCH_CONFIG_ITEM_END()
|
SWITCH_CONFIG_ITEM_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
static switch_status_t do_config()
|
static switch_status_t do_config(void)
|
||||||
{
|
{
|
||||||
switch_cache_db_handle_t *dbh = NULL;
|
switch_cache_db_handle_t *dbh = NULL;
|
||||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||||
|
|
|
@ -161,7 +161,6 @@ static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match)
|
||||||
char *string = NULL;
|
char *string = NULL;
|
||||||
switch_channel_t *channel;
|
switch_channel_t *channel;
|
||||||
switch_core_session_t *use_session = act->session;
|
switch_core_session_t *use_session = act->session;
|
||||||
int x = 0;
|
|
||||||
char *flags = "";
|
char *flags = "";
|
||||||
|
|
||||||
if (act->target == DIGIT_TARGET_PEER || act->target == DIGIT_TARGET_BOTH) {
|
if (act->target == DIGIT_TARGET_PEER || act->target == DIGIT_TARGET_BOTH) {
|
||||||
|
@ -171,7 +170,6 @@ static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match)
|
||||||
}
|
}
|
||||||
|
|
||||||
top:
|
top:
|
||||||
x++;
|
|
||||||
|
|
||||||
string = switch_core_session_strdup(use_session, act->string);
|
string = switch_core_session_strdup(use_session, act->string);
|
||||||
exec = 0;
|
exec = 0;
|
||||||
|
@ -595,7 +593,7 @@ SWITCH_STANDARD_APP(filter_codecs_function)
|
||||||
r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
|
r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
|
||||||
|
|
||||||
if (data && r_sdp) {
|
if (data && r_sdp) {
|
||||||
switch_core_media_merge_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST, data);
|
switch_core_media_merge_sdp_codec_string(session, r_sdp, SDP_OFFER, data);
|
||||||
switch_channel_set_variable(channel, "filter_codec_string", data);
|
switch_channel_set_variable(channel, "filter_codec_string", data);
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Incomplete data\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Incomplete data\n");
|
||||||
|
@ -4584,7 +4582,7 @@ SWITCH_STANDARD_APP(wait_for_silence_function)
|
||||||
timeout_ms = switch_atoui(argv[3]);
|
timeout_ms = switch_atoui(argv[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thresh > 0 && silence_hits > 0 && listen_hits >= 0) {
|
if (thresh > 0 && silence_hits > 0) {
|
||||||
switch_ivr_wait_for_silence(session, thresh, silence_hits, listen_hits, timeout_ms, argv[4]);
|
switch_ivr_wait_for_silence(session, thresh, silence_hits, listen_hits, timeout_ms, argv[4]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1419,7 +1419,7 @@ static switch_status_t httapi_sync(client_t *client)
|
||||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||||
int get_style_method = 0;
|
int get_style_method = 0;
|
||||||
char *method = NULL;
|
char *method = NULL;
|
||||||
struct curl_httppost *formpost=NULL;
|
switch_curl_mime *formpost = NULL;
|
||||||
switch_event_t *save_params = NULL;
|
switch_event_t *save_params = NULL;
|
||||||
const char *put_file;
|
const char *put_file;
|
||||||
FILE *fd = NULL;
|
FILE *fd = NULL;
|
||||||
|
@ -1476,7 +1476,7 @@ static switch_status_t httapi_sync(client_t *client)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!put_file) {
|
if (!put_file) {
|
||||||
switch_curl_process_form_post_params(client->params, curl_handle, &formpost);
|
switch_curl_process_mime(client->params, curl_handle, &formpost);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (formpost) {
|
if (formpost) {
|
||||||
|
@ -1588,7 +1588,7 @@ static switch_status_t httapi_sync(client_t *client)
|
||||||
curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, put_file_read);
|
curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, put_file_read);
|
||||||
|
|
||||||
} else if (formpost) {
|
} else if (formpost) {
|
||||||
curl_easy_setopt(curl_handle, CURLOPT_HTTPPOST, formpost);
|
switch_curl_easy_setopt_mime(curl_handle, formpost);
|
||||||
} else {
|
} else {
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_POST, !get_style_method);
|
switch_curl_easy_setopt(curl_handle, CURLOPT_POST, !get_style_method);
|
||||||
}
|
}
|
||||||
|
@ -1670,9 +1670,7 @@ static switch_status_t httapi_sync(client_t *client)
|
||||||
switch_curl_easy_cleanup(curl_handle);
|
switch_curl_easy_cleanup(curl_handle);
|
||||||
switch_curl_slist_free_all(headers);
|
switch_curl_slist_free_all(headers);
|
||||||
|
|
||||||
if (formpost) {
|
switch_curl_mime_free(&formpost);
|
||||||
curl_formfree(formpost);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client->err) {
|
if (client->err) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error encountered! [%s]\ndata: [%s]\n", client->profile->url, data);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error encountered! [%s]\ndata: [%s]\n", client->profile->url, data);
|
||||||
|
|
|
@ -279,7 +279,11 @@ switch_status_t azure_blob_finalise_put(http_profile_t *profile, const char *url
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x070c01)
|
||||||
|
switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1);
|
||||||
|
#else
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1);
|
switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1);
|
||||||
|
#endif
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
|
switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
|
switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_URL, full_url);
|
switch_curl_easy_setopt(curl_handle, CURLOPT_URL, full_url);
|
||||||
|
|
|
@ -393,7 +393,9 @@ static switch_status_t http_put(url_cache_t *cache, http_profile_t *profile, swi
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1);
|
switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1);
|
||||||
|
#if !defined(LIBCURL_VERSION_NUM) || (LIBCURL_VERSION_NUM < 0x070c01)
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1);
|
switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1);
|
||||||
|
#endif
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
|
switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
|
switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_URL, full_url);
|
switch_curl_easy_setopt(curl_handle, CURLOPT_URL, full_url);
|
||||||
|
|
|
@ -228,7 +228,7 @@ static ks_status_t load_credentials_from_json(ks_json_t *json)
|
||||||
const char *relay_connector_id = NULL;
|
const char *relay_connector_id = NULL;
|
||||||
|
|
||||||
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
||||||
if ((bootstrap = ks_json_get_string(json, "bootstrap")) == NULL) {
|
if ((bootstrap = ks_json_get_object_string(json, "bootstrap", NULL)) == NULL) {
|
||||||
#else
|
#else
|
||||||
if ((bootstrap = ks_json_get_object_cstr(json, "bootstrap")) == NULL) {
|
if ((bootstrap = ks_json_get_object_cstr(json, "bootstrap")) == NULL) {
|
||||||
#endif
|
#endif
|
||||||
|
@ -238,7 +238,7 @@ static ks_status_t load_credentials_from_json(ks_json_t *json)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
||||||
if ((relay_connector_id = ks_json_get_string(json, "relay_connector_id")) == NULL) {
|
if ((relay_connector_id = ks_json_get_object_string(json, "relay_connector_id", NULL)) == NULL) {
|
||||||
#else
|
#else
|
||||||
if ((relay_connector_id = ks_json_get_object_cstr(json, "relay_connector_id")) == NULL) {
|
if ((relay_connector_id = ks_json_get_object_cstr(json, "relay_connector_id")) == NULL) {
|
||||||
#endif
|
#endif
|
||||||
|
@ -704,7 +704,7 @@ done:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static switch_status_t load_config()
|
static switch_status_t load_config(void)
|
||||||
{
|
{
|
||||||
char *cf = "signalwire.conf";
|
char *cf = "signalwire.conf";
|
||||||
switch_xml_t cfg, xml;
|
switch_xml_t cfg, xml;
|
||||||
|
@ -797,6 +797,7 @@ static ks_status_t load_credentials(void)
|
||||||
status = KS_STATUS_FAIL;
|
status = KS_STATUS_FAIL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
json = ks_json_parse(data);
|
json = ks_json_parse(data);
|
||||||
|
@ -805,6 +806,7 @@ static ks_status_t load_credentials(void)
|
||||||
status = KS_STATUS_FAIL;
|
status = KS_STATUS_FAIL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = load_credentials_from_json(json);
|
status = load_credentials_from_json(json);
|
||||||
ks_json_delete(&json);
|
ks_json_delete(&json);
|
||||||
|
|
||||||
|
@ -981,7 +983,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_signalwire_load)
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
sslLoadWindowsCACertificate();
|
sslLoadWindowsCACertificate();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
swclt_config_create(&globals.config);
|
swclt_config_create(&globals.config);
|
||||||
load_config();
|
load_config();
|
||||||
|
@ -1206,6 +1207,7 @@ static void mod_signalwire_state_configure(void)
|
||||||
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
||||||
if (!swclt_sess_provisioning_configure(globals.signalwire_session, "freeswitch", local_endpoint, external_endpoint, globals.relay_connector_id, &reply)) {
|
if (!swclt_sess_provisioning_configure(globals.signalwire_session, "freeswitch", local_endpoint, external_endpoint, globals.relay_connector_id, &reply)) {
|
||||||
if (reply->type == SWCLT_CMD_TYPE_RESULT) {
|
if (reply->type == SWCLT_CMD_TYPE_RESULT) {
|
||||||
|
ks_json_t *result;
|
||||||
#else
|
#else
|
||||||
if (!swclt_sess_provisioning_configure(globals.signalwire_session, "freeswitch", local_endpoint, external_endpoint, globals.relay_connector_id, &cmd)) {
|
if (!swclt_sess_provisioning_configure(globals.signalwire_session, "freeswitch", local_endpoint, external_endpoint, globals.relay_connector_id, &cmd)) {
|
||||||
SWCLT_CMD_TYPE cmd_type;
|
SWCLT_CMD_TYPE cmd_type;
|
||||||
|
@ -1215,7 +1217,8 @@ static void mod_signalwire_state_configure(void)
|
||||||
#endif
|
#endif
|
||||||
signalwire_provisioning_configure_response_t *configure_res;
|
signalwire_provisioning_configure_response_t *configure_res;
|
||||||
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
||||||
if (!SIGNALWIRE_PROVISIONING_CONFIGURE_RESPONSE_PARSE(reply->pool, reply->json, &configure_res)) {
|
result = ks_json_get_object_item(reply->json, "result");
|
||||||
|
if (!SIGNALWIRE_PROVISIONING_CONFIGURE_RESPONSE_PARSE(reply->pool, result, &configure_res)) {
|
||||||
#else
|
#else
|
||||||
swclt_cmd_result(cmd, &result);
|
swclt_cmd_result(cmd, &result);
|
||||||
result = ks_json_get_object_item(result, "result");
|
result = ks_json_get_object_item(result, "result");
|
||||||
|
@ -1223,7 +1226,7 @@ static void mod_signalwire_state_configure(void)
|
||||||
#endif
|
#endif
|
||||||
ks_json_t *configuration = configure_res->configuration;
|
ks_json_t *configuration = configure_res->configuration;
|
||||||
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
||||||
const char *configuration_profile = ks_json_get_string(configuration, "profile");
|
const char *configuration_profile = ks_json_get_object_string(configuration, "profile", NULL);
|
||||||
#else
|
#else
|
||||||
const char *configuration_profile = ks_json_get_object_cstr(configuration, "profile");
|
const char *configuration_profile = ks_json_get_object_cstr(configuration, "profile");
|
||||||
#endif
|
#endif
|
||||||
|
@ -1231,6 +1234,7 @@ static void mod_signalwire_state_configure(void)
|
||||||
switch_xml_free(globals.signalwire_profile);
|
switch_xml_free(globals.signalwire_profile);
|
||||||
globals.signalwire_profile = NULL;
|
globals.signalwire_profile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\"%s\"\n", configuration_profile);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\"%s\"\n", configuration_profile);
|
||||||
globals.signalwire_profile = switch_xml_parse_str_dynamic((char *)configuration_profile, SWITCH_TRUE);
|
globals.signalwire_profile = switch_xml_parse_str_dynamic((char *)configuration_profile, SWITCH_TRUE);
|
||||||
if (!globals.signalwire_profile) {
|
if (!globals.signalwire_profile) {
|
||||||
|
@ -1386,7 +1390,7 @@ static void mod_signalwire_state_register(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mod_signalwire_state_ready()
|
static void mod_signalwire_state_ready(void)
|
||||||
{
|
{
|
||||||
if (globals.profile_update) {
|
if (globals.profile_update) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Signalwire SIP profile update initiated\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Signalwire SIP profile update initiated\n");
|
||||||
|
|
|
@ -897,9 +897,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
if (new_session) {
|
switch_core_session_destroy(new_session);
|
||||||
switch_core_session_destroy(new_session);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modem) {
|
if (modem) {
|
||||||
modem_set_state(modem, MODEM_STATE_ONHOOK);
|
modem_set_state(modem, MODEM_STATE_ONHOOK);
|
||||||
|
|
|
@ -130,6 +130,7 @@ static void translate_number(char *number, char *profile, char **translated, swi
|
||||||
hi = switch_core_hash_find_rdlock(globals.translate_profiles, (const char *)profile, globals.profile_hash_rwlock);
|
hi = switch_core_hash_find_rdlock(globals.translate_profiles, (const char *)profile, globals.profile_hash_rwlock);
|
||||||
if (!hi) {
|
if (!hi) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "can't find key for profile matching [%s]\n", profile);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "can't find key for profile matching [%s]\n", profile);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,6 +143,7 @@ static void translate_number(char *number, char *profile, char **translated, swi
|
||||||
switch_regex_safe_free(re);
|
switch_regex_safe_free(re);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(substituted, 0, len);
|
memset(substituted, 0, len);
|
||||||
|
|
||||||
switch_perform_substitution(re, proceed, rule->replace, number, substituted, len, ovector);
|
switch_perform_substitution(re, proceed, rule->replace, number, substituted, len, ovector);
|
||||||
|
@ -153,16 +155,21 @@ static void translate_number(char *number, char *profile, char **translated, swi
|
||||||
} else if (event) {
|
} else if (event) {
|
||||||
subbed = switch_event_expand_headers(event, substituted);
|
subbed = switch_event_expand_headers(event, substituted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (subbed != substituted) {
|
||||||
|
switch_safe_free(substituted);
|
||||||
|
}
|
||||||
|
|
||||||
if (session) {
|
if (session) {
|
||||||
substituted = switch_core_session_strdup(session, subbed);
|
substituted = switch_core_session_strdup(session, subbed);
|
||||||
} else {
|
} else {
|
||||||
substituted = switch_core_strdup(pool, subbed);
|
substituted = switch_core_strdup(pool, subbed);
|
||||||
}
|
}
|
||||||
if (subbed != substituted) {
|
|
||||||
switch_safe_free(subbed);
|
switch_safe_free(subbed);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_regex_safe_free(re);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,6 +250,7 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_
|
||||||
int x, i, argc, fmtptmp_pos;
|
int x, i, argc, fmtptmp_pos;
|
||||||
char *argv[10];
|
char *argv[10];
|
||||||
char fmtptmp[128];
|
char fmtptmp[128];
|
||||||
|
char *fmtp_dup = NULL;
|
||||||
|
|
||||||
encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
|
encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
|
||||||
decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
|
decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
|
||||||
|
@ -283,13 +284,19 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_
|
||||||
switch_set_flag(context, AMR_OPT_OCTET_ALIGN);
|
switch_set_flag(context, AMR_OPT_OCTET_ALIGN);
|
||||||
}
|
}
|
||||||
if (codec->fmtp_in) {
|
if (codec->fmtp_in) {
|
||||||
argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0])));
|
fmtp_dup = strdup(codec->fmtp_in);
|
||||||
|
switch_assert(fmtp_dup);
|
||||||
|
|
||||||
|
argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||||
|
|
||||||
for (x = 0; x < argc; x++) {
|
for (x = 0; x < argc; x++) {
|
||||||
char *data = argv[x];
|
char *data = argv[x];
|
||||||
char *arg;
|
char *arg;
|
||||||
|
|
||||||
while (*data && *data == ' ') {
|
while (*data && *data == ' ') {
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((arg = strchr(data, '='))) {
|
if ((arg = strchr(data, '='))) {
|
||||||
*arg++ = '\0';
|
*arg++ = '\0';
|
||||||
if (!strcasecmp(data, "octet-align")) {
|
if (!strcasecmp(data, "octet-align")) {
|
||||||
|
@ -325,13 +332,17 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_
|
||||||
} else if (!strcasecmp(data, "mode-set")) {
|
} else if (!strcasecmp(data, "mode-set")) {
|
||||||
int y, m_argc;
|
int y, m_argc;
|
||||||
char *m_argv[SWITCH_AMR_MODES-1];
|
char *m_argv[SWITCH_AMR_MODES-1];
|
||||||
|
|
||||||
m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0])));
|
m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0])));
|
||||||
|
|
||||||
for (y = 0; y < m_argc; y++) {
|
for (y = 0; y < m_argc; y++) {
|
||||||
context->enc_modes |= (1 << atoi(m_argv[y]));
|
context->enc_modes |= (1 << atoi(m_argv[y]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(fmtp_dup);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->enc_modes) {
|
if (context->enc_modes) {
|
||||||
|
@ -475,13 +486,15 @@ static switch_status_t switch_amr_decode(switch_codec_t *codec,
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
#else
|
#else
|
||||||
struct amr_context *context = codec->private_info;
|
struct amr_context *context = codec->private_info;
|
||||||
unsigned char *buf = encoded_data;
|
unsigned char buf[SWITCH_AMR_OUT_MAX_SIZE];
|
||||||
uint8_t tmp[SWITCH_AMR_OUT_MAX_SIZE];
|
uint8_t tmp[SWITCH_AMR_OUT_MAX_SIZE];
|
||||||
|
|
||||||
if (!context) {
|
if (!context || encoded_data_len > SWITCH_AMR_OUT_MAX_SIZE) {
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(buf, encoded_data, encoded_data_len);
|
||||||
|
|
||||||
if (globals.debug) {
|
if (globals.debug) {
|
||||||
switch_amr_info(codec, buf, encoded_data_len, switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0, "AMR decoder");
|
switch_amr_info(codec, buf, encoded_data_len, switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0, "AMR decoder");
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,6 +198,7 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla
|
||||||
int x, i, argc, fmtptmp_pos;
|
int x, i, argc, fmtptmp_pos;
|
||||||
char *argv[10];
|
char *argv[10];
|
||||||
char fmtptmp[128];
|
char fmtptmp[128];
|
||||||
|
char *fmtp_dup = NULL;
|
||||||
|
|
||||||
encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
|
encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
|
||||||
decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
|
decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
|
||||||
|
@ -222,13 +223,19 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codec->fmtp_in) {
|
if (codec->fmtp_in) {
|
||||||
argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0])));
|
fmtp_dup = strdup(codec->fmtp_in);
|
||||||
|
switch_assert(fmtp_dup);
|
||||||
|
|
||||||
|
argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||||
|
|
||||||
for (x = 0; x < argc; x++) {
|
for (x = 0; x < argc; x++) {
|
||||||
char *data = argv[x];
|
char *data = argv[x];
|
||||||
char *arg;
|
char *arg;
|
||||||
|
|
||||||
while (*data && *data == ' ') {
|
while (*data && *data == ' ') {
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((arg = strchr(data, '='))) {
|
if ((arg = strchr(data, '='))) {
|
||||||
*arg++ = '\0';
|
*arg++ = '\0';
|
||||||
if (!strcasecmp(data, "octet-align")) {
|
if (!strcasecmp(data, "octet-align")) {
|
||||||
|
@ -264,7 +271,9 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla
|
||||||
} else if (!strcasecmp(data, "mode-set")) {
|
} else if (!strcasecmp(data, "mode-set")) {
|
||||||
int y, m_argc;
|
int y, m_argc;
|
||||||
char *m_argv[SWITCH_AMRWB_MODES-1]; /* AMRWB has 9 modes */
|
char *m_argv[SWITCH_AMRWB_MODES-1]; /* AMRWB has 9 modes */
|
||||||
|
|
||||||
m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0])));
|
m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0])));
|
||||||
|
|
||||||
for (y = 0; y < m_argc; y++) {
|
for (y = 0; y < m_argc; y++) {
|
||||||
context->enc_modes |= (1 << atoi(m_argv[y]));
|
context->enc_modes |= (1 << atoi(m_argv[y]));
|
||||||
context->enc_mode = atoi(m_argv[y]);
|
context->enc_mode = atoi(m_argv[y]);
|
||||||
|
@ -272,6 +281,8 @@ static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_fla
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(fmtp_dup);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->enc_modes && !globals.mode_set_overwrite) {
|
if (context->enc_modes && !globals.mode_set_overwrite) {
|
||||||
|
@ -401,13 +412,15 @@ static switch_status_t switch_amrwb_decode(switch_codec_t *codec,
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
#else
|
#else
|
||||||
struct amrwb_context *context = codec->private_info;
|
struct amrwb_context *context = codec->private_info;
|
||||||
unsigned char *buf = encoded_data;
|
unsigned char buf[SWITCH_AMRWB_OUT_MAX_SIZE];
|
||||||
uint8_t tmp[SWITCH_AMRWB_OUT_MAX_SIZE];
|
uint8_t tmp[SWITCH_AMRWB_OUT_MAX_SIZE];
|
||||||
|
|
||||||
if (!context) {
|
if (!context || encoded_data_len > SWITCH_AMRWB_OUT_MAX_SIZE) {
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(buf, encoded_data, encoded_data_len);
|
||||||
|
|
||||||
if (globals.debug) {
|
if (globals.debug) {
|
||||||
switch_amrwb_info(codec, buf, encoded_data_len, switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0, "AMRWB decoder");
|
switch_amrwb_info(codec, buf, encoded_data_len, switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0, "AMRWB decoder");
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ static switch_status_t switch_ilbc_fmtp_parse(const char *fmtp, switch_codec_fmt
|
||||||
|
|
||||||
memset(codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
|
memset(codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
|
||||||
|
|
||||||
if (fmtp && (mode = strstr(fmtp, "mode=")) && (mode + 5)) {
|
if (fmtp && (mode = strstr(fmtp, "mode=")) && *(mode + 5)) {
|
||||||
codec_ms = atoi(mode + 5);
|
codec_ms = atoi(mode + 5);
|
||||||
}
|
}
|
||||||
if (!codec_ms) {
|
if (!codec_ms) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ MODNAME=mod_opus
|
||||||
if HAVE_OPUS
|
if HAVE_OPUS
|
||||||
|
|
||||||
mod_LTLIBRARIES = mod_opus.la
|
mod_LTLIBRARIES = mod_opus.la
|
||||||
mod_opus_la_SOURCES = mod_opus.c
|
mod_opus_la_SOURCES = mod_opus.c opus_parse.c
|
||||||
mod_opus_la_CFLAGS = $(AM_CFLAGS) $(OPUS_CFLAGS)
|
mod_opus_la_CFLAGS = $(AM_CFLAGS) $(OPUS_CFLAGS)
|
||||||
mod_opus_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(OPUS_LIBS)
|
mod_opus_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(OPUS_LIBS)
|
||||||
mod_opus_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm -lz
|
mod_opus_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm -lz
|
||||||
|
|
|
@ -130,6 +130,10 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="mod_opus.c" />
|
<ClCompile Include="mod_opus.c" />
|
||||||
|
<ClCompile Include="opus_parse.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="opus_parse.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\..\libs\win32\opus\opus.2017.vcxproj">
|
<ProjectReference Include="..\..\..\..\libs\win32\opus\opus.2017.vcxproj">
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include "switch.h"
|
#include "switch.h"
|
||||||
#include "opus.h"
|
#include "opus.h"
|
||||||
|
#include "opus_parse.h"
|
||||||
|
|
||||||
#define SWITCH_OPUS_MIN_BITRATE 6000
|
#define SWITCH_OPUS_MIN_BITRATE 6000
|
||||||
#define SWITCH_OPUS_MAX_BITRATE 510000
|
#define SWITCH_OPUS_MAX_BITRATE 510000
|
||||||
|
@ -142,25 +143,26 @@ struct opus_context {
|
||||||
dec_stats_t decoder_stats;
|
dec_stats_t decoder_stats;
|
||||||
enc_stats_t encoder_stats;
|
enc_stats_t encoder_stats;
|
||||||
codec_control_state_t control_state;
|
codec_control_state_t control_state;
|
||||||
|
switch_bool_t recreate_decoder;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int use_vbr;
|
switch_bool_t use_vbr;
|
||||||
int use_dtx;
|
switch_bool_t use_dtx;
|
||||||
int complexity;
|
int complexity;
|
||||||
int maxaveragebitrate;
|
int maxaveragebitrate;
|
||||||
int maxplaybackrate;
|
int maxplaybackrate;
|
||||||
int sprop_maxcapturerate;
|
int sprop_maxcapturerate;
|
||||||
int plpct;
|
int plpct;
|
||||||
int asymmetric_samplerates;
|
switch_bool_t asymmetric_samplerates;
|
||||||
int bitrate_negotiation;
|
switch_bool_t bitrate_negotiation;
|
||||||
int keep_fec;
|
switch_bool_t keep_fec;
|
||||||
int fec_decode;
|
switch_bool_t fec_decode;
|
||||||
int adjust_bitrate;
|
switch_bool_t adjust_bitrate;
|
||||||
int debuginfo;
|
int debuginfo;
|
||||||
uint32_t use_jb_lookahead;
|
switch_bool_t use_jb_lookahead;
|
||||||
switch_mutex_t *mutex;
|
switch_mutex_t *mutex;
|
||||||
int mono;
|
switch_bool_t mono;
|
||||||
} opus_prefs;
|
} opus_prefs;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
|
@ -272,10 +274,12 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt
|
||||||
|
|
||||||
if (!strcasecmp(data, "maxptime")) {
|
if (!strcasecmp(data, "maxptime")) {
|
||||||
codec_settings->maxptime = atoi(arg);
|
codec_settings->maxptime = atoi(arg);
|
||||||
|
codec_fmtp->max_ptime = codec_settings->maxptime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcasecmp(data, "minptime")) {
|
if (!strcasecmp(data, "minptime")) {
|
||||||
codec_settings->minptime = atoi(arg);
|
codec_settings->minptime = atoi(arg);
|
||||||
|
codec_fmtp->min_ptime = codec_settings->minptime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcasecmp(data, "ptime")) {
|
if (!strcasecmp(data, "ptime")) {
|
||||||
|
@ -290,6 +294,7 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt
|
||||||
|
|
||||||
if (!strcasecmp(data, "sprop-stereo")) {
|
if (!strcasecmp(data, "sprop-stereo")) {
|
||||||
codec_settings->sprop_stereo = atoi(arg);
|
codec_settings->sprop_stereo = atoi(arg);
|
||||||
|
codec_fmtp->sprop_stereo = codec_settings->sprop_stereo;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcasecmp(data, "maxaveragebitrate")) {
|
if (!strcasecmp(data, "maxaveragebitrate")) {
|
||||||
|
@ -310,6 +315,10 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt
|
||||||
if (!switch_opus_acceptable_rate(codec_settings->sprop_maxcapturerate)) {
|
if (!switch_opus_acceptable_rate(codec_settings->sprop_maxcapturerate)) {
|
||||||
codec_settings->sprop_maxcapturerate = 0; /* value not supported */
|
codec_settings->sprop_maxcapturerate = 0; /* value not supported */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (codec_settings->sprop_maxcapturerate) {
|
||||||
|
codec_fmtp->actual_samples_per_second = codec_settings->sprop_maxcapturerate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -471,7 +480,7 @@ static int switch_opus_get_fec_bitrate(int fs, int loss)
|
||||||
return SWITCH_STATUS_FALSE ;
|
return SWITCH_STATUS_FALSE ;
|
||||||
}
|
}
|
||||||
|
|
||||||
static switch_status_t switch_opus_info(void * encoded_data, uint32_t len, uint32_t samples_per_second, char *print_text)
|
static switch_status_t switch_opus_info(switch_core_session_t *session, void * encoded_data, uint32_t len, uint32_t samples_per_second, char *print_text)
|
||||||
{
|
{
|
||||||
int nb_samples, nb_opus_frames, nb_channels;
|
int nb_samples, nb_opus_frames, nb_channels;
|
||||||
int audiobandwidth;
|
int audiobandwidth;
|
||||||
|
@ -483,18 +492,18 @@ static switch_status_t switch_opus_info(void * encoded_data, uint32_t len, uint3
|
||||||
|
|
||||||
if (!encoded_data) {
|
if (!encoded_data) {
|
||||||
/* print stuff, even if encoded_data is NULL. eg: "PLC correction" */
|
/* print stuff, even if encoded_data is NULL. eg: "PLC correction" */
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s", print_text);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s", print_text);
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
audiobandwidth = opus_packet_get_bandwidth(encoded_data);
|
audiobandwidth = opus_packet_get_bandwidth(encoded_data);
|
||||||
|
|
||||||
if (!switch_opus_show_audio_bandwidth(audiobandwidth,audiobandwidth_str)) {
|
if (!switch_opus_show_audio_bandwidth(audiobandwidth,audiobandwidth_str)) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET !\n", print_text);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET !\n", print_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((nb_opus_frames = opus_packet_parse(encoded_data, len, NULL, frame_data, frame_sizes, NULL)) <= 0 ) {
|
if ((nb_opus_frames = opus_packet_parse(encoded_data, len, NULL, frame_data, frame_sizes, NULL)) <= 0 ) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET ! frames: %d\n", print_text, nb_opus_frames);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET ! frames: %d\n", print_text, nb_opus_frames);
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,7 +513,7 @@ static switch_status_t switch_opus_info(void * encoded_data, uint32_t len, uint3
|
||||||
|
|
||||||
nb_channels = opus_packet_get_nb_channels(payload);
|
nb_channels = opus_packet_get_nb_channels(payload);
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: opus_frames [%d] samples [%d] audio bandwidth [%s] bytes [%d] FEC[%s] channels[%d]\n",
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s: opus_frames [%d] samples [%d] audio bandwidth [%s] bytes [%d] FEC[%s] channels[%d]\n",
|
||||||
print_text, nb_opus_frames, nb_samples, audiobandwidth_str, len, has_fec ? "yes" : "no", nb_channels);
|
print_text, nb_opus_frames, nb_samples, audiobandwidth_str, len, has_fec ? "yes" : "no", nb_channels);
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
@ -518,6 +527,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
||||||
switch_codec_fmtp_t codec_fmtp, codec_fmtp_only_remote = { 0 };
|
switch_codec_fmtp_t codec_fmtp, codec_fmtp_only_remote = { 0 };
|
||||||
opus_codec_settings_t opus_codec_settings = { 0 };
|
opus_codec_settings_t opus_codec_settings = { 0 };
|
||||||
opus_codec_settings_t opus_codec_settings_remote = { 0 };
|
opus_codec_settings_t opus_codec_settings_remote = { 0 };
|
||||||
|
switch_core_session_t *session = codec->session;
|
||||||
|
|
||||||
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
|
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
|
@ -591,7 +601,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
||||||
if (settings && settings->maxplaybackrate < enc_samplerate && settings->maxplaybackrate) {
|
if (settings && settings->maxplaybackrate < enc_samplerate && settings->maxplaybackrate) {
|
||||||
enc_samplerate = settings->maxplaybackrate; /*R1*/
|
enc_samplerate = settings->maxplaybackrate; /*R1*/
|
||||||
context->enc_frame_size = enc_samplerate * (codec->implementation->microseconds_per_packet / 1000) / 1000;
|
context->enc_frame_size = enc_samplerate * (codec->implementation->microseconds_per_packet / 1000) / 1000;
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder will be created at sample rate %d hz\n",enc_samplerate);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder will be created at sample rate %d hz\n",enc_samplerate);
|
||||||
} else {
|
} else {
|
||||||
enc_samplerate = codec->implementation->actual_samples_per_second;
|
enc_samplerate = codec->implementation->actual_samples_per_second;
|
||||||
}
|
}
|
||||||
|
@ -604,19 +614,19 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
||||||
codec->implementation->number_of_channels == 1 ? OPUS_APPLICATION_VOIP : OPUS_APPLICATION_AUDIO, &err);
|
codec->implementation->number_of_channels == 1 ? OPUS_APPLICATION_VOIP : OPUS_APPLICATION_AUDIO, &err);
|
||||||
|
|
||||||
if (err != OPUS_OK) {
|
if (err != OPUS_OK) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create encoder: %s\n", opus_strerror(err));
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot create encoder: %s\n", opus_strerror(err));
|
||||||
return SWITCH_STATUS_GENERR;
|
return SWITCH_STATUS_GENERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* https://tools.ietf.org/html/rfc7587 */
|
/* https://tools.ietf.org/html/rfc7587 */
|
||||||
if (opus_codec_settings.maxaveragebitrate) {
|
if (opus_codec_settings.maxaveragebitrate) {
|
||||||
opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(opus_codec_settings.maxaveragebitrate));
|
opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(opus_codec_settings.maxaveragebitrate));
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: set bitrate based on maxaveragebitrate value found in SDP or local config [%dbps]\n", opus_codec_settings.maxaveragebitrate);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: set bitrate based on maxaveragebitrate value found in SDP or local config [%dbps]\n", opus_codec_settings.maxaveragebitrate);
|
||||||
} else {
|
} else {
|
||||||
opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(OPUS_AUTO));
|
opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(OPUS_AUTO));
|
||||||
opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(bitrate_bps)); /* OPUS_AUTO */
|
opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(bitrate_bps)); /* OPUS_AUTO */
|
||||||
opus_encoder_ctl(context->encoder_object, OPUS_GET_BITRATE(&bitrate_bps)); /* return average bps for this audio bandwidth */
|
opus_encoder_ctl(context->encoder_object, OPUS_GET_BITRATE(&bitrate_bps)); /* return average bps for this audio bandwidth */
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: set bitrate to local settings [%dbps]\n", bitrate_bps);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: set bitrate to local settings [%dbps]\n", bitrate_bps);
|
||||||
}
|
}
|
||||||
/* Another fmtp setting from https://tools.ietf.org/html/rfc7587 - "RTP Payload Format for the Opus Speech and Audio Codec" */
|
/* Another fmtp setting from https://tools.ietf.org/html/rfc7587 - "RTP Payload Format for the Opus Speech and Audio Codec" */
|
||||||
if (opus_codec_settings.maxplaybackrate) {
|
if (opus_codec_settings.maxplaybackrate) {
|
||||||
|
@ -627,14 +637,14 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
||||||
if (!switch_opus_show_audio_bandwidth(audiobandwidth,audiobandwidth_str)) {
|
if (!switch_opus_show_audio_bandwidth(audiobandwidth,audiobandwidth_str)) {
|
||||||
snprintf(audiobandwidth_str, sizeof(audiobandwidth_str), "%s", "OPUS_AUTO");
|
snprintf(audiobandwidth_str, sizeof(audiobandwidth_str), "%s", "OPUS_AUTO");
|
||||||
}
|
}
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: set audio bandwidth to [%s] based on maxplaybackrate value found in SDP or local config [%dHz]\n",audiobandwidth_str,opus_codec_settings.maxplaybackrate);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: set audio bandwidth to [%s] based on maxplaybackrate value found in SDP or local config [%dHz]\n",audiobandwidth_str,opus_codec_settings.maxplaybackrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_vbr) {
|
if (use_vbr) {
|
||||||
/* VBR is default*/
|
/* VBR is default*/
|
||||||
opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(use_vbr));
|
opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(use_vbr));
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: CBR mode enabled\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: CBR mode enabled\n");
|
||||||
opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(0));
|
opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,7 +694,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
||||||
if (settings && dec_samplerate > settings->sprop_maxcapturerate && settings->sprop_maxcapturerate) {
|
if (settings && dec_samplerate > settings->sprop_maxcapturerate && settings->sprop_maxcapturerate) {
|
||||||
dec_samplerate = settings->sprop_maxcapturerate; /* R2 */
|
dec_samplerate = settings->sprop_maxcapturerate; /* R2 */
|
||||||
context->dec_frame_size = dec_samplerate*(codec->implementation->microseconds_per_packet / 1000) / 1000;
|
context->dec_frame_size = dec_samplerate*(codec->implementation->microseconds_per_packet / 1000) / 1000;
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus decoder will be created at sample rate %d hz\n",dec_samplerate);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus decoder will be created at sample rate %d hz\n",dec_samplerate);
|
||||||
} else {
|
} else {
|
||||||
dec_samplerate = codec->implementation->actual_samples_per_second;
|
dec_samplerate = codec->implementation->actual_samples_per_second;
|
||||||
}
|
}
|
||||||
|
@ -697,7 +707,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
||||||
switch_set_flag(codec, SWITCH_CODEC_FLAG_HAS_PLC);
|
switch_set_flag(codec, SWITCH_CODEC_FLAG_HAS_PLC);
|
||||||
|
|
||||||
if (err != OPUS_OK) {
|
if (err != OPUS_OK) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create decoder: %s\n", opus_strerror(err));
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot create decoder: %s\n", opus_strerror(err));
|
||||||
|
|
||||||
if (context->encoder_object) {
|
if (context->encoder_object) {
|
||||||
opus_encoder_destroy(context->encoder_object);
|
opus_encoder_destroy(context->encoder_object);
|
||||||
|
@ -774,7 +784,7 @@ static switch_status_t switch_opus_encode(switch_codec_t *codec,
|
||||||
|
|
||||||
if (globals.debug || context->debug > 1) {
|
if (globals.debug || context->debug > 1) {
|
||||||
int samplerate = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000);
|
int samplerate = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000);
|
||||||
switch_opus_info(encoded_data, bytes, samplerate, "encode");
|
switch_opus_info(codec->session, encoded_data, bytes, samplerate, "encode");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes > 0) {
|
if (bytes > 0) {
|
||||||
|
@ -796,7 +806,7 @@ static switch_status_t switch_opus_encode(switch_codec_t *codec,
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR,
|
||||||
"Encoder Error: %s Decoded Datalen %u Codec NumberChans %u Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p!\n",
|
"Encoder Error: %s Decoded Datalen %u Codec NumberChans %u Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p!\n",
|
||||||
opus_strerror(bytes),decoded_data_len,codec->implementation->number_of_channels,len,(void *) decoded_data,
|
opus_strerror(bytes),decoded_data_len,codec->implementation->number_of_channels,len,(void *) decoded_data,
|
||||||
(void *) encoded_data,(void *) context->encoder_object);
|
(void *) encoded_data,(void *) context->encoder_object);
|
||||||
|
@ -817,6 +827,8 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||||
int fec = 0, plc = 0;
|
int fec = 0, plc = 0;
|
||||||
int32_t frame_size = 0, last_frame_size = 0;
|
int32_t frame_size = 0, last_frame_size = 0;
|
||||||
uint32_t frame_samples;
|
uint32_t frame_samples;
|
||||||
|
uint8_t buf[SWITCH_RTP_MAX_BUF_LEN];
|
||||||
|
switch_core_session_t *session = codec->session;
|
||||||
|
|
||||||
if (!context) {
|
if (!context) {
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
|
@ -826,7 +838,6 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||||
frame_size = frame_samples - (frame_samples % (codec->implementation->actual_samples_per_second / 400));
|
frame_size = frame_samples - (frame_samples % (codec->implementation->actual_samples_per_second / 400));
|
||||||
|
|
||||||
if (*flag & SFF_PLC) {
|
if (*flag & SFF_PLC) {
|
||||||
switch_core_session_t *session = codec->session;
|
|
||||||
switch_jb_t *jb = NULL;
|
switch_jb_t *jb = NULL;
|
||||||
|
|
||||||
plc = 1;
|
plc = 1;
|
||||||
|
@ -842,7 +853,6 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||||
}
|
}
|
||||||
if (codec->cur_frame && (jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO))) {
|
if (codec->cur_frame && (jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO))) {
|
||||||
switch_frame_t frame = { 0 };
|
switch_frame_t frame = { 0 };
|
||||||
uint8_t buf[SWITCH_RTP_MAX_BUF_LEN];
|
|
||||||
uint32_t ts = 0;
|
uint32_t ts = 0;
|
||||||
uint16_t seq = 0;
|
uint16_t seq = 0;
|
||||||
|
|
||||||
|
@ -856,12 +866,12 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||||
frame.buflen = sizeof(buf);
|
frame.buflen = sizeof(buf);
|
||||||
|
|
||||||
if (globals.debug || context->debug) {
|
if (globals.debug || context->debug) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Missing %s %u Checking JB\n", seq ? "SEQ" : "TS", seq ? seq : ts);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Missing %s %u Checking JB\n", seq ? "SEQ" : "TS", seq ? seq : ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switch_jb_peek_frame(jb, ts, seq, 1, &frame) == SWITCH_STATUS_SUCCESS) {
|
if (switch_jb_peek_frame(jb, ts, seq, 1, &frame) == SWITCH_STATUS_SUCCESS) {
|
||||||
if (globals.debug || context->debug) {
|
if (globals.debug || context->debug) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Lookahead frame found: %u:%u\n",
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Lookahead frame found: %u:%u\n",
|
||||||
frame.timestamp, frame.seq);
|
frame.timestamp, frame.seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -873,10 +883,10 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||||
|
|
||||||
if (globals.debug || context->debug) {
|
if (globals.debug || context->debug) {
|
||||||
if (fec) {
|
if (fec) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FEC info available in packet with SEQ: %d LEN: %d\n",
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "FEC info available in packet with SEQ: %d LEN: %d\n",
|
||||||
frame.seq, frame.datalen);
|
frame.seq, frame.datalen);
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NO FEC info in this packet with SEQ: %d LEN: %d\n",
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "NO FEC info in this packet with SEQ: %d LEN: %d\n",
|
||||||
frame.seq, frame.datalen);
|
frame.seq, frame.datalen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -890,9 +900,9 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||||
|
|
||||||
if (globals.debug || context->debug) {
|
if (globals.debug || context->debug) {
|
||||||
if (opus_prefs.use_jb_lookahead || context->use_jb_lookahead) {
|
if (opus_prefs.use_jb_lookahead || context->use_jb_lookahead) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "MISSING FRAME: %s\n", fec ? "Look-ahead FEC" : "PLC");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MISSING FRAME: %s\n", fec ? "Look-ahead FEC" : "PLC");
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "MISSING FRAME: OPUS_PLC\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MISSING FRAME: OPUS_PLC\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -901,7 +911,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||||
|
|
||||||
if (globals.debug || context->debug > 1) {
|
if (globals.debug || context->debug > 1) {
|
||||||
int samplerate = context->dec_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000);
|
int samplerate = context->dec_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000);
|
||||||
switch_opus_info(encoded_data, encoded_data_len,
|
switch_opus_info(codec->session, encoded_data, encoded_data_len,
|
||||||
samplerate ? samplerate : codec->implementation->actual_samples_per_second,
|
samplerate ? samplerate : codec->implementation->actual_samples_per_second,
|
||||||
!encoded_data ? "PLC correction" : fec ? "FEC correction" : "decode");
|
!encoded_data ? "PLC correction" : fec ? "FEC correction" : "decode");
|
||||||
}
|
}
|
||||||
|
@ -918,9 +928,9 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||||
samples = opus_decode(context->decoder_object, encoded_data, encoded_data_len, decoded_data, frame_size, fec);
|
samples = opus_decode(context->decoder_object, encoded_data, encoded_data_len, decoded_data, frame_size, fec);
|
||||||
|
|
||||||
if (samples < 0) {
|
if (samples < 0) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Decoder Error: %s fs:%u plc:%s!\n",
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Decoder Error: %s fs:%u plc:%s!\n",
|
||||||
opus_strerror(samples), frame_size, plc ? "true" : "false");
|
opus_strerror(samples), frame_size, plc ? "true" : "false");
|
||||||
return SWITCH_STATUS_NOOP;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*decoded_data_len = samples * 2 * (!context->codec_settings.sprop_stereo ? codec->implementation->number_of_channels : 2);
|
*decoded_data_len = samples * 2 * (!context->codec_settings.sprop_stereo ? codec->implementation->number_of_channels : 2);
|
||||||
|
@ -962,7 +972,7 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec,
|
||||||
}
|
}
|
||||||
frame_size = (decoded_data_len / 2) / nb_frames;
|
frame_size = (decoded_data_len / 2) / nb_frames;
|
||||||
if((frame_size * nb_frames) != context->enc_frame_size) {
|
if((frame_size * nb_frames) != context->enc_frame_size) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Encoder Error: Decoded Datalen %u Number of frames: %u Encoder frame size: %u\n",decoded_data_len,nb_frames,context->enc_frame_size);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR,"Encoder Error: Decoded Datalen %u Number of frames: %u Encoder frame size: %u\n",decoded_data_len,nb_frames,context->enc_frame_size);
|
||||||
switch_goto_status(SWITCH_STATUS_GENERR, end);
|
switch_goto_status(SWITCH_STATUS_GENERR, end);
|
||||||
}
|
}
|
||||||
opus_repacketizer_init(rp);
|
opus_repacketizer_init(rp);
|
||||||
|
@ -982,7 +992,7 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec,
|
||||||
bytes = opus_encode(context->encoder_object, (opus_int16 *) dec_ptr_buf, frame_size, enc_ptr_buf, len);
|
bytes = opus_encode(context->encoder_object, (opus_int16 *) dec_ptr_buf, frame_size, enc_ptr_buf, len);
|
||||||
|
|
||||||
if (bytes < 0) {
|
if (bytes < 0) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder Error: %s Decoded Datalen %u Codec NumberChans %u" \
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Encoder Error: %s Decoded Datalen %u Codec NumberChans %u" \
|
||||||
"Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p enc_frame_size: %d\n",
|
"Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p enc_frame_size: %d\n",
|
||||||
opus_strerror(bytes), decoded_data_len, codec->implementation->number_of_channels, len,
|
opus_strerror(bytes), decoded_data_len, codec->implementation->number_of_channels, len,
|
||||||
(void *) decoded_data, (void *) encoded_data, (void *) context->encoder_object, context->enc_frame_size);
|
(void *) decoded_data, (void *) encoded_data, (void *) context->encoder_object, context->enc_frame_size);
|
||||||
|
@ -991,7 +1001,7 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec,
|
||||||
/* enc_ptr_buf : Opus API manual: "The application must ensure this pointer remains valid until the next call to opus_repacketizer_init() or opus_repacketizer_destroy()." */
|
/* enc_ptr_buf : Opus API manual: "The application must ensure this pointer remains valid until the next call to opus_repacketizer_init() or opus_repacketizer_destroy()." */
|
||||||
ret = opus_repacketizer_cat(rp, enc_ptr_buf, bytes);
|
ret = opus_repacketizer_cat(rp, enc_ptr_buf, bytes);
|
||||||
if (ret != OPUS_OK) {
|
if (ret != OPUS_OK) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (cat) : %s !\n",opus_strerror(ret));
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (cat) : %s !\n",opus_strerror(ret));
|
||||||
switch_goto_status(SWITCH_STATUS_GENERR, end);
|
switch_goto_status(SWITCH_STATUS_GENERR, end);
|
||||||
}
|
}
|
||||||
enc_ptr_buf += bytes;
|
enc_ptr_buf += bytes;
|
||||||
|
@ -1000,18 +1010,18 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec,
|
||||||
}
|
}
|
||||||
/* this will never happen, unless there is a huge and unsupported number of frames */
|
/* this will never happen, unless there is a huge and unsupported number of frames */
|
||||||
if (total_len + opus_repacketizer_get_nb_frames(rp) > len / 2) {
|
if (total_len + opus_repacketizer_get_nb_frames(rp) > len / 2) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing: not enough buffer space\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing: not enough buffer space\n");
|
||||||
switch_goto_status(SWITCH_STATUS_GENERR, end);
|
switch_goto_status(SWITCH_STATUS_GENERR, end);
|
||||||
}
|
}
|
||||||
ret = opus_repacketizer_out(rp, encoded_data, total_len+opus_repacketizer_get_nb_frames(rp));
|
ret = opus_repacketizer_out(rp, encoded_data, total_len+opus_repacketizer_get_nb_frames(rp));
|
||||||
|
|
||||||
if (globals.debug || context->debug) {
|
if (globals.debug || context->debug) {
|
||||||
int samplerate = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000);
|
int samplerate = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000);
|
||||||
switch_opus_info(encoded_data, ret, samplerate, "encode_repacketize");
|
switch_opus_info(codec->session, encoded_data, ret, samplerate, "encode_repacketize");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (out) : %s ! packed nb_frames: %d\n", opus_strerror(ret), opus_repacketizer_get_nb_frames(rp));
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (out) : %s ! packed nb_frames: %d\n", opus_strerror(ret), opus_repacketizer_get_nb_frames(rp));
|
||||||
switch_goto_status(SWITCH_STATUS_GENERR, end);
|
switch_goto_status(SWITCH_STATUS_GENERR, end);
|
||||||
}
|
}
|
||||||
if (want_fec) {
|
if (want_fec) {
|
||||||
|
@ -1052,25 +1062,25 @@ static switch_status_t opus_load_config(switch_bool_t reload)
|
||||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
char *val = (char *) switch_xml_attr_soft(param, "value");
|
||||||
|
|
||||||
if (!strcasecmp(key, "use-vbr") && !zstr(val)) {
|
if (!strcasecmp(key, "use-vbr") && !zstr(val)) {
|
||||||
opus_prefs.use_vbr = atoi(val);
|
opus_prefs.use_vbr = switch_true(val);
|
||||||
} else if (!strcasecmp(key, "use-dtx")) {
|
} else if (!strcasecmp(key, "use-dtx")) {
|
||||||
opus_prefs.use_dtx = atoi(val);
|
opus_prefs.use_dtx = switch_true(val);
|
||||||
} else if (!strcasecmp(key, "complexity")) {
|
} else if (!strcasecmp(key, "complexity")) {
|
||||||
opus_prefs.complexity = atoi(val);
|
opus_prefs.complexity = atoi(val);
|
||||||
} else if (!strcasecmp(key, "packet-loss-percent")) {
|
} else if (!strcasecmp(key, "packet-loss-percent")) {
|
||||||
opus_prefs.plpct = atoi(val);
|
opus_prefs.plpct = atoi(val);
|
||||||
} else if (!strcasecmp(key, "asymmetric-sample-rates")) {
|
} else if (!strcasecmp(key, "asymmetric-sample-rates")) {
|
||||||
opus_prefs.asymmetric_samplerates = atoi(val);
|
opus_prefs.asymmetric_samplerates = switch_true(val);
|
||||||
} else if (!strcasecmp(key, "bitrate-negotiation")) {
|
} else if (!strcasecmp(key, "bitrate-negotiation")) {
|
||||||
opus_prefs.bitrate_negotiation = atoi(val);
|
opus_prefs.bitrate_negotiation = switch_true(val);
|
||||||
} else if (!strcasecmp(key, "use-jb-lookahead")) {
|
} else if (!strcasecmp(key, "use-jb-lookahead")) {
|
||||||
opus_prefs.use_jb_lookahead = switch_true(val);
|
opus_prefs.use_jb_lookahead = switch_true(val);
|
||||||
} else if (!strcasecmp(key, "keep-fec-enabled")) { /* encoder */
|
} else if (!strcasecmp(key, "keep-fec-enabled")) { /* encoder */
|
||||||
opus_prefs.keep_fec = atoi(val);
|
opus_prefs.keep_fec = switch_true(val);
|
||||||
} else if (!strcasecmp(key, "advertise-useinbandfec")) { /*decoder, has meaning only for FMTP: useinbandfec=1 by default */
|
} else if (!strcasecmp(key, "advertise-useinbandfec")) { /*decoder, has meaning only for FMTP: useinbandfec=1 by default */
|
||||||
opus_prefs.fec_decode = atoi(val);
|
opus_prefs.fec_decode = switch_true(val);
|
||||||
} else if (!strcasecmp(key, "adjust-bitrate")) { /* encoder, this setting will make the encoder adjust its bitrate based on a feedback loop (RTCP). This is not "VBR".*/
|
} else if (!strcasecmp(key, "adjust-bitrate")) { /* encoder, this setting will make the encoder adjust its bitrate based on a feedback loop (RTCP). This is not "VBR".*/
|
||||||
opus_prefs.adjust_bitrate = atoi(val);
|
opus_prefs.adjust_bitrate = switch_true(val);
|
||||||
} else if (!strcasecmp(key, "maxaveragebitrate")) {
|
} else if (!strcasecmp(key, "maxaveragebitrate")) {
|
||||||
opus_prefs.maxaveragebitrate = atoi(val);
|
opus_prefs.maxaveragebitrate = atoi(val);
|
||||||
if (opus_prefs.maxaveragebitrate < SWITCH_OPUS_MIN_BITRATE || opus_prefs.maxaveragebitrate > SWITCH_OPUS_MAX_BITRATE) {
|
if (opus_prefs.maxaveragebitrate < SWITCH_OPUS_MIN_BITRATE || opus_prefs.maxaveragebitrate > SWITCH_OPUS_MAX_BITRATE) {
|
||||||
|
@ -1087,7 +1097,7 @@ static switch_status_t opus_load_config(switch_bool_t reload)
|
||||||
opus_prefs.sprop_maxcapturerate = 0; /* value not supported */
|
opus_prefs.sprop_maxcapturerate = 0; /* value not supported */
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(key, "mono")) {
|
} else if (!strcasecmp(key, "mono")) {
|
||||||
opus_prefs.mono = atoi(val);
|
opus_prefs.mono = switch_true(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1132,7 +1142,7 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec)
|
||||||
LBRR_threshold_bitrate = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16);
|
LBRR_threshold_bitrate = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16);
|
||||||
|
|
||||||
if (!real_target_bitrate || !LBRR_threshold_bitrate) {
|
if (!real_target_bitrate || !LBRR_threshold_bitrate) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while controlling FEC params\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while controlling FEC params\n");
|
||||||
|
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1141,7 +1151,7 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec)
|
||||||
if (real_target_bitrate > LBRR_threshold_bitrate) {
|
if (real_target_bitrate > LBRR_threshold_bitrate) {
|
||||||
/*FEC is already enabled, do nothing*/
|
/*FEC is already enabled, do nothing*/
|
||||||
if (globals.debug || context->debug) {
|
if (globals.debug || context->debug) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: FEC is enabled\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: FEC is enabled\n");
|
||||||
}
|
}
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1153,13 +1163,40 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec)
|
||||||
opus_encoder_ctl(context->encoder_object,OPUS_SET_BITRATE(current_bitrate));
|
opus_encoder_ctl(context->encoder_object,OPUS_SET_BITRATE(current_bitrate));
|
||||||
|
|
||||||
if (globals.debug || context->debug) {
|
if (globals.debug || context->debug) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: increased bitrate to [%d] to keep FEC enabled\n", current_bitrate);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: increased bitrate to [%d] to keep FEC enabled\n", current_bitrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static switch_bool_t switch_opus_vad(struct opus_context *context, void *encoded_data, uint32_t encoded_data_len)
|
||||||
|
{
|
||||||
|
const uint8_t *payload = (const uint8_t *)encoded_data;
|
||||||
|
opus_packet_info_t opus_packet_info;
|
||||||
|
switch_bool_t debug = (globals.debug || context->debug > 1);
|
||||||
|
|
||||||
|
if (!switch_opus_packet_parse(payload, encoded_data_len, &opus_packet_info, debug)) {
|
||||||
|
if (debug) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "OPUS PACKET PARSING ERROR len:%d bytes:%02x %02x\n",
|
||||||
|
(int)encoded_data_len, payload[0], payload[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "OPUS EXTRACT PAYLOAD VAD len:%d vad_ms:%d bytes:%02x %02x\n",
|
||||||
|
(int)encoded_data_len, opus_packet_info.vad_ms, payload[0], payload[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opus_packet_info.vad_ms == 0) {
|
||||||
|
return SWITCH_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static switch_status_t switch_opus_control(switch_codec_t *codec,
|
static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||||
switch_codec_control_command_t cmd,
|
switch_codec_control_command_t cmd,
|
||||||
switch_codec_control_type_t ctype,
|
switch_codec_control_type_t ctype,
|
||||||
|
@ -1229,7 +1266,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globals.debug || context->debug) {
|
if (globals.debug || context->debug) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting packet loss percent from %d%% to %d%%!\n",
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting packet loss percent from %d%% to %d%%!\n",
|
||||||
context->old_plpct, plpct);
|
context->old_plpct, plpct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1243,7 +1280,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||||
float steps = (float)((float)(range / 100) / base_step);
|
float steps = (float)((float)(range / 100) / base_step);
|
||||||
int br_step = (int)(round(steps) * base_step) * plpct;
|
int br_step = (int)(round(steps) * base_step) * plpct;
|
||||||
if (globals.debug || context->debug) {
|
if (globals.debug || context->debug) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG,
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session),
|
||||||
SWITCH_LOG_DEBUG, "Opus encoder: bitrate increase/decrease step now is: %d bps, range:%d\n", br_step, range);
|
SWITCH_LOG_DEBUG, "Opus encoder: bitrate increase/decrease step now is: %d bps, range:%d\n", br_step, range);
|
||||||
}
|
}
|
||||||
context->control_state.increase_step = context->control_state.decrease_step = br_step;
|
context->control_state.increase_step = context->control_state.decrease_step = br_step;
|
||||||
|
@ -1251,6 +1288,15 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||||
context->old_plpct = plpct;
|
context->old_plpct = plpct;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SCC_AUDIO_VAD:
|
||||||
|
{
|
||||||
|
void *encoded_data = (void *)cmd_data;
|
||||||
|
uint16_t *encoded_data_len = (uint16_t *)cmd_arg;
|
||||||
|
switch_bool_t *ret = (switch_bool_t *)*ret_data;
|
||||||
|
|
||||||
|
*ret = switch_opus_vad(context, encoded_data, *encoded_data_len);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCC_AUDIO_ADJUST_BITRATE:
|
case SCC_AUDIO_ADJUST_BITRATE:
|
||||||
{
|
{
|
||||||
const char *cmd = (const char *)cmd_data;
|
const char *cmd = (const char *)cmd_data;
|
||||||
|
@ -1269,7 +1315,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||||
opus_prefs.keep_fec = 1; /* enable back FEC if it was disabled by SCC_AUDIO_ADJUST_BITRATE, we have enough network bandwidth now */
|
opus_prefs.keep_fec = 1; /* enable back FEC if it was disabled by SCC_AUDIO_ADJUST_BITRATE, we have enough network bandwidth now */
|
||||||
}
|
}
|
||||||
if (globals.debug || context->debug) {
|
if (globals.debug || context->debug) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (increase)\n", current_bitrate+br_step);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (increase)\n", current_bitrate+br_step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(cmd, "decrease")) {
|
} else if (!strcasecmp(cmd, "decrease")) {
|
||||||
|
@ -1283,7 +1329,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||||
}
|
}
|
||||||
opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(current_bitrate-br_step));
|
opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(current_bitrate-br_step));
|
||||||
if (globals.debug || context->debug) {
|
if (globals.debug || context->debug) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (decrease)\n", current_bitrate-br_step);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (decrease)\n", current_bitrate-br_step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(cmd, "default")) {
|
} else if (!strcasecmp(cmd, "default")) {
|
||||||
|
@ -1293,7 +1339,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||||
opus_prefs.keep_fec = 1; /* enable back FEC, we have enough network bandwidth now */
|
opus_prefs.keep_fec = 1; /* enable back FEC, we have enough network bandwidth now */
|
||||||
}
|
}
|
||||||
if (globals.debug || context->debug) {
|
if (globals.debug || context->debug) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (configured maxaveragebitrate)\n", opus_prefs.maxaveragebitrate);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (configured maxaveragebitrate)\n", opus_prefs.maxaveragebitrate);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* set Opus minimum bitrate */
|
/* set Opus minimum bitrate */
|
||||||
|
@ -1302,7 +1348,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||||
opus_prefs.keep_fec = 0; /* do not enforce FEC anymore, we're low on network bandwidth */
|
opus_prefs.keep_fec = 0; /* do not enforce FEC anymore, we're low on network bandwidth */
|
||||||
}
|
}
|
||||||
if (globals.debug || context->debug) {
|
if (globals.debug || context->debug) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (minimum)\n", SWITCH_OPUS_MIN_BITRATE);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (minimum)\n", SWITCH_OPUS_MIN_BITRATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1340,7 +1386,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
|
||||||
{
|
{
|
||||||
switch_codec_interface_t *codec_interface;
|
switch_codec_interface_t *codec_interface;
|
||||||
switch_api_interface_t *commands_api_interface;
|
switch_api_interface_t *commands_api_interface;
|
||||||
int samples = 480;
|
int samples = 480; /* start with 10 ms ptime */
|
||||||
int bytes = 960;
|
int bytes = 960;
|
||||||
int mss = 10000;
|
int mss = 10000;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
@ -1441,7 +1487,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 16 khz */
|
/* 16 khz */
|
||||||
samples = 480;
|
samples = 160;
|
||||||
bytes = 320;
|
bytes = 320;
|
||||||
mss = 10000;
|
mss = 10000;
|
||||||
rate = 16000;
|
rate = 16000;
|
||||||
|
@ -1538,7 +1584,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 8 khz */
|
/* 8 khz */
|
||||||
samples = 480;
|
samples = 80;
|
||||||
bytes = 160;
|
bytes = 160;
|
||||||
mss = 10000;
|
mss = 10000;
|
||||||
rate = 8000;
|
rate = 8000;
|
||||||
|
|
|
@ -0,0 +1,401 @@
|
||||||
|
/*
|
||||||
|
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||||
|
* Copyright (C) 2005-2023, Anthony Minessale II <anthm@freeswitch.org>
|
||||||
|
*
|
||||||
|
* Version: MPL 1.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
|
* Portions created by the Initial Developer are Copyright (C)
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Claude Lamblin
|
||||||
|
* Julien Chavanton <jchavanton@gmail.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "switch.h"
|
||||||
|
#include "opus.h"
|
||||||
|
#include "opus_parse.h"
|
||||||
|
/* Tables for LBRR_sympbol decoding */
|
||||||
|
|
||||||
|
static const opus_int16 silk_LBRR_flags_2_PDFCum[3] = { 53, 106, 256 }; /* 256 - silk_LBRR_flags_2_iCDF[i] ; silk_LBRR_flags_2_iCDF[ 3 ] = { 203, 150, 0 }; */
|
||||||
|
static const opus_int16 silk_LBRR_flags_3_PDFCum[7] = { 41, 61, 90, 131, 146, 174, 256 }; /* 256 - silk_LBRR_flags_3_iCDF[i] ; silk_LBRR_flags_3_iCDF[ 7 ] = { 215, 195, 166, 125, 110, 82, 0 }; */
|
||||||
|
|
||||||
|
/* Get the number of VAD flags - i.e. number of 20 ms frame - from the config
|
||||||
|
* in a silk-only or hybrid opus frame mono or stereo
|
||||||
|
* 5 MSB TOC byte (see table 2 of IETF RFC6716 clause 3.1)
|
||||||
|
* if 10 ms frame (config=0, 4, 8, 12, 14) : return 1
|
||||||
|
* if CELT_only frame no VAD flag =>return 0 */
|
||||||
|
static opus_int16 switch_opus_get_nb_flags_in_silk_frame(int16_t config)
|
||||||
|
{
|
||||||
|
opus_int16 silk_frame_nb_flags;
|
||||||
|
|
||||||
|
if (config > 15) {
|
||||||
|
/* CELT_only frame no VAD flag nor LBRR flag */
|
||||||
|
silk_frame_nb_flags = 0;
|
||||||
|
} else {
|
||||||
|
silk_frame_nb_flags = 1; /* default */
|
||||||
|
|
||||||
|
if (config < 12) {
|
||||||
|
/* silk-only NB, MB or WB
|
||||||
|
* The least two significant bits give the number of VAD flags inside the silk frame 1, 2 or 3 */
|
||||||
|
silk_frame_nb_flags = config & 0x3;
|
||||||
|
|
||||||
|
if (silk_frame_nb_flags == 0) { /* 0 => 10ms frame : one VAD flag */
|
||||||
|
silk_frame_nb_flags++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return silk_frame_nb_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the time in ms corresponding to one VAD flag from the config
|
||||||
|
* in a silk-only or hybrid opus frame mono or stereo
|
||||||
|
* 5 MSB TOC byte (see table 2 of IETF RFC6716 clause 3.1)
|
||||||
|
* if CELT_only frame (config >15) no VAD flag =>return FALSE
|
||||||
|
* if 10 ms frame (config=0, 4, 8, 12, 14) : return 10
|
||||||
|
* otherwise return 20 */
|
||||||
|
static opus_int16 switch_opus_get_silk_frame_ms_per_flag(int16_t config, opus_int16 silk_frame_nb_flags)
|
||||||
|
{
|
||||||
|
opus_int16 silk_size_frame_ms_per_flag;
|
||||||
|
|
||||||
|
if (config > 15) {
|
||||||
|
/* CELT_only frame no VAD flag nor LBRR flag */
|
||||||
|
/* switch_opus_get_silk_frame_ms_per_flag: code not written for CELT-only mode */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
silk_size_frame_ms_per_flag = 20; /* default*/
|
||||||
|
if (silk_frame_nb_flags == 1) { /* could be 10 or 20 ms */
|
||||||
|
if ((config & 0x01) == 0) {
|
||||||
|
silk_size_frame_ms_per_flag = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return silk_size_frame_ms_per_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code written only for mono, silk-only or hybrid mode
|
||||||
|
* for CELT-only frame no vad flags for LBRR flag the routine must not be called
|
||||||
|
* for stereo : the mid frame VAD_flags and the LBRR_flag could be obtained
|
||||||
|
* yet, to get the LBRR_flags of the mid frame the routine should be modified
|
||||||
|
* to skip the side VAD flags and the side LBRR flag and to get the mid LBRR_symbol */
|
||||||
|
static void switch_opus_get_VAD_LBRR_flags(const uint8_t *buf, opus_int16 silk_frame_nb_flags,
|
||||||
|
opus_int16 *VAD_flags, opus_int16 *LBRR_flags, opus_int16 *nb_VAD1, opus_int16 *nb_FEC)
|
||||||
|
{
|
||||||
|
const opus_int16 *ptr_pdf_cum;
|
||||||
|
opus_int nb_pdf_symbol;
|
||||||
|
opus_uint16 LBRR_symbol;
|
||||||
|
opus_int16 val, nb_bit, compl_nb_bit, mask, mask2;
|
||||||
|
opus_int16 *ptr_flags;
|
||||||
|
opus_int16 LBRR_flag;
|
||||||
|
opus_int16 nb_vad, nb_fec;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nb_vad = 0;
|
||||||
|
nb_fec = 0;
|
||||||
|
|
||||||
|
/* Get VAD_FLAGS & LBRR_FLAG
|
||||||
|
* silk_frame_nb_flags = 1 (10 or 20 ms), the two MSB of the first byte are the VAD flag and the LBRR flag
|
||||||
|
* silk_frame_nb_flags = 2 (40 ms), the three MSB of the first byte are the two VAD flags and the LBRR flag
|
||||||
|
* silk_frame_nb_flags = 3 (60 ms), the four MSB of the first byte are the three VAD flags and the LBRR flag
|
||||||
|
* compute the number of MSB to analyze */
|
||||||
|
nb_bit = silk_frame_nb_flags + 1;
|
||||||
|
|
||||||
|
/* number of right shifts to apply to the first byte to only have the bits of LBRR flag and of the VAD flags */
|
||||||
|
compl_nb_bit = 8 - nb_bit;
|
||||||
|
mask = (1 << nb_bit) - 1;
|
||||||
|
|
||||||
|
/* The bits of the silk_frame_nb_flags VAD flags and the LBRR flag are the MSB of the first byte
|
||||||
|
* silk_frame_nb_flags = 1 (10 or 20 ms), VAD_flags(0) | LBRR_flag
|
||||||
|
* silk_frame_nb_flags = 2 (40 ms), VAD_flags(0) | VAD_flags(1) | LBRR_flag
|
||||||
|
* silk_frame_nb_flags = 3 (60 ms), VAD_flags(0) | VAD_flags(1) | VAD_flags(2) |LBRR_flag */
|
||||||
|
val = (buf[0] >> compl_nb_bit) & mask;
|
||||||
|
|
||||||
|
LBRR_flag = val & 0x1; /* LBRR_FLAG LSB */
|
||||||
|
|
||||||
|
/* get VAD_flags */
|
||||||
|
ptr_flags = VAD_flags + silk_frame_nb_flags;
|
||||||
|
for (i = 0; i < silk_frame_nb_flags; i++) {
|
||||||
|
LBRR_flags[i] = 0; /* init */
|
||||||
|
val >>= 1;
|
||||||
|
*(--ptr_flags) = val & 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LBRR_flag != 0) { /* there is at least one LBRR frame */
|
||||||
|
if (silk_frame_nb_flags == 1) {
|
||||||
|
LBRR_flags[0] = 1;
|
||||||
|
nb_fec = 1;
|
||||||
|
} else { /* get LBRR_symbol then LBRR_flags */
|
||||||
|
/* LBRR symbol is encoded with range encoder : range on 8 bits
|
||||||
|
* silk_frame_nb_flags = 2 ; 3 possible values for LBRR_flags(1) | LBRR_flags(0))= 01, 10, 11
|
||||||
|
* silk_frame_nb_flags = 3 ; 7 possible values for LBRR_flags(2) | LBRR_flags(1) | LBRR_flags(0))= 001, 010, 011, 100, 101, 110, 111 */
|
||||||
|
mask2 = (1 << compl_nb_bit) - 1;
|
||||||
|
/* get next 8 bits: (8-nb_bit) LSB of the first byte and nb_bit MSB of the second byte */
|
||||||
|
val = (((buf[0]) & mask2) << nb_bit) | ((buf[1] >> compl_nb_bit) & mask);
|
||||||
|
|
||||||
|
if (silk_frame_nb_flags == 2) {
|
||||||
|
nb_pdf_symbol = 3;
|
||||||
|
ptr_pdf_cum = silk_LBRR_flags_2_PDFCum;
|
||||||
|
} else {
|
||||||
|
nb_pdf_symbol = 7;
|
||||||
|
ptr_pdf_cum = silk_LBRR_flags_3_PDFCum;
|
||||||
|
}
|
||||||
|
|
||||||
|
LBRR_symbol = 0;
|
||||||
|
for (i = 1; i <= nb_pdf_symbol; i++) {
|
||||||
|
if (val < *ptr_pdf_cum++) {
|
||||||
|
LBRR_symbol = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < silk_frame_nb_flags; i++) {
|
||||||
|
LBRR_flags[i] = LBRR_symbol & 0x01;
|
||||||
|
LBRR_symbol >>= 1;
|
||||||
|
nb_fec += LBRR_flags[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < silk_frame_nb_flags; i++) {
|
||||||
|
nb_vad += VAD_flags[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
*nb_VAD1 = nb_vad;
|
||||||
|
*nb_FEC = nb_fec;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse the packet to retrieve informations about its content
|
||||||
|
* RFC6716: Definition of the Opus Audio Codec
|
||||||
|
* return: SWITCH_FALSE if there was a problem found parsing the packet, the info returned should be ignored.
|
||||||
|
* */
|
||||||
|
switch_bool_t switch_opus_packet_parse(const uint8_t *payload, int payload_length_bytes, opus_packet_info_t *packet_info, switch_bool_t debug)
|
||||||
|
{
|
||||||
|
int f;
|
||||||
|
int32_t samplerate;
|
||||||
|
int i, shift_silk, silk_frame_packet;
|
||||||
|
int16_t vad_flags_per_silk_frame, fec_flags_per_silk_frame;
|
||||||
|
opus_int16 frame_sizes[48];
|
||||||
|
const unsigned char *frame_data[48];
|
||||||
|
opus_int16 packet_LBBR_FLAGS[3 * 48], packet_VAD_FLAGS[3 * 48];
|
||||||
|
opus_int16 *ptr_LBBR_FLAGS, *ptr_VAD_FLAGS;
|
||||||
|
opus_int16 silk_frame_nb_flags, silk_size_frame_ms_per_flag;
|
||||||
|
opus_int16 silk_frame_nb_fec, silk_frame_nb_vad1;
|
||||||
|
opus_int sample_per_frame;
|
||||||
|
|
||||||
|
packet_info->config = 0;
|
||||||
|
packet_info->fec = 0;
|
||||||
|
packet_info->fec_ms = 0;
|
||||||
|
packet_info->vad = 0;
|
||||||
|
packet_info->vad_ms = 0;
|
||||||
|
packet_info->stereo = FALSE;
|
||||||
|
packet_info->frames = 0;
|
||||||
|
packet_info->channels = 1; /* as stereo is set to FALSE */
|
||||||
|
packet_info->ms_per_frame = 0;
|
||||||
|
packet_info->ptime_ts = 0;
|
||||||
|
|
||||||
|
if (payload == NULL || payload_length_bytes <= 0) {
|
||||||
|
if (debug) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: payload null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In CELT_ONLY mode, packets should not have FEC. */
|
||||||
|
if (payload[0] & 0x80) {
|
||||||
|
/* opus_packet_parse: CELT_ONLY mode, we do not support this mode. */
|
||||||
|
return SWITCH_FALSE;
|
||||||
|
} else {
|
||||||
|
int mode = (payload[0] >> 3);
|
||||||
|
|
||||||
|
if (mode <= 3) {
|
||||||
|
samplerate = 8000;
|
||||||
|
} else if (mode <= 7) {
|
||||||
|
samplerate = 12000;
|
||||||
|
} else if (mode <= 11) {
|
||||||
|
samplerate = 16000;
|
||||||
|
} else if (mode <= 13) {
|
||||||
|
samplerate = 24000;
|
||||||
|
} else if (mode <= 15) {
|
||||||
|
samplerate = 48000;
|
||||||
|
} else {
|
||||||
|
/* opus_packet_parse: CELT_ONLY mode, we do not support this mode. */
|
||||||
|
return SWITCH_FALSE;
|
||||||
|
}
|
||||||
|
if (debug) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: mode[%d]s[%d]c[%d] [%d]Hz\n", mode, (payload[0] >> 2) & 0x1, (payload[0]) & 0x3, samplerate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload[0] & 0x04) {
|
||||||
|
packet_info->stereo = TRUE;
|
||||||
|
packet_info->channels = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
packet_info->config = payload[0] >> 3;
|
||||||
|
sample_per_frame = opus_packet_get_samples_per_frame(payload, samplerate);
|
||||||
|
packet_info->ms_per_frame = sample_per_frame * 1000 / samplerate;
|
||||||
|
if (packet_info->ms_per_frame < 10 || packet_info->ms_per_frame > 120) {
|
||||||
|
if (debug) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: invalid packet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
packet_info->frames = opus_packet_parse(payload, payload_length_bytes, NULL, frame_data, frame_sizes, NULL);
|
||||||
|
if (packet_info->frames < 0) {
|
||||||
|
packet_info->frames = 0;
|
||||||
|
if (debug) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: opus_packet_parse found no frame.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
packet_info->ptime_ts = packet_info->frames * sample_per_frame;
|
||||||
|
|
||||||
|
if (frame_sizes[0] <= 1) {
|
||||||
|
if (debug) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: opus_packet_parse frame size too small.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* +---------------+-----------+-----------+-------------------+
|
||||||
|
| Configuration | Mode | Bandwidth | Frame Sizes |
|
||||||
|
| Number(s) | | | |
|
||||||
|
+---------------+-----------+-----------+-------------------+
|
||||||
|
| 0...3 | SILK-only | NB | 10, 20, 40, 60 ms |
|
||||||
|
| 4...7 | SILK-only | MB | 10, 20, 40, 60 ms |
|
||||||
|
| 8...11 | SILK-only | WB | 10, 20, 40, 60 ms |
|
||||||
|
| 12...13 | Hybrid | SWB | 10, 20 ms |
|
||||||
|
| 14...15 | Hybrid | FB | 10, 20 ms |
|
||||||
|
| 16...19 | CELT-only | NB | 2.5, 5, 10, 20 ms |
|
||||||
|
| 20...23 | CELT-only | WB | 2.5, 5, 10, 20 ms |
|
||||||
|
| 24...27 | CELT-only | SWB | 2.5, 5, 10, 20 ms |
|
||||||
|
| 28...31 | CELT-only | FB | 2.5, 5, 10, 20 ms |
|
||||||
|
+---------------+-----------+-----------+-------------------+ */
|
||||||
|
|
||||||
|
if (!packet_info->stereo) {
|
||||||
|
/* The routines opus_get_nb_flags_in_silk_frame and opus_get_silk_frame_ms_per_flag are also valid for stereo frames
|
||||||
|
* yet the routine opus_get_VAD_LBRR_flags is currently only for mono frame */
|
||||||
|
silk_frame_nb_flags = switch_opus_get_nb_flags_in_silk_frame(packet_info->config); /* =1 for 10 or 20 ms frame; = 2 for 40 ms; = 3 for 60 ms */
|
||||||
|
if (!silk_frame_nb_flags) {
|
||||||
|
/* We should not go there as CELT_ONLY is already tested above */
|
||||||
|
return SWITCH_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
packet_info->frames_silk = silk_frame_nb_flags;
|
||||||
|
silk_size_frame_ms_per_flag = switch_opus_get_silk_frame_ms_per_flag(packet_info->config, silk_frame_nb_flags); /* 10 or 20 ms frame*/
|
||||||
|
if (!silk_size_frame_ms_per_flag) {
|
||||||
|
/* we should not go there as CELT_ONLY is already tested above */
|
||||||
|
return SWITCH_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr_LBBR_FLAGS = packet_LBBR_FLAGS;
|
||||||
|
ptr_VAD_FLAGS = packet_VAD_FLAGS;
|
||||||
|
|
||||||
|
for (f = 0; f < packet_info->frames; f++) {
|
||||||
|
switch_opus_get_VAD_LBRR_flags(frame_data[f], silk_frame_nb_flags, ptr_VAD_FLAGS, ptr_LBBR_FLAGS,
|
||||||
|
&silk_frame_nb_vad1, &silk_frame_nb_fec);
|
||||||
|
packet_info->vad += silk_frame_nb_vad1;
|
||||||
|
packet_info->fec += silk_frame_nb_fec;
|
||||||
|
packet_info->vad_ms += silk_frame_nb_vad1 * silk_size_frame_ms_per_flag;
|
||||||
|
packet_info->fec_ms += silk_frame_nb_fec * silk_size_frame_ms_per_flag;
|
||||||
|
|
||||||
|
ptr_VAD_FLAGS += silk_frame_nb_flags;
|
||||||
|
ptr_LBBR_FLAGS += silk_frame_nb_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* store the VAD & LBRR flags of all 20 ms silk-frames of the packet; LSB the first frame, MSB: the last */
|
||||||
|
vad_flags_per_silk_frame = 0;
|
||||||
|
fec_flags_per_silk_frame = 0;
|
||||||
|
silk_frame_packet = packet_info->frames * packet_info->frames_silk;
|
||||||
|
if (silk_frame_packet > 15) {
|
||||||
|
if (debug) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: more than %d 20-ms frames in the packet ; only first 15 silk-frames data will be stored (pb silkFastAccelerate)\n", silk_frame_packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
silk_frame_packet = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr_LBBR_FLAGS = packet_LBBR_FLAGS;
|
||||||
|
ptr_VAD_FLAGS = packet_VAD_FLAGS;
|
||||||
|
shift_silk = 0;
|
||||||
|
for (i = 0; i < silk_frame_packet; i++) {
|
||||||
|
vad_flags_per_silk_frame += (*ptr_VAD_FLAGS) << shift_silk;
|
||||||
|
fec_flags_per_silk_frame += (*ptr_LBBR_FLAGS) << shift_silk;
|
||||||
|
shift_silk++;
|
||||||
|
ptr_LBBR_FLAGS++; ptr_VAD_FLAGS++;
|
||||||
|
}
|
||||||
|
|
||||||
|
packet_info->vad_flags_per_silk_frame = vad_flags_per_silk_frame;
|
||||||
|
packet_info->fec_flags_per_silk_frame = fec_flags_per_silk_frame;
|
||||||
|
|
||||||
|
return SWITCH_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packet_info->config != 1 && packet_info->config != 5 && packet_info->config != 9) {
|
||||||
|
if (debug) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: the current parser implementation does not support muliple SILK frames for VAD or FEC detection.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the VAD and LBRR flags in each Opus frame
|
||||||
|
* */
|
||||||
|
for (f = 0; f < packet_info->frames; f++) {
|
||||||
|
if (frame_data[f][0] & 0x80) {
|
||||||
|
packet_info->vad++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame_data[f][0] & 0x40) {
|
||||||
|
packet_info->fec++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: LP layer opus_frame[%d] VAD[%d] FEC[%d]\n", f + 1, (frame_data[f][0] & 0x80) >> 7, (frame_data[f][0] & 0x40) >> 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
packet_info->vad_ms = packet_info->vad * packet_info->ms_per_frame;
|
||||||
|
packet_info->fec_ms = packet_info->fec * packet_info->ms_per_frame;
|
||||||
|
|
||||||
|
return SWITCH_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
|
||||||
|
*/
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||||
|
* Copyright (C) 2005-2023, Anthony Minessale II <anthm@freeswitch.org>
|
||||||
|
*
|
||||||
|
* Version: MPL 1.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
|
* Portions created by the Initial Developer are Copyright (C)
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Julien Chavanton <jchavanton@gmail.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SWITCH_OPUS_PARSE_H
|
||||||
|
#define SWITCH_OPUS_PARSE_H
|
||||||
|
|
||||||
|
typedef enum { false, true } bool_t;
|
||||||
|
|
||||||
|
typedef struct opus_packet_info {
|
||||||
|
int16_t vad;
|
||||||
|
int16_t vad_ms;
|
||||||
|
int16_t fec;
|
||||||
|
int16_t fec_ms;
|
||||||
|
bool_t stereo;
|
||||||
|
/* number of opus frames in the packet */
|
||||||
|
int16_t frames;
|
||||||
|
int16_t config;
|
||||||
|
int16_t channels;
|
||||||
|
int16_t ms_per_frame;
|
||||||
|
int32_t ptime_ts;
|
||||||
|
bool_t valid;
|
||||||
|
/* number of silk_frames in an opus frame */
|
||||||
|
int16_t frames_silk;
|
||||||
|
/* VAD flag of all 20 ms silk-frames of the packet; LSB the first frame, MSB: the last */
|
||||||
|
int16_t vad_flags_per_silk_frame;
|
||||||
|
/* LBRR (FEC) flag of all 20 ms silk-frames of the packet; LSB the first frame, MSB: the last */
|
||||||
|
int16_t fec_flags_per_silk_frame;
|
||||||
|
} opus_packet_info_t;
|
||||||
|
|
||||||
|
switch_bool_t switch_opus_packet_parse(const uint8_t *payload, int payload_length_bytes, opus_packet_info_t *packet_info, switch_bool_t debug);
|
||||||
|
|
||||||
|
#endif /* SWITCH_OPUS_PARSE_H */
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
|
||||||
|
*/
|
|
@ -411,7 +411,7 @@ switch_status_t mariadb_finish_results_real(const char* file, const char* func,
|
||||||
if ((status = mysql_next_result(&handle->con))) {
|
if ((status = mysql_next_result(&handle->con))) {
|
||||||
if (status > 0) {
|
if (status > 0) {
|
||||||
err_str = mariadb_handle_get_error(handle);
|
err_str = mariadb_handle_get_error(handle);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to get next for query (%s): %s\n", handle->sql, err_str);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to get next for query (%s): %s\n", handle->sql, switch_str_nil(err_str));
|
||||||
switch_safe_free(err_str);
|
switch_safe_free(err_str);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -627,13 +627,27 @@ switch_status_t mariadb_send_query(mariadb_handle_t *handle, const char* sql)
|
||||||
{
|
{
|
||||||
char *err_str;
|
char *err_str;
|
||||||
int ret;
|
int ret;
|
||||||
|
unsigned retries = 60; /* 60 tries, will take 30 to 60 seconds at worst */
|
||||||
|
|
||||||
switch_safe_free(handle->sql);
|
switch_safe_free(handle->sql);
|
||||||
handle->sql = strdup(sql);
|
handle->sql = strdup(sql);
|
||||||
|
again:
|
||||||
handle->stored_results = 0;
|
handle->stored_results = 0;
|
||||||
ret = mysql_real_query(&handle->con, sql, (unsigned long)strlen(sql));
|
ret = mysql_real_query(&handle->con, sql, (unsigned long)strlen(sql));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
err_str = mariadb_handle_get_error(handle);
|
err_str = mariadb_handle_get_error(handle);
|
||||||
|
if (strstr(err_str, "Deadlock found when trying to get lock; try restarting transaction")) {
|
||||||
|
if (--retries > 0) {
|
||||||
|
switch_safe_free(err_str);
|
||||||
|
/* We are waiting for 500 ms and random time is not more than 500 ms.
|
||||||
|
This is necessary so that the delay on the primary and secondary servers does not coincide and deadlock does not occur again. */
|
||||||
|
switch_yield(500 + (rand() & 511));
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "DeadLock. The retries are over.\n");
|
||||||
|
}
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to send query (%s) to database: %s\n", sql, err_str);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to send query (%s) to database: %s\n", sql, err_str);
|
||||||
switch_safe_free(err_str);
|
switch_safe_free(err_str);
|
||||||
mariadb_finish_results(handle);
|
mariadb_finish_results(handle);
|
||||||
|
|
|
@ -113,7 +113,7 @@ static int db_is_up(switch_pgsql_handle_t *handle)
|
||||||
char *err_str = NULL;
|
char *err_str = NULL;
|
||||||
int max_tries = DEFAULT_PGSQL_RETRIES;
|
int max_tries = DEFAULT_PGSQL_RETRIES;
|
||||||
int code = 0;
|
int code = 0;
|
||||||
int recon = 0;
|
switch_status_t recon = SWITCH_STATUS_FALSE;
|
||||||
switch_byte_t sanity = 255;
|
switch_byte_t sanity = 255;
|
||||||
|
|
||||||
if (handle) {
|
if (handle) {
|
||||||
|
@ -128,6 +128,7 @@ top:
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Handle\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Handle\n");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!handle->con) {
|
if (!handle->con) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Connection\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Connection\n");
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -141,6 +142,7 @@ top:
|
||||||
switch_yield(1);
|
switch_yield(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +160,7 @@ reset:
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PQstatus returned bad connection -- reconnection failed!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PQstatus returned bad connection -- reconnection failed!\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->state = SWITCH_PGSQL_STATE_CONNECTED;
|
handle->state = SWITCH_PGSQL_STATE_CONNECTED;
|
||||||
handle->sock = PQsocket(handle->con);
|
handle->sock = PQsocket(handle->con);
|
||||||
}
|
}
|
||||||
|
@ -193,6 +196,7 @@ error:
|
||||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "The connection could not be re-established");
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "The connection could not be re-established");
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The connection could not be re-established\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The connection could not be re-established\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!max_tries) {
|
if (!max_tries) {
|
||||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "Giving up!");
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "Giving up!");
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Giving up!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Giving up!\n");
|
||||||
|
|
|
@ -142,6 +142,7 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt)
|
||||||
|
|
||||||
if (!caller_profile || zstr(caller_profile->destination_number)) {
|
if (!caller_profile || zstr(caller_profile->destination_number)) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Obtaining Profile!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Obtaining Profile!\n");
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,6 +151,7 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt)
|
||||||
if (!switch_config_open_file(&cfg, cf)) {
|
if (!switch_config_open_file(&cfg, cf)) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,12 +228,14 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (pattern && strcasecmp(pattern, field_data)) {
|
if (pattern && strcasecmp(pattern, field_data)) {
|
||||||
|
switch_safe_free(field_expanded);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cid) {
|
if (cid) {
|
||||||
if (strcasecmp(cid, caller_profile->caller_id_number)) {
|
if (strcasecmp(cid, caller_profile->caller_id_number)) {
|
||||||
|
switch_safe_free(field_expanded);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,15 +270,19 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt)
|
||||||
switch_perform_substitution(re, proceed, argument, field_data, substituted, sizeof(substituted), ovector);
|
switch_perform_substitution(re, proceed, argument, field_data, substituted, sizeof(substituted), ovector);
|
||||||
argument = substituted;
|
argument = substituted;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_regex_safe_free(re);
|
switch_regex_safe_free(re);
|
||||||
|
|
||||||
if (!extension) {
|
if (!extension) {
|
||||||
if (zstr(field_data)) {
|
if (zstr(field_data)) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No extension!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No extension!\n");
|
||||||
|
switch_safe_free(field_expanded);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((extension = switch_caller_extension_new(session, field_data, field_data)) == 0) {
|
if ((extension = switch_caller_extension_new(session, field_data, field_data)) == 0) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
|
||||||
|
switch_safe_free(field_expanded);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1429,7 +1429,7 @@ static switch_status_t null_tech_init(null_private_t *tech_pvt, switch_core_sess
|
||||||
// switch_core_media_check_video_codecs(session);
|
// switch_core_media_check_video_codecs(session);
|
||||||
// switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_AUDIO, 0);
|
// switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_AUDIO, 0);
|
||||||
// switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 0);
|
// switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 0);
|
||||||
// switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, "127.0.0.1", 2000, NULL, 0);
|
// switch_core_media_gen_local_sdp(session, SDP_OFFER, "127.0.0.1", 2000, NULL, 0);
|
||||||
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s\n", mparams.local_sdp_str);
|
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s\n", mparams.local_sdp_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1296,9 +1296,9 @@ error:
|
||||||
}
|
}
|
||||||
switch_mutex_unlock(endpoint->mutex);
|
switch_mutex_unlock(endpoint->mutex);
|
||||||
}
|
}
|
||||||
if (new_session && *new_session) {
|
|
||||||
switch_core_session_destroy(new_session);
|
switch_core_session_destroy(new_session);
|
||||||
}
|
|
||||||
return retcause;
|
return retcause;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x0090800 || !defined(SHA256_DIGEST_LENGTH)
|
#if OPENSSL_VERSION_NUMBER < 0x0090800 || !defined(SHA256_DIGEST_LENGTH)
|
||||||
#error Your OpenSSL is too old, need 0.9.8 or newer with SHA256
|
#error Your OpenSSL is too old, need 0.9.8 or newer with SHA256
|
||||||
#endif
|
#endif
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
#define HMAC_setup(ctx, key, len) HMAC_CTX_init(&ctx); HMAC_Init_ex(&ctx, key, len, EVP_sha256(), 0)
|
#define HMAC_setup(ctx, key, len) HMAC_CTX_init(&ctx); HMAC_Init_ex(&ctx, key, len, EVP_sha256(), 0)
|
||||||
#define HMAC_crunch(ctx, buf, len) HMAC_Update(&ctx, buf, len)
|
#define HMAC_crunch(ctx, buf, len) HMAC_Update(&ctx, buf, len)
|
||||||
|
@ -51,6 +52,7 @@
|
||||||
#define HMAC_crunch(ctx, buf, len)HMAC_Update(ctx, buf, len)
|
#define HMAC_crunch(ctx, buf, len)HMAC_Update(ctx, buf, len)
|
||||||
#define HMAC_finish(ctx, dig, dlen) HMAC_Final(ctx, dig, &dlen); HMAC_CTX_free(ctx)
|
#define HMAC_finish(ctx, dig, dlen) HMAC_Final(ctx, dig, &dlen); HMAC_CTX_free(ctx)
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define FP10
|
#define FP10
|
||||||
#define RTMP_SIG_SIZE 1536
|
#define RTMP_SIG_SIZE 1536
|
||||||
|
@ -155,9 +157,13 @@ static unsigned int GetDigestOffset1(uint8_t *handshake, unsigned int len)
|
||||||
static getoff *digoff[] = {GetDigestOffset1, GetDigestOffset2};
|
static getoff *digoff[] = {GetDigestOffset1, GetDigestOffset2};
|
||||||
// static getoff *dhoff[] = {GetDHOffset1, GetDHOffset2};
|
// static getoff *dhoff[] = {GetDHOffset1, GetDHOffset2};
|
||||||
|
|
||||||
static void HMACsha256(const uint8_t *message, size_t messageLen, const uint8_t *key, size_t keylen, uint8_t *digest)
|
static void HMACsha256(const uint8_t *message, size_t messageLen, const uint8_t *key, int keylen, uint8_t *digest)
|
||||||
{
|
{
|
||||||
unsigned int digestLen;
|
unsigned int digestLen;
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
HMAC(EVP_sha256(), key, keylen, (uint8_t *)message, messageLen, digest, &digestLen);
|
||||||
|
#else
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
HMAC_CTX ctx;
|
HMAC_CTX ctx;
|
||||||
#else
|
#else
|
||||||
|
@ -167,11 +173,12 @@ static void HMACsha256(const uint8_t *message, size_t messageLen, const uint8_t
|
||||||
HMAC_setup(ctx, key, (int)keylen);
|
HMAC_setup(ctx, key, (int)keylen);
|
||||||
HMAC_crunch(ctx, message, messageLen);
|
HMAC_crunch(ctx, message, messageLen);
|
||||||
HMAC_finish(ctx, digest, digestLen);
|
HMAC_finish(ctx, digest, digestLen);
|
||||||
|
#endif
|
||||||
|
|
||||||
assert(digestLen == 32);
|
assert(digestLen == 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CalculateDigest(unsigned int digestPos, uint8_t *handshakeMessage, const uint8_t *key, size_t keyLen, uint8_t *digest)
|
static void CalculateDigest(unsigned int digestPos, uint8_t *handshakeMessage, const uint8_t *key, int keyLen, uint8_t *digest)
|
||||||
{
|
{
|
||||||
const int messageLen = RTMP_SIG_SIZE - SHA256_DIGEST_LENGTH;
|
const int messageLen = RTMP_SIG_SIZE - SHA256_DIGEST_LENGTH;
|
||||||
uint8_t message[RTMP_SIG_SIZE - SHA256_DIGEST_LENGTH];
|
uint8_t message[RTMP_SIG_SIZE - SHA256_DIGEST_LENGTH];
|
||||||
|
@ -184,7 +191,7 @@ static void CalculateDigest(unsigned int digestPos, uint8_t *handshakeMessage, c
|
||||||
HMACsha256(message, messageLen, key, keyLen, digest);
|
HMACsha256(message, messageLen, key, keyLen, digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int VerifyDigest(unsigned int digestPos, uint8_t *handshakeMessage, const uint8_t *key, size_t keyLen)
|
static int VerifyDigest(unsigned int digestPos, uint8_t *handshakeMessage, const uint8_t *key, int keyLen)
|
||||||
{
|
{
|
||||||
uint8_t calcDigest[SHA256_DIGEST_LENGTH];
|
uint8_t calcDigest[SHA256_DIGEST_LENGTH];
|
||||||
|
|
||||||
|
|
|
@ -2136,7 +2136,7 @@ void launch_skinny_profile_thread(skinny_profile_t *profile) {
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* MODULE FUNCTIONS */
|
/* MODULE FUNCTIONS */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
switch_endpoint_interface_t *skinny_get_endpoint_interface()
|
switch_endpoint_interface_t *skinny_get_endpoint_interface(void)
|
||||||
{
|
{
|
||||||
return skinny_endpoint_interface;
|
return skinny_endpoint_interface;
|
||||||
}
|
}
|
||||||
|
|
|
@ -355,7 +355,7 @@ switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* MODULE FUNCTIONS */
|
/* MODULE FUNCTIONS */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
switch_endpoint_interface_t *skinny_get_endpoint_interface();
|
switch_endpoint_interface_t *skinny_get_endpoint_interface(void);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* TEXT FUNCTIONS */
|
/* TEXT FUNCTIONS */
|
||||||
|
|
|
@ -697,7 +697,7 @@ switch_status_t skinny_api_register(switch_loadable_module_interface_t **module_
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_status_t skinny_api_unregister()
|
switch_status_t skinny_api_unregister(void)
|
||||||
{
|
{
|
||||||
switch_console_set_complete("del skinny");
|
switch_console_set_complete("del skinny");
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#define _SKINNY_API_H
|
#define _SKINNY_API_H
|
||||||
|
|
||||||
switch_status_t skinny_api_register(switch_loadable_module_interface_t **module_interface);
|
switch_status_t skinny_api_register(switch_loadable_module_interface_t **module_interface);
|
||||||
switch_status_t skinny_api_unregister();
|
switch_status_t skinny_api_unregister(void);
|
||||||
|
|
||||||
#endif /* _SKINNY_API_H */
|
#endif /* _SKINNY_API_H */
|
||||||
|
|
||||||
|
|
|
@ -92,14 +92,14 @@ char* skinny_codec2string(skinny_codecs skinnycodec);
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#define skinny_create_message(message,msgtype,field) \
|
#define skinny_create_message(message,msgtype,field) \
|
||||||
message = calloc(1, 12 + sizeof(message->data.field)); \
|
message = calloc(1, sizeof(skinny_message_t)); \
|
||||||
message->type = msgtype; \
|
message->type = msgtype; \
|
||||||
message->length = 4 + sizeof(message->data.field)
|
message->length = 4 + sizeof(message->data.field)
|
||||||
|
|
||||||
#define skinny_create_empty_message(message,msgtype) \
|
#define skinny_create_empty_message(message,msgtype) \
|
||||||
message = calloc(1, 12); \
|
message = calloc(1, sizeof(skinny_empty_message_t)); \
|
||||||
message->type = msgtype; \
|
((skinny_empty_message_t *)message)->type = msgtype; \
|
||||||
message->length = 4
|
((skinny_empty_message_t *)message)->length = 4
|
||||||
|
|
||||||
|
|
||||||
/* KeepAliveMessage */
|
/* KeepAliveMessage */
|
||||||
|
@ -937,6 +937,12 @@ union skinny_data {
|
||||||
#pragma pack(push, r1, 1)
|
#pragma pack(push, r1, 1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct PACKED skinny_empty_message {
|
||||||
|
uint32_t length;
|
||||||
|
uint32_t version;
|
||||||
|
uint32_t type;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* header is length+version
|
* header is length+version
|
||||||
* body is type+data
|
* body is type+data
|
||||||
|
@ -954,6 +960,7 @@ struct PACKED skinny_message {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct skinny_message skinny_message_t;
|
typedef struct skinny_message skinny_message_t;
|
||||||
|
typedef struct skinny_empty_message skinny_empty_message_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ switch_endpoint_interface_t *sofia_endpoint_interface;
|
||||||
|
|
||||||
#define STRLEN 15
|
#define STRLEN 15
|
||||||
|
|
||||||
void mod_sofia_shutdown_cleanup();
|
void mod_sofia_shutdown_cleanup(void);
|
||||||
static switch_status_t sofia_on_init(switch_core_session_t *session);
|
static switch_status_t sofia_on_init(switch_core_session_t *session);
|
||||||
|
|
||||||
static switch_status_t sofia_on_exchange_media(switch_core_session_t *session);
|
static switch_status_t sofia_on_exchange_media(switch_core_session_t *session);
|
||||||
|
@ -348,6 +348,7 @@ static int hangup_cause_to_sip(switch_call_cause_t cause)
|
||||||
case SWITCH_CAUSE_BUSY_EVERYWHERE:
|
case SWITCH_CAUSE_BUSY_EVERYWHERE:
|
||||||
return 600;
|
return 600;
|
||||||
case SWITCH_CAUSE_DECLINE:
|
case SWITCH_CAUSE_DECLINE:
|
||||||
|
case SWITCH_CAUSE_REJECT_ALL:
|
||||||
return 603;
|
return 603;
|
||||||
case SWITCH_CAUSE_DOES_NOT_EXIST_ANYWHERE:
|
case SWITCH_CAUSE_DOES_NOT_EXIST_ANYWHERE:
|
||||||
return 604;
|
return 604;
|
||||||
|
@ -472,7 +473,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
|
||||||
switch_core_hash_delete_locked(tech_pvt->profile->chat_hash, tech_pvt->hash_key, tech_pvt->profile->flag_mutex);
|
switch_core_hash_delete_locked(tech_pvt->profile->chat_hash, tech_pvt->hash_key, tech_pvt->profile->flag_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session && tech_pvt->profile->pres_type) {
|
if (tech_pvt->profile->pres_type) {
|
||||||
char *sql = switch_mprintf("delete from sip_dialogs where uuid='%q'", switch_core_session_get_uuid(session));
|
char *sql = switch_mprintf("delete from sip_dialogs where uuid='%q'", switch_core_session_get_uuid(session));
|
||||||
switch_assert(sql);
|
switch_assert(sql);
|
||||||
sofia_glue_execute_sql_now(tech_pvt->profile, &sql, SWITCH_TRUE);
|
sofia_glue_execute_sql_now(tech_pvt->profile, &sql, SWITCH_TRUE);
|
||||||
|
@ -487,7 +488,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
|
||||||
if (sofia_test_pflag(tech_pvt->profile, PFLAG_DESTROY)) {
|
if (sofia_test_pflag(tech_pvt->profile, PFLAG_DESTROY)) {
|
||||||
sofia_set_flag(tech_pvt, TFLAG_BYE);
|
sofia_set_flag(tech_pvt, TFLAG_BYE);
|
||||||
} else if (tech_pvt->nh && !sofia_test_flag(tech_pvt, TFLAG_BYE)) {
|
} else if (tech_pvt->nh && !sofia_test_flag(tech_pvt, TFLAG_BYE)) {
|
||||||
char reason[128] = "";
|
char *reason = switch_core_session_sprintf(session, "");
|
||||||
char *bye_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_BYE_HEADER_PREFIX);
|
char *bye_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_BYE_HEADER_PREFIX);
|
||||||
const char *val = NULL;
|
const char *val = NULL;
|
||||||
const char *max_forwards = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE);
|
const char *max_forwards = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE);
|
||||||
|
@ -498,15 +499,15 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
|
||||||
|
|
||||||
if (!val || switch_false(val)) {
|
if (!val || switch_false(val)) {
|
||||||
if ((val = switch_channel_get_variable(tech_pvt->channel, "sip_reason"))) {
|
if ((val = switch_channel_get_variable(tech_pvt->channel, "sip_reason"))) {
|
||||||
switch_snprintf(reason, sizeof(reason), "%s", val);
|
reason = switch_core_session_sprintf(session, "%s", val);
|
||||||
} else {
|
} else {
|
||||||
if ((switch_channel_test_flag(channel, CF_INTERCEPT) || cause == SWITCH_CAUSE_PICKED_OFF || cause == SWITCH_CAUSE_LOSE_RACE)
|
if ((switch_channel_test_flag(channel, CF_INTERCEPT) || cause == SWITCH_CAUSE_PICKED_OFF || cause == SWITCH_CAUSE_LOSE_RACE)
|
||||||
&& !switch_true(switch_channel_get_variable(channel, "ignore_completed_elsewhere"))) {
|
&& !switch_true(switch_channel_get_variable(channel, "ignore_completed_elsewhere"))) {
|
||||||
switch_snprintf(reason, sizeof(reason), "SIP;cause=200;text=\"Call completed elsewhere\"");
|
reason = switch_core_session_sprintf(session, "SIP;cause=200;text=\"Call completed elsewhere\"");
|
||||||
} else if (cause > 0 && cause < 128) {
|
} else if (cause > 0 && cause < 128) {
|
||||||
switch_snprintf(reason, sizeof(reason), "Q.850;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause));
|
reason = switch_core_session_sprintf(session, "Q.850;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause));
|
||||||
} else {
|
} else {
|
||||||
switch_snprintf(reason, sizeof(reason), "SIP;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause));
|
reason = switch_core_session_sprintf(session, "SIP;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -789,7 +790,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
||||||
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
|
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
|
||||||
tech_pvt->mparams.local_sdp_str = NULL;
|
tech_pvt->mparams.local_sdp_str = NULL;
|
||||||
switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
|
switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0);
|
||||||
} else if (is_3pcc_proxy) {
|
} else if (is_3pcc_proxy) {
|
||||||
|
|
||||||
if (!(sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY))) {
|
if (!(sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY))) {
|
||||||
|
@ -801,7 +802,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
||||||
} else {
|
} else {
|
||||||
switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
|
switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
|
||||||
switch_core_media_prepare_codecs(session, 1);
|
switch_core_media_prepare_codecs(session, 1);
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1);
|
switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 1);
|
||||||
sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);
|
sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -888,7 +889,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
||||||
|
|
||||||
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
|
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
|
||||||
|
|
||||||
if (zstr(r_sdp) || sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) {
|
if (zstr(r_sdp) || sofia_media_tech_media(tech_pvt, r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
|
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
|
||||||
//switch_mutex_lock(tech_pvt->sofia_mutex);
|
//switch_mutex_lock(tech_pvt->sofia_mutex);
|
||||||
//nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
|
//nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
|
||||||
|
@ -903,7 +904,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0);
|
||||||
if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
|
if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||||
}
|
}
|
||||||
|
@ -1597,7 +1598,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||||
ip = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE);
|
ip = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE);
|
||||||
port = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE);
|
port = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE);
|
||||||
if (ip && port) {
|
if (ip && port) {
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, ip, (switch_port_t)atoi(port), msg->string_arg, 1);
|
switch_core_media_gen_local_sdp(session, SDP_OFFER, ip, (switch_port_t)atoi(port), msg->string_arg, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
|
if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
|
||||||
|
@ -1782,7 +1783,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||||
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||||
|
|
||||||
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
|
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
|
||||||
if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) {
|
if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
|
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
|
||||||
status = SWITCH_STATUS_FALSE;
|
status = SWITCH_STATUS_FALSE;
|
||||||
goto end_lock;
|
goto end_lock;
|
||||||
|
@ -1792,7 +1793,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch_core_media_set_sdp_codec_string(tech_pvt->session, r_sdp, SDP_TYPE_RESPONSE);
|
switch_core_media_set_sdp_codec_string(tech_pvt->session, r_sdp, SDP_ANSWER);
|
||||||
switch_channel_set_variable(tech_pvt->channel, "absolute_codec_string", switch_channel_get_variable(tech_pvt->channel, "ep_codec_string"));
|
switch_channel_set_variable(tech_pvt->channel, "absolute_codec_string", switch_channel_get_variable(tech_pvt->channel, "ep_codec_string"));
|
||||||
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
|
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
|
||||||
|
|
||||||
|
@ -1801,7 +1802,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||||
goto end_lock;
|
goto end_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1);
|
switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 1);
|
||||||
|
|
||||||
if (!msg->numeric_arg) {
|
if (!msg->numeric_arg) {
|
||||||
if (send_invite) {
|
if (send_invite) {
|
||||||
|
@ -2205,11 +2206,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||||
argv[i], (double)((double)(MAX_REDIR + 1 - i))/1000);
|
argv[i], (double)((double)(MAX_REDIR + 1 - i))/1000);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (i == argc - 1) {
|
switch_snprintf(newdest + strlen(newdest), len - strlen(newdest), "\"unknown\" <%s>", argv[i]);
|
||||||
switch_snprintf(newdest + strlen(newdest), len - strlen(newdest), "\"unknown\" <%s>", argv[i]);
|
|
||||||
} else {
|
|
||||||
switch_snprintf(newdest + strlen(newdest), len - strlen(newdest), "\"unknown\" <%s>,", argv[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (i == argc - 1) {
|
if (i == argc - 1) {
|
||||||
|
@ -2259,7 +2256,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||||
switch_channel_clear_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE);
|
switch_channel_clear_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE);
|
||||||
|
|
||||||
switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
|
switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0);
|
||||||
|
|
||||||
if (sofia_use_soa(tech_pvt)) {
|
if (sofia_use_soa(tech_pvt)) {
|
||||||
nua_respond(tech_pvt->nh, SIP_200_OK,
|
nua_respond(tech_pvt->nh, SIP_200_OK,
|
||||||
|
@ -2587,7 +2584,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||||
|
|
||||||
|
|
||||||
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
|
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
|
||||||
if (zstr(r_sdp) || sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) {
|
if (zstr(r_sdp) || sofia_media_tech_media(tech_pvt, r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
|
||||||
"CODEC NEGOTIATION ERROR. SDP:\n%s\n", r_sdp ? r_sdp : "NO SDP!");
|
"CODEC NEGOTIATION ERROR. SDP:\n%s\n", r_sdp ? r_sdp : "NO SDP!");
|
||||||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
|
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
|
||||||
|
@ -2602,7 +2599,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||||
goto end_lock;
|
goto end_lock;
|
||||||
}
|
}
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0);
|
||||||
if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
|
if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||||
}
|
}
|
||||||
|
@ -3258,8 +3255,6 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
|
||||||
switch_hash_index_t *hi;
|
switch_hash_index_t *hi;
|
||||||
void *val;
|
void *val;
|
||||||
const void *vvar;
|
const void *vvar;
|
||||||
int c = 0;
|
|
||||||
int ac = 0;
|
|
||||||
const char *header = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
|
const char *header = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
|
||||||
|
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
|
@ -3469,7 +3464,6 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
|
||||||
if (sofia_test_pflag(profile, PFLAG_RUNNING)) {
|
if (sofia_test_pflag(profile, PFLAG_RUNNING)) {
|
||||||
|
|
||||||
if (strcmp(vvar, profile->name)) {
|
if (strcmp(vvar, profile->name)) {
|
||||||
ac++;
|
|
||||||
stream->write_function(stream, "<alias>\n<name>%s</name>\n<type>%s</type>\n<data>%s</data>\n<state>%s</state>\n</alias>\n", vvar, "alias",
|
stream->write_function(stream, "<alias>\n<name>%s</name>\n<type>%s</type>\n<data>%s</data>\n<state>%s</state>\n</alias>\n", vvar, "alias",
|
||||||
profile->name, "ALIASED");
|
profile->name, "ALIASED");
|
||||||
} else {
|
} else {
|
||||||
|
@ -3495,8 +3489,6 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
|
||||||
profile->inuse);
|
profile->inuse);
|
||||||
}
|
}
|
||||||
|
|
||||||
c++;
|
|
||||||
|
|
||||||
for (gp = profile->gateways; gp; gp = gp->next) {
|
for (gp = profile->gateways; gp; gp = gp->next) {
|
||||||
switch_assert(gp->state < REG_STATE_LAST);
|
switch_assert(gp->state < REG_STATE_LAST);
|
||||||
stream->write_function(stream, "<gateway>\n<name>%s</name>\n<type>%s</type>\n<data>%s</data>\n<state>%s</state>\n</gateway>\n",
|
stream->write_function(stream, "<gateway>\n<name>%s</name>\n<type>%s</type>\n<data>%s</data>\n<state>%s</state>\n</gateway>\n",
|
||||||
|
@ -4313,6 +4305,8 @@ SWITCH_STANDARD_API(sofia_presence_data_function)
|
||||||
user = argv[1];
|
user = argv[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!user) goto end;
|
||||||
|
|
||||||
if ((domain = strchr(user, '@'))) {
|
if ((domain = strchr(user, '@'))) {
|
||||||
*domain++ = '\0';
|
*domain++ = '\0';
|
||||||
if ((concat = strchr(domain, '/'))) {
|
if ((concat = strchr(domain, '/'))) {
|
||||||
|
@ -4329,8 +4323,6 @@ SWITCH_STANDARD_API(sofia_presence_data_function)
|
||||||
domain = dup_domain;
|
domain = dup_domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user) goto end;
|
|
||||||
|
|
||||||
if (zstr(profile_name) || strcmp(profile_name, "*") || zstr(domain)) {
|
if (zstr(profile_name) || strcmp(profile_name, "*") || zstr(domain)) {
|
||||||
if (!zstr(profile_name)) {
|
if (!zstr(profile_name)) {
|
||||||
profile = sofia_glue_find_profile(profile_name);
|
profile = sofia_glue_find_profile(profile_name);
|
||||||
|
@ -6836,7 +6828,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mod_sofia_shutdown_cleanup() {
|
void mod_sofia_shutdown_cleanup(void) {
|
||||||
int sanity = 0;
|
int sanity = 0;
|
||||||
int i;
|
int i;
|
||||||
switch_status_t st;
|
switch_status_t st;
|
||||||
|
|
|
@ -82,9 +82,6 @@
|
||||||
* <dt>-6</dt>
|
* <dt>-6</dt>
|
||||||
* <dd>Query IP6 addresses (AAAA records).
|
* <dd>Query IP6 addresses (AAAA records).
|
||||||
* </dd>
|
* </dd>
|
||||||
* <dt>-v</dt>
|
|
||||||
* <dd>Be verbatim.
|
|
||||||
* </dd>
|
|
||||||
* <dt></dt>
|
* <dt></dt>
|
||||||
* <dd>
|
* <dd>
|
||||||
* </dd>
|
* </dd>
|
||||||
|
@ -201,7 +198,7 @@ switch_bool_t verify_ip(sres_record_t **answers, const char *ip, switch_bool_t i
|
||||||
switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream)
|
switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream)
|
||||||
|
|
||||||
{
|
{
|
||||||
int o_sctp = 1, o_tls_sctp = 1, o_verbatim = 1;
|
int o_sctp = 1, o_tls_sctp = 1;
|
||||||
int family = 0, multiple = 0;
|
int family = 0, multiple = 0;
|
||||||
char const *string;
|
char const *string;
|
||||||
url_t *uri = NULL;
|
url_t *uri = NULL;
|
||||||
|
@ -247,9 +244,7 @@ switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_cor
|
||||||
}
|
}
|
||||||
|
|
||||||
while (argv[i] && argv[i][0] == '-') {
|
while (argv[i] && argv[i][0] == '-') {
|
||||||
if (strcmp(argv[i], "-v") == 0) {
|
if (strcmp(argv[i], "-6") == 0) {
|
||||||
o_verbatim++;
|
|
||||||
} else if (strcmp(argv[i], "-6") == 0) {
|
|
||||||
dig->ip6 = ++family;
|
dig->ip6 = ++family;
|
||||||
} else if (strcmp(argv[i], "-4") == 0) {
|
} else if (strcmp(argv[i], "-4") == 0) {
|
||||||
dig->ip4 = ++family;
|
dig->ip4 = ++family;
|
||||||
|
@ -815,8 +810,12 @@ sres_record_t ** dig_addr_simple(struct dig *dig,
|
||||||
uint16_t type)
|
uint16_t type)
|
||||||
{
|
{
|
||||||
sres_record_t **answers = NULL;
|
sres_record_t **answers = NULL;
|
||||||
|
int error;
|
||||||
|
|
||||||
sres_blocking_query(dig->sres, type, host, 0, &answers);
|
error = sres_blocking_query(dig->sres, type, host, 0, &answers);
|
||||||
|
if (error < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return answers;
|
return answers;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2818,7 +2818,10 @@ void event_handler(switch_event_t *event)
|
||||||
|
|
||||||
if ((sptr = strstr(fixed_contact_str, needle))) {
|
if ((sptr = strstr(fixed_contact_str, needle))) {
|
||||||
char *origsptr = strstr(contact_str, needle);
|
char *origsptr = strstr(contact_str, needle);
|
||||||
eptr = strchr(++origsptr, ';');
|
|
||||||
|
if (origsptr) {
|
||||||
|
eptr = strchr(++origsptr, ';');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sptr = strchr(fixed_contact_str, '\0') - 1;
|
sptr = strchr(fixed_contact_str, '\0') - 1;
|
||||||
}
|
}
|
||||||
|
@ -6680,7 +6683,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
|
||||||
tech_pvt->mparams.last_sdp_response = NULL;
|
tech_pvt->mparams.last_sdp_response = NULL;
|
||||||
|
|
||||||
if (sip->sip_payload && sip->sip_payload->pl_data) {
|
if (sip->sip_payload && sip->sip_payload->pl_data) {
|
||||||
switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_TYPE_RESPONSE);
|
switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_ANSWER);
|
||||||
|
|
||||||
if (!zstr(tech_pvt->mparams.prev_sdp_response) && !strcmp(tech_pvt->mparams.prev_sdp_response, sip->sip_payload->pl_data)) {
|
if (!zstr(tech_pvt->mparams.prev_sdp_response) && !strcmp(tech_pvt->mparams.prev_sdp_response, sip->sip_payload->pl_data)) {
|
||||||
tech_pvt->mparams.last_sdp_response = tech_pvt->mparams.prev_sdp_response;
|
tech_pvt->mparams.last_sdp_response = tech_pvt->mparams.prev_sdp_response;
|
||||||
|
@ -7503,9 +7506,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
switch_channel_mark_pre_answered(channel);
|
switch_channel_mark_pre_answered(channel);
|
||||||
}
|
}
|
||||||
//if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
|
//if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
|
||||||
// switch_core_media_set_sdp_codec_string(session, r_sdp, status < 200 ? SDP_TYPE_REQUEST : SDP_TYPE_RESPONSE);
|
// switch_core_media_set_sdp_codec_string(session, r_sdp, status < 200 ? SDP_OFFER : SDP_ANSWER);
|
||||||
//}
|
//}
|
||||||
switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST);
|
switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_OFFER);
|
||||||
sofia_glue_pass_sdp(tech_pvt, (char *) r_sdp);
|
sofia_glue_pass_sdp(tech_pvt, (char *) r_sdp);
|
||||||
sofia_set_flag(tech_pvt, TFLAG_NEW_SDP);
|
sofia_set_flag(tech_pvt, TFLAG_NEW_SDP);
|
||||||
|
|
||||||
|
@ -7677,7 +7680,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (sofia_media_tech_media(tech_pvt, (char *) r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) {
|
if (sofia_media_tech_media(tech_pvt, (char *) r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
|
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
|
||||||
nua_respond(nh, SIP_488_NOT_ACCEPTABLE,
|
nua_respond(nh, SIP_488_NOT_ACCEPTABLE,
|
||||||
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),TAG_END());
|
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),TAG_END());
|
||||||
|
@ -7773,7 +7776,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
|
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
|
||||||
|
|
||||||
if (tech_pvt->mparams.num_codecs) {
|
if (tech_pvt->mparams.num_codecs) {
|
||||||
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
|
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!match) {
|
if (!match) {
|
||||||
|
@ -7782,7 +7785,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),TAG_END());
|
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),TAG_END());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0);
|
||||||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED");
|
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED");
|
||||||
sofia_set_flag_locked(tech_pvt, TFLAG_READY);
|
sofia_set_flag_locked(tech_pvt, TFLAG_READY);
|
||||||
|
|
||||||
|
@ -7906,7 +7909,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
uint8_t match = 0;
|
uint8_t match = 0;
|
||||||
|
|
||||||
if (tech_pvt->mparams.num_codecs) {
|
if (tech_pvt->mparams.num_codecs) {
|
||||||
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
|
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!match) {
|
if (!match) {
|
||||||
|
@ -7989,10 +7992,11 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING);
|
switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING);
|
||||||
} else {
|
} else {
|
||||||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP");
|
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP");
|
||||||
|
switch_channel_set_flag(channel, CF_3PCC);
|
||||||
switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
|
switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
|
||||||
switch_core_media_prepare_codecs(session, 1);
|
switch_core_media_prepare_codecs(session, 1);
|
||||||
switch_channel_set_state(channel, CS_HIBERNATE);
|
switch_channel_set_state(channel, CS_HIBERNATE);
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0);
|
switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 0);
|
||||||
sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);
|
sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);
|
||||||
|
|
||||||
if (sofia_use_soa(tech_pvt)) {
|
if (sofia_use_soa(tech_pvt)) {
|
||||||
|
@ -8064,10 +8068,10 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
switch_channel_set_flag(channel, CF_NOSDP_REINVITE);
|
switch_channel_set_flag(channel, CF_NOSDP_REINVITE);
|
||||||
|
|
||||||
if (switch_channel_var_true(channel, "sip_unhold_nosdp")) {
|
if (switch_channel_var_true(channel, "sip_unhold_nosdp")) {
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, "sendrecv",
|
switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, "sendrecv",
|
||||||
zstr(tech_pvt->mparams.local_sdp_str) || !switch_channel_test_flag(channel, CF_PROXY_MODE));
|
zstr(tech_pvt->mparams.local_sdp_str) || !switch_channel_test_flag(channel, CF_PROXY_MODE));
|
||||||
} else {
|
} else {
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL,
|
switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL,
|
||||||
zstr(tech_pvt->mparams.local_sdp_str) || !switch_channel_test_flag(channel, CF_PROXY_MODE));
|
zstr(tech_pvt->mparams.local_sdp_str) || !switch_channel_test_flag(channel, CF_PROXY_MODE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8113,13 +8117,13 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
sofia_set_flag(tech_pvt, TFLAG_SDP);
|
sofia_set_flag(tech_pvt, TFLAG_SDP);
|
||||||
|
|
||||||
|
|
||||||
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
|
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_ANSWER);
|
||||||
if (match) {
|
if (match) {
|
||||||
if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
|
if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0);
|
||||||
|
|
||||||
if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
|
if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Early Media RTP Error!\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Early Media RTP Error!\n");
|
||||||
|
@ -8188,7 +8192,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
|
|
||||||
|
|
||||||
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
|
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
|
||||||
if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) {
|
if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_OFFER) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
|
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
|
||||||
switch_core_session_rwunlock(other_session);
|
switch_core_session_rwunlock(other_session);
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||||
|
@ -8207,7 +8211,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 1);
|
switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 1);
|
||||||
|
|
||||||
if (sofia_use_soa(tech_pvt)) {
|
if (sofia_use_soa(tech_pvt)) {
|
||||||
nua_respond(tech_pvt->nh, SIP_200_OK,
|
nua_respond(tech_pvt->nh, SIP_200_OK,
|
||||||
|
@ -8317,7 +8321,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
|
switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
|
||||||
|
|
||||||
if (tech_pvt->mparams.num_codecs){
|
if (tech_pvt->mparams.num_codecs){
|
||||||
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
|
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!match) {
|
if (!match) {
|
||||||
|
@ -8366,7 +8370,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0);
|
||||||
if (sofia_use_soa(tech_pvt)){
|
if (sofia_use_soa(tech_pvt)){
|
||||||
nua_respond(tech_pvt->nh, SIP_200_OK,
|
nua_respond(tech_pvt->nh, SIP_200_OK,
|
||||||
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
|
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
|
||||||
|
@ -8416,7 +8420,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
|
switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
|
||||||
|
|
||||||
if (tech_pvt->mparams.num_codecs) {
|
if (tech_pvt->mparams.num_codecs) {
|
||||||
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
|
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -8435,7 +8439,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0);
|
||||||
|
|
||||||
if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
|
if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite RTP Error!\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite RTP Error!\n");
|
||||||
|
@ -8459,7 +8463,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
if (is_ok) {
|
if (is_ok) {
|
||||||
|
|
||||||
if (switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
|
if (switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!switch_channel_test_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE)) {
|
if (!switch_channel_test_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE)) {
|
||||||
|
@ -8504,13 +8508,13 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
|
|
||||||
|
|
||||||
if (tech_pvt->mparams.num_codecs) {
|
if (tech_pvt->mparams.num_codecs) {
|
||||||
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
|
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_ANSWER);
|
||||||
}
|
}
|
||||||
if (match) {
|
if (match) {
|
||||||
if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
|
if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
switch_core_media_gen_local_sdp(session, SDP_ANSWER, NULL, 0, NULL, 0);
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n");
|
||||||
switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
|
switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
|
||||||
|
@ -8568,9 +8572,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
|
|
||||||
if (tech_pvt->mparams.num_codecs) {
|
if (tech_pvt->mparams.num_codecs) {
|
||||||
if (sofia_test_flag(tech_pvt, TFLAG_GOT_ACK)) {
|
if (sofia_test_flag(tech_pvt, TFLAG_GOT_ACK)) {
|
||||||
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
|
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_OFFER);
|
||||||
} else {
|
} else {
|
||||||
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
|
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_ANSWER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8665,7 +8669,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||||
uint8_t match = 0;
|
uint8_t match = 0;
|
||||||
|
|
||||||
|
|
||||||
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
|
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_ANSWER);
|
||||||
|
|
||||||
|
|
||||||
sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
|
sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
|
||||||
|
@ -10463,7 +10467,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
|
||||||
|
|
||||||
|
|
||||||
if (r_sdp) {
|
if (r_sdp) {
|
||||||
switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST);
|
switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_OFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -929,9 +929,9 @@ char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix
|
||||||
if ( !exclude_regex || !(/*proceed*/ switch_regex_perform(name, exclude_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
|
if ( !exclude_regex || !(/*proceed*/ switch_regex_perform(name, exclude_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
|
||||||
const char *hname = name + strlen(prefix);
|
const char *hname = name + strlen(prefix);
|
||||||
stream.write_function(&stream, "%s: %s\r\n", hname, value);
|
stream.write_function(&stream, "%s: %s\r\n", hname, value);
|
||||||
switch_regex_safe_free(re);
|
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ignoring Extra Header [%s] , matches exclude_outgoing_extra_header [%s]\n", name, exclude_regex);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ignoring Extra Header [%s] , matches exclude_outgoing_extra_header [%s]\n", name, exclude_regex);
|
||||||
|
switch_regex_safe_free(re);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1158,7 +1158,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!switch_channel_get_private(tech_pvt->channel, "t38_options") || zstr(tech_pvt->mparams.local_sdp_str)) {
|
if (!switch_channel_get_private(tech_pvt->channel, "t38_options") || zstr(tech_pvt->mparams.local_sdp_str)) {
|
||||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0);
|
switch_core_media_gen_local_sdp(session, SDP_OFFER, NULL, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
sofia_set_flag_locked(tech_pvt, TFLAG_READY);
|
sofia_set_flag_locked(tech_pvt, TFLAG_READY);
|
||||||
|
@ -2282,8 +2282,7 @@ int sofia_recover_callback(switch_core_session_t *session)
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
private_object_t *tech_pvt = NULL;
|
private_object_t *tech_pvt = NULL;
|
||||||
sofia_profile_t *profile = NULL;
|
sofia_profile_t *profile = NULL;
|
||||||
const char *tmp;
|
const char *tmp, *rr, *use_uuid;
|
||||||
const char *rr;
|
|
||||||
int r = 0;
|
int r = 0;
|
||||||
const char *profile_name = switch_channel_get_variable_dup(channel, "recovery_profile_name", SWITCH_FALSE, -1);
|
const char *profile_name = switch_channel_get_variable_dup(channel, "recovery_profile_name", SWITCH_FALSE, -1);
|
||||||
int swap = switch_channel_var_true(channel, "dlg_req_swap_direction");
|
int swap = switch_channel_var_true(channel, "dlg_req_swap_direction");
|
||||||
|
@ -2374,17 +2373,13 @@ int sofia_recover_callback(switch_core_session_t *session)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session) {
|
if ((use_uuid = switch_channel_get_variable(channel, "origination_uuid"))) {
|
||||||
const char *use_uuid;
|
if (switch_core_session_set_uuid(session, use_uuid) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(channel),
|
||||||
if ((use_uuid = switch_channel_get_variable(channel, "origination_uuid"))) {
|
use_uuid);
|
||||||
if (switch_core_session_set_uuid(session, use_uuid) == SWITCH_STATUS_SUCCESS) {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(channel),
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n",
|
||||||
use_uuid);
|
switch_channel_get_name(channel), use_uuid);
|
||||||
} else {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n",
|
|
||||||
switch_channel_get_name(channel), use_uuid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1621,7 +1621,6 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Event Thread Started\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Event Thread Started\n");
|
||||||
|
|
||||||
while (mod_sofia_globals.running == 1) {
|
while (mod_sofia_globals.running == 1) {
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
if (switch_queue_pop(mod_sofia_globals.presence_queue, &pop) == SWITCH_STATUS_SUCCESS) {
|
if (switch_queue_pop(mod_sofia_globals.presence_queue, &pop) == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_event_t *event = (switch_event_t *) pop;
|
switch_event_t *event = (switch_event_t *) pop;
|
||||||
|
@ -1656,7 +1655,6 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_event_destroy(&event);
|
switch_event_destroy(&event);
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ static const char *test_wait_for_chan_var(switch_channel_t *channel, const char
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
|
|
||||||
static switch_bool_t has_ipv6()
|
static switch_bool_t has_ipv6(void)
|
||||||
{
|
{
|
||||||
switch_stream_handle_t stream = { 0 };
|
switch_stream_handle_t stream = { 0 };
|
||||||
SWITCH_STANDARD_STREAM(stream);
|
SWITCH_STANDARD_STREAM(stream);
|
||||||
|
@ -110,7 +110,7 @@ static switch_bool_t has_ipv6()
|
||||||
return SWITCH_TRUE;
|
return SWITCH_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void register_gw()
|
static void register_gw(void)
|
||||||
{
|
{
|
||||||
switch_stream_handle_t stream = { 0 };
|
switch_stream_handle_t stream = { 0 };
|
||||||
SWITCH_STANDARD_STREAM(stream);
|
SWITCH_STANDARD_STREAM(stream);
|
||||||
|
@ -118,7 +118,7 @@ static void register_gw()
|
||||||
switch_safe_free(stream.data);
|
switch_safe_free(stream.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unregister_gw()
|
static void unregister_gw(void)
|
||||||
{
|
{
|
||||||
switch_stream_handle_t stream = { 0 };
|
switch_stream_handle_t stream = { 0 };
|
||||||
SWITCH_STANDARD_STREAM(stream);
|
SWITCH_STANDARD_STREAM(stream);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue