Merge branch 'master' of ssh://git.freeswitch.org:222/freeswitch
This commit is contained in:
commit
3feb222e09
|
@ -709,6 +709,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_say_pt", "src\mod\say\m
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ldns", "libs\win32\ldns\ldns-lib\ldns-lib.2010.vcxproj", "{23B4D303-79FC-49E0-89E2-2280E7E28940}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_callcenter", "src\mod\applications\mod_callcenter\mod_callcenter.2010.vcxproj", "{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
All|Win32 = All|Win32
|
||||
|
@ -3633,6 +3635,19 @@ Global
|
|||
{23B4D303-79FC-49E0-89E2-2280E7E28940}.Release|x64.Build.0 = Release|x64
|
||||
{23B4D303-79FC-49E0-89E2-2280E7E28940}.Release|x64 Setup.ActiveCfg = Release|x64
|
||||
{23B4D303-79FC-49E0-89E2-2280E7E28940}.Release|x86 Setup.ActiveCfg = Release|x64
|
||||
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.All|Win32.ActiveCfg = Release|x64
|
||||
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.All|x64.ActiveCfg = Release|x64
|
||||
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.All|x64.Build.0 = Release|x64
|
||||
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.All|x64 Setup.ActiveCfg = Release|x64
|
||||
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.All|x86 Setup.ActiveCfg = Release|x64
|
||||
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Debug|x64 Setup.ActiveCfg = Debug|x64
|
||||
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Debug|x86 Setup.ActiveCfg = Debug|x64
|
||||
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Release|x64.ActiveCfg = Release|x64
|
||||
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Release|x64 Setup.ActiveCfg = Release|x64
|
||||
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Release|x86 Setup.ActiveCfg = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -3680,6 +3695,7 @@ Global
|
|||
{2E250296-0C08-4342-9C8A-BCBDD0E7DF65} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
|
||||
{B889A18E-70A7-44B5-B2C9-47798D4F43B3} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
|
||||
{5C2B4D88-3BEA-4FE0-90DF-FA9836099D5F} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
|
||||
{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
|
||||
{07113B25-D3AF-4E04-BA77-4CD1171F022C} = {C5F182F9-754A-4EC5-B50F-76ED02BE13F4}
|
||||
{A27CCA23-1541-4337-81A4-F0A6413078A0} = {C5F182F9-754A-4EC5-B50F-76ED02BE13F4}
|
||||
{E7BC026C-7CC5-45A3-BC7C-3B88EEF01F24} = {C5F182F9-754A-4EC5-B50F-76ED02BE13F4}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<configuration name="cepstral.conf" description="Cepstral TTS configuration">
|
||||
<settings>
|
||||
<!--
|
||||
Possible encodings:
|
||||
* utf-8
|
||||
* us-ascii
|
||||
* iso8859-1 (default)
|
||||
* iso8859-15
|
||||
-->
|
||||
<param name="encoding" value="utf-8"/>
|
||||
</settings>
|
||||
</configuration>
|
|
@ -24,6 +24,17 @@
|
|||
<!--Colorize the Console -->
|
||||
<param name="colorize-console" value="true"/>
|
||||
|
||||
<!-- Run the timer at 20ms by default and drop down as needed unless you set 1m-timer=true which was previous default -->
|
||||
<!-- <param name="1ms-timer" value="true"/> -->
|
||||
|
||||
<!--
|
||||
Set the Switch Name for HA environments.
|
||||
When setting the switch name, it will override the system hostname for all DB and CURL requests
|
||||
allowing cluster environments such as RHCS to have identical FreeSWITCH configurations but run
|
||||
as different hostnames.
|
||||
-->
|
||||
<!-- <param name="switchname" value="freeswitch"/>-->
|
||||
|
||||
<!-- maximum number of simo db handles open -->
|
||||
<param name="max-db-handles" value="50"/>
|
||||
<!-- maximum number of seconds to wait for a new db handle before failing -->
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<include>
|
||||
<extension name="Talking Clock Time" ><!--e.g. 10:56pm-->
|
||||
<condition field="destination_number" expression="9170">
|
||||
<action application="say" data="en CURRENT_TIME pronounced
|
||||
${strepoch()}"/>
|
||||
<action application="hangup"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="Talking Clock Date" ><!--e.g. March 8, 2011-->
|
||||
<condition field="destination_number" expression="9171">
|
||||
<action application="say" data="en CURRENT_DATE pronounced
|
||||
${strepoch()}"/>
|
||||
<action application="hangup"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="Talking Clock Date and Time" ><!--e.g. March 8, 2011
|
||||
10:56pm-->
|
||||
<condition field="destination_number" expression="9172">
|
||||
<action application="say" data="en CURRENT_DATE_TIME pronounced
|
||||
${strepoch()}"/>
|
||||
<action application="hangup"/>
|
||||
</condition>
|
||||
</extension>
|
||||
</include>
|
|
@ -52,14 +52,12 @@
|
|||
<X-PRE-PROCESS cmd="include" data="directory/*.xml"/>
|
||||
</section>
|
||||
|
||||
<!-- phrases section (under development still) -->
|
||||
<section name="phrases" description="Speech Phrase Management">
|
||||
<macros>
|
||||
<!-- languages section (under development still) -->
|
||||
<section name="languages" description="Language Management">
|
||||
<X-PRE-PROCESS cmd="include" data="lang/de/*.xml"/>
|
||||
<X-PRE-PROCESS cmd="include" data="lang/en/*.xml"/>
|
||||
<X-PRE-PROCESS cmd="include" data="lang/fr/*.xml"/>
|
||||
<X-PRE-PROCESS cmd="include" data="lang/ru/*.xml"/>
|
||||
<X-PRE-PROCESS cmd="include" data="lang/he/*.xml"/>
|
||||
</macros>
|
||||
</section>
|
||||
</document>
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
<include>
|
||||
<language name="de" sound-path="/snds" tts-engine="cepstral" tts-voice="david">
|
||||
<language name="de" sound-prefix="/snds" tts-engine="cepstral" tts-voice="david">
|
||||
<phrases>
|
||||
<macros>
|
||||
<X-PRE-PROCESS cmd="include" data="demo/demo.xml"/>
|
||||
<!--voicemail_de_tts is purely implemented with tts, we need a files based implementation too -->
|
||||
<X-PRE-PROCESS cmd="include" data="vm/tts.xml"/>
|
||||
</macros>
|
||||
</phrases>
|
||||
</language>
|
||||
</include>
|
||||
|
|
|
@ -0,0 +1,407 @@
|
|||
<include><!--This line will be ignored it's here to validate the xml and is optional -->
|
||||
<macro name="voicemail_enter_id">
|
||||
<input pattern="(.*)">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-enter_id.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_enter_pass">
|
||||
<input pattern="(.*)">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-enter_pass.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_fail_auth">
|
||||
<input pattern="(.*)">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-fail_auth.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_hello">
|
||||
<input pattern="(.*)">
|
||||
<match>
|
||||
<!--<action function="play-file" data="voicemail/vm-hello.wav"/> -->
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_goodbye">
|
||||
<input pattern="(.*)">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-goodbye.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_abort">
|
||||
<input pattern="(.*)">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-abort.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_message_count">
|
||||
<input pattern="^(1):(.*)$" break_on_match="true">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-you_have.wav"/>
|
||||
<action application="log" data="INFO $1 $2"/>
|
||||
<action function="say" data="$1" method="pronounced" type="items" gender="feminine"/>
|
||||
<action function="play-file" data="voicemail/vm-$2.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-message.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
<input pattern="^(\d+):(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-you_have.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="items" gender="feminine"/>
|
||||
<action function="play-file" data="voicemail/vm-$2.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-messages.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_menu">
|
||||
<input pattern="^([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*])$">
|
||||
<match>
|
||||
<!-- To listen to new messages -->
|
||||
<action function="play-file" data="voicemail/vm-listen_new.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
<action function="execute" data="sleep(100)"/>
|
||||
|
||||
<!-- To listen to saved messages -->
|
||||
<action function="play-file" data="voicemail/vm-listen_saved.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$2" method="pronounced" type="name_spelled"/>
|
||||
<action function="execute" data="sleep(100)"/>
|
||||
|
||||
<!-- For advanced options -->
|
||||
<action function="play-file" data="voicemail/vm-advanced.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$3" method="pronounced" type="name_spelled"/>
|
||||
<action function="execute" data="sleep(100)"/>
|
||||
|
||||
<!-- To exit -->
|
||||
<action function="play-file" data="voicemail/vm-to_exit.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$4" method="pronounced" type="name_phonetic"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_config_menu">
|
||||
<input pattern="^([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*])$">
|
||||
<match>
|
||||
<!-- To record a greeting -->
|
||||
<action function="play-file" data="voicemail/vm-to_record_greeting.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
<action function="execute" data="sleep(100)"/>
|
||||
|
||||
<!-- To choose greeting -->
|
||||
<action function="play-file" data="voicemail/vm-choose_greeting.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$2" method="pronounced" type="name_spelled"/>
|
||||
<action function="execute" data="sleep(100)"/>
|
||||
|
||||
<!-- To record your name -->
|
||||
<action function="play-file" data="voicemail/vm-record_name2.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$3" method="pronounced" type="name_spelled"/>
|
||||
<action function="execute" data="sleep(100)"/>
|
||||
|
||||
<!-- To change password -->
|
||||
<action function="play-file" data="voicemail/vm-change_password.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$4" method="pronounced" type="name_spelled"/>
|
||||
<action function="execute" data="sleep(100)"/>
|
||||
|
||||
<!-- To return to main menu -->
|
||||
<action function="play-file" data="voicemail/vm-main_menu.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$5" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_record_name">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-record_name1.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_record_file_check">
|
||||
<input pattern="^([0-9#*]):([0-9#*]):([0-9#*])$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-listen_to_recording.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$2" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-save_recording.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$3" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-rerecord.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_record_urgent_check">
|
||||
<input pattern="^([0-9#*]):([0-9#*])$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-mark-urgent.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-continue.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$2" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_forward_prepend">
|
||||
<input pattern="^([0-9#*]):([0-9#*])$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-forward_add_intro.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-send_message_now.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$2" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_forward_message_enter_extension">
|
||||
<input pattern="^([0-9#*])$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-forward_enter_ext.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-followed_by.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_invalid_extension">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-that_was_an_invalid_ext.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_listen_file_check">
|
||||
<input pattern="^([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*]):(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-listen_to_recording.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-save_recording.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$2" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-delete_recording.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$3" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-forward_to_email.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$4" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-return_call.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$5" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-to_forward.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$6" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
<input pattern="^([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*]):([0-9#*])$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-listen_to_recording.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-save_recording.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$2" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-delete_recording.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$3" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-return_call.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$5" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-to_forward.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$6" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_choose_greeting">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-choose_greeting_choose.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_choose_greeting_fail">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-choose_greeting_fail.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_record_greeting">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-record_greeting.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_record_message">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-record_message.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_greeting_selected">
|
||||
<input pattern="^(\d+)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-greeting.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="items"/>
|
||||
<action function="play-file" data="voicemail/vm-selected.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_play_greeting">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-person.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-not_available.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_say_number">
|
||||
<input pattern="^(\d+)$">
|
||||
<match>
|
||||
<action function="say" data="$1" method="pronounced" type="items"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_say_message_number">
|
||||
<input pattern="^([a-z]+):(\d+)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-$1.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-message_number.wav"/>
|
||||
<action application="log" data="INFO $1 $2"/>
|
||||
<action function="say" data="$2" method="pronounced" type="items"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_say_phone_number">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_say_name">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
<!-- Note: Update this to marked-urgent,emailed and saved once new sound files are recorded -->
|
||||
<macro name="voicemail_ack">
|
||||
<input pattern="^(too-small)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-too-small.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
<input pattern="^(deleted)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-message.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-$1.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
<input pattern="^(saved)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-message.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-$1.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
<input pattern="^(emailed)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-message.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-$1.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
<input pattern="^(marked-urgent)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-message.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-$1.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_say_date">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action application="log" data="INFO $1"/>
|
||||
<action function="say" data="$1" method="counted" type="current_date_time"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="voicemail_disk_quota_exceeded">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-mailbox_full.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="valet_announce_ext">
|
||||
<input pattern="^([^\:]+):(.*)$">
|
||||
<match>
|
||||
<action function="say" data="$2" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="valet_lot_full">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="tone_stream://%(275,10,600);%(275,100,300)"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="valet_lot_empty">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="tone_stream://%(275,10,600);%(275,100,300)"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
</include><!--This line will be ignored it's here to validate the xml and is optional -->
|
|
@ -99,7 +99,7 @@
|
|||
<action function="play-file" data="directory/dir-for_next.wav"/>
|
||||
<action function="play-file" data="directory/dir-press.wav"/>
|
||||
<action function="say" data="$2" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="directory/dir-for_previous.wav"/>
|
||||
<action function="play-file" data="directory/dir-for_prev.wav"/>
|
||||
<action function="play-file" data="directory/dir-press.wav"/>
|
||||
<action function="say" data="$3" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="directory/dir-start_new_search.wav"/>
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
<include>
|
||||
<language name="en" sound-path="$${sounds_dir}/en/us/callie" tts-engine="cepstral" tts-voice="callie">
|
||||
<language name="en" say-module="en" sound-prefix="$${sounds_dir}/en/us/callie" tts-engine="cepstral" tts-voice="callie">
|
||||
<phrases>
|
||||
<macros>
|
||||
<X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
|
||||
<!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
|
||||
<X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/> <!-- vm/tts.xml if you want to use tts and have cepstral -->
|
||||
<X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/> <!-- dir/tts.xml if you want to use tts and have cepstral -->
|
||||
</macros>
|
||||
</phrases>
|
||||
</language>
|
||||
</include>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<include> <!--This line will be ignored it's here to validate the xml and is optional -->
|
||||
<macro name="queue_position">
|
||||
<input pattern="^(\d+)$">
|
||||
<match>
|
||||
<action function="play-file" data="ivr/ivr-you_are_number.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="items"/>
|
||||
<action function="play-file" data="ivr/ivr-in_line.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
</include>
|
|
@ -1,8 +1,12 @@
|
|||
<include>
|
||||
<language name="fr" sound-path="/snds" tts-engine="cepstral" tts-voice="david">
|
||||
<language name="fr" say-module="fr" sound-prefix="$${sounds_dir}/fr/ca/june" tts-engine="cepstral" tts-voice="david">
|
||||
<phrases>
|
||||
<macros>
|
||||
<X-PRE-PROCESS cmd="include" data="demo/demo.xml"/>
|
||||
<!--voicemail_fr_tts is purely implemented with tts, we need a files based implementation too -->
|
||||
<X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>
|
||||
<X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/> <!-- dir/tts.xml if you want to use tts and have cepstral -->
|
||||
</macros>
|
||||
</phrases>
|
||||
</language>
|
||||
</include>
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
<include>
|
||||
<language name="he" sound-path="$${sounds_dir}/he/daniel" tts-engine="cepstral" tts-voice="daniel">
|
||||
<language name="he" sound-prefix="$${sounds_dir}/he/daniel" tts-engine="cepstral" tts-voice="daniel">
|
||||
<phrases>
|
||||
<macros>
|
||||
<X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
|
||||
<X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>
|
||||
<X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/>
|
||||
</macros>
|
||||
</phrases>
|
||||
</language>
|
||||
</include>
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--тестовые файлы Вы звуковые файлы можно взять тут svn co http://svn.freeswitch.ru/bbv/mod_say_ru/ru/ -->
|
||||
<include>
|
||||
<language name="ru" sound-path="$${sounds_dir}/ru/RU/elena" tts-engine="cepstral" tts-voice="elena">
|
||||
<language name="ru" sound-prefix="$${sounds_dir}/ru/RU/elena" tts-engine="cepstral" tts-voice="elena">
|
||||
<phrases>
|
||||
<macros>
|
||||
<X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
|
||||
<!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
|
||||
<X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/> <!-- vm/tts.xml if you want to use tts and have cepstral -->
|
||||
</macros>
|
||||
</phrases>
|
||||
</language>
|
||||
</include>
|
||||
|
|
15
configure.in
15
configure.in
|
@ -583,6 +583,21 @@ if test x"$ac_cv_gcc_declaration_after_statement" = xyes; then
|
|||
fi
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
|
||||
# Tested and fixed lot of modules, but some are untested. Will be added back when the core team decide it ready
|
||||
# Untested modules : mod_osp mod_soundtouch mod_sangoma_codec mod_dingaling mod_opal mod_skypopen mod_h323 mod_khomp
|
||||
# mod_unimrcp mod_cepstral mod_erlang_event mod_snmp mod_perl mod_java mod_managed
|
||||
#
|
||||
#saved_CFLAGS="$CFLAGS"
|
||||
#AC_CACHE_CHECK([whether compiler supports -Wunused-but-set-variable], [ac_cv_gcc_unused_but_set_variable], [
|
||||
#CFLAGS="$CFLAGS -Wunused-but-set-variable"
|
||||
#AC_TRY_COMPILE([],[return 0;],[ac_cv_gcc_unused_but_set_variable=yes],[ac_cv_gcc_unused_but_set_variable=no])
|
||||
#])
|
||||
#AC_MSG_RESULT($ac_cv_gcc_unused_but_set_variable)
|
||||
#if test x"$ac_cv_gcc_unused_but_set_variable" = xyes; then
|
||||
# APR_ADDTO(SWITCH_ANSI_CFLAGS, -Wunused-but-set-variable)
|
||||
#fi
|
||||
#CFLAGS="$saved_CFLAGS"
|
||||
|
||||
AC_C_BIGENDIAN(AC_DEFINE([SWITCH_BYTE_ORDER],__BIG_ENDIAN,[Big Endian]),AC_DEFINE([SWITCH_BYTE_ORDER],__LITTLE_ENDIAN,[Little Endian]))
|
||||
|
||||
# Checks for integer size
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/opt/freeswitch/conf/lang/de/demo/demo.xml
|
||||
/opt/freeswitch/conf/lang/de/de.xml
|
||||
/opt/freeswitch/conf/lang/de/vm/tts.xml
|
||||
/opt/freeswitch/conf/lang/de/vm/sounds.xml
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
opt/freeswitch/conf/lang/de/demo/demo.xml
|
||||
opt/freeswitch/conf/lang/de/de.xml
|
||||
opt/freeswitch/conf/lang/de/vm/tts.xml
|
||||
/opt/freeswitch/conf/lang/de/vm/sounds.xml
|
||||
opt/freeswitch/mod/mod_say_de.so*
|
||||
|
|
|
@ -24,6 +24,7 @@ freeswitch (1.0.7)
|
|||
build: VS2010 libportaudio project improvements for DirectX builds and switch to build DirectX by default (r:e9e33f51/FS-3033)
|
||||
build: add make targets for mod_com_g729 mod_com_g729-activate mod_com_g729-install mod_com_g729-clean mod_com_g729-uninstall (r:17d52112)
|
||||
build: add support for bz2 to getlibs (r:b61fc396)
|
||||
build: Bump callie sounds to 1.0.15 (r:c8eaef60)
|
||||
codec2: working prototype, still for testing only (r:04ca0751)
|
||||
config: move limit.conf to db.conf
|
||||
config: Update VM phrase macros to voice option then action on main, config menus
|
||||
|
@ -231,6 +232,19 @@ freeswitch (1.0.7)
|
|||
core: Fix X-PREPROCESS exec to wait pid (r:dae2cb4a)
|
||||
core: Ability to use mod_say with native files; native is a special case so use the extension native e.g. en.native (r:3a2e1d03/FS-3176)
|
||||
core: Fix: Bridging a call to multiple legs and using leg_delay_start, legs that lost the race before the leg_delay_start time is up still get originated for a brief moment (r:c5daf80e/FS-3218)
|
||||
core: Have UPNP/PMP active without opening port mappings in the router/firewall (r:008f9889/FS-3208)
|
||||
core: add execute_on function so you can have execute_on_answer_1 execute_on_answer_2 execute_on_answer_3 etc (r:27c6d111)
|
||||
core: do this slightly safer so we don't have the mutex locked when we exec the app (r:ef175741)
|
||||
core: Fix argument parsing for tone_detect app (r:38c3a67a/FS-3229)
|
||||
core: add L16 def for 32ms and allow timer matrix to drop to 1ms to support nelly (r:82e3d49f)
|
||||
core: fix segfault in zrtp srtcp (r:2330b340)
|
||||
core: add switch_clean_name_string util function to strip out caller id name chars that can cause issues (r:244048f8)
|
||||
core: switch_core_sqldb - clear pointer on release (r:aaef33cc)
|
||||
core: all [] {} and <> can be stacked and override the delim per set <><^^:>{}{^^:}{^^;}[][^^:] (r:4c4bf59e/FS-3246)
|
||||
core: fix default tipping point it was too low (r:e4eade33)
|
||||
core: enable optimal defaults on linux kernels that can support newer features. (r:0b51aca3)
|
||||
core: Lower NAT port mapping disabled log msg from WARNING to INFO (r:973a850d)
|
||||
core: Change the structure of the phrases/language system. Previously it was fxml->phrases->macros->language->macro. Changed it so fxml->languages->language->phrases->macros->macro You can have sub macros <macros name="voicemail"><macro ...> and allow you to call it login@voicemail. Change the sound-path to sound-prefix to make it constistant with the rest of freeswitch. Also allow to set a sound-prefix to a macros, so you can override it for a specific file set. You can set say-modules="en" or whatever in the <language section to define that say module to use. (r:4137b360)
|
||||
embedded languages: Provide core level support for conditional Set Global Variable (r:c017c24b/FSCORE-612)
|
||||
embedded languages: add insertFile front end to switch_ivr_insert_file and reswig (r:c4e350ab)
|
||||
fs_cli: block control-z from fs cli and print a warning how to exit properly (r:dc436b82)
|
||||
|
@ -271,6 +285,7 @@ freeswitch (1.0.7)
|
|||
libesl: Add 'make perlmod-install' to ESL (please test) (r:06c42179)
|
||||
libesl: build python esl bindings and ship them in freeswitch-python-package (r:44bfcf1d/FS-3128)
|
||||
libesl: use poll instead of select in ESL client lib because select is not your friend.... (r:ae595cd5)
|
||||
libesl: Add digit_timeout to ESL::IVR's playAndGetDigits method (r:f564d383)
|
||||
libfreetdm: implemented freetdm config nodes and ss7 initial configuration
|
||||
libfreetdm: fix codec for CAS signaling (r:b76e7f18)
|
||||
libfreetdm: freetdm: ss7- added support for incoming group blocks, started adding support for ansi (r:c219a73c)
|
||||
|
@ -331,12 +346,16 @@ freeswitch (1.0.7)
|
|||
mod_callcenter: New Agent order Possibility: Agent order by Level and Position by agents.last_offered_call. Change the default and sequentially-by-agent-order strategy to include the longest-idle-agent. This should offer a default consistant way to go through all the agent within the same tier/position. (Before, it was left to the DB to return the order of the result) (r:dcafff20/FS-3158)
|
||||
mod_callcenter: Generate per member uuid different from the member session uuid. Might fix transfer between queue. More changes are coming (r:b63a72f8)
|
||||
mod_callcenter: Remove the concept of Caller for Members. Event Socket event have been changed (CC-Caller.* to CC-Member.*) Also CC-Caller-UUID is renamed to CC-Member-Session-UUID. The reason for this is you could actually put people to be call in the queue. So they are not caller per say. But they are a member of a queue. (r:40a134bd)
|
||||
mod_callcenter: Reload a queue wont delete all the currently waiting members. Only a reload of the module will. (r:c5ae5de0/FS-3250)
|
||||
mod_callcenter: Add a very prototype (and maybe not functional) strategy called : sequentially-by-next-agent-order. It will try to find the last agent we tried to reach, and start calling more agent after that one based on position. It will use the level for the next agent, but once that level is done, it start back at the lowest level (r:bef6f0f4)
|
||||
mod_callcenter: New strategies: round-robin, random, and 'top-down' (r:2b4b23aa,r:bee247ca)
|
||||
mod_cdr_sqlite: initial commit (r:f625fe3b)
|
||||
mod_cdr_sqlite: config file for mod_cdr_sqlite (r:25bc8fe3)
|
||||
mod_cdr_sqlite: Drop transaction BEGIN/END around INSERT. We're only executing one command, and autocommit will automatically rollback if the INSERT fails. Sync state_handlers with mod_cdr_csv. Minor libpq fixups. (r:0f95b870)
|
||||
mod_celt: Bump celt to 0.10.0 (r:231fbe5e)
|
||||
mod_celt: update code in mod_celt to match API of 0.10.0 (r:6e4c30ea)
|
||||
mod_celt: Add dependency to fix parallel builds (r:6e37a8b2)
|
||||
mod_cepstral: add ability to set encoding of text (r:28738b06/FS-3001)
|
||||
mod_cidlookup: null xml is bad (r:095815f8)
|
||||
mod_cid_lookup: honor skipcitystate when using whitepages (r:a66654de/FSMOD-53)
|
||||
mod_commands: make break uuid_break and add cascade flag
|
||||
|
@ -390,6 +409,8 @@ freeswitch (1.0.7)
|
|||
mod_conference: prevent race condition on conference join/exit (r:1552ecf5)
|
||||
mod_conference: I finally tracked this down to the actual recordings generated by mod_conference. This patch delays the recording slightly to allow time for the buffer to fill up, we were riding it so closely that sometimes we would come up short and inject silence into the file to preserve time passing (r:3253bcb3/FS-3147)
|
||||
mod_conference: wait for channels to come up in paging mode (r:b8063c3d)
|
||||
mod_conference: Conference APIs for enabling/disabling enter/exit sounds for active conferences (r:31cebd4f/FS-3219)
|
||||
mod_conference: Fix pool swelling, replaced a pool strdup that could recur with a strdup/free to avoid it (r:bcd6c3a1/FS-3137)
|
||||
mod_curl: use method=post when post requested (r:c6a4ddd0/FSMOD-69)
|
||||
mod_db: fix stack corruption (MODAPP-407)
|
||||
mod_dialplan_xml: Add in the INFO log the caller id number when processing a request (Currenly only show the caller name) (r:e1df5e13)
|
||||
|
@ -415,6 +436,7 @@ freeswitch (1.0.7)
|
|||
mod_dptools: merge file_string into dptools (r:eefdb764)
|
||||
mod_dptools: change mod_dptools to use the better method of fetching user xml that does not hang onto the xml root (r:e52e44e3)
|
||||
mod_dptools: the intent for having the module and lang separate is for things where the same module can use different sets of sounds like en module and en-male or en-female lang (sound dirs) there was indeed a disconnect in the dialplan version of this app. Originally say was only available in phrase macros so I change the syntax of the say app so you can specify both the module and the lang absolte from the dp with something like he:he as the module name. (r:44304f49)
|
||||
mod_dptools: Set the default lang if not supplied (mod_say_en) (r:5382972a/FS-3215)
|
||||
mod_easyroute: Fix possible segfaults and memory leak during unload, and add new setting odbc-retries (r:7fbc47f8/FS-2973)
|
||||
mod_enum: switch mod_enum to use new portable in-tree version (r:2bbc37e3)
|
||||
mod_enum: fix race condition between ldns configure creating ldns/util.h and mod_enum (r:87884c5c)
|
||||
|
@ -496,10 +518,11 @@ freeswitch (1.0.7)
|
|||
mod_hash: use 5 seconds connection timeouts for remote connections (r:7431fbe9)
|
||||
mod_hash: use esl_recv_timed with a 5000ms timeout when doing api commands (r:27d8378f)
|
||||
mod_hash: limit_remote_thread sending invalid handle to esl_connect_timeout causing core (r:6cdd3e2a/MODAPP-446)
|
||||
mod_hash: avoid scheduler caling a function on null hash during shutdown (r:8458adeb)
|
||||
mod_hash: avoid scheduler calling a function on null hash during shutdown (r:8458adeb)
|
||||
mod_hash: add realm filter to hash_dump db command so that you can quickly dump all entries that belong only to a specific realm without getting the whole db (r:81347126)
|
||||
mod_h323: initial t.38 support. remake logical channel opening. add missing param name in example config. (r:8c58074c)
|
||||
mod_h323: some t.38 and lockinng improvements. replace ptrace with switch_log_printf. (r:5efe5c88)
|
||||
mod_h323: add missing conf prameter (r:0b353d7a)
|
||||
mod_h323: some t.38 and locking improvements. replace ptrace with switch_log_printf. (r:5efe5c88)
|
||||
mod_h323: add missing conf praameter (r:0b353d7a)
|
||||
mod_h323: Add mod_h323 to windows (r:015bcaf6/MODENDP-301)
|
||||
mod_h323: move PTrace level set to FSH323EndPoint::Initialise. partially apply patch from from Peter Olsson, Remove UnLock() when TryLock() failed and DEBUG_RTP_PACKETS directiv e. (r:7b5803f7)
|
||||
mod_h323: set network_addr of caller profile to signaling ip address. (requested by Steven Ayre) (r:072bf5ad)
|
||||
|
@ -518,6 +541,7 @@ freeswitch (1.0.7)
|
|||
mod_lcr: fix compiler warning on newer gcc (r:bfa414cb)
|
||||
mod_lcr: don't count twice (r:eaeabc7b/FS-1810)
|
||||
mod_lcr: properly destroy lcr object when done (r:084819a3/FS-3199)
|
||||
mod_lcr: don't add routes that have no rate of the desired type (r:82e3ccf8)
|
||||
mod_loopback: add loopback_bowout_on_execute var to make 1 legged loopback calls bow out of the picture
|
||||
mod_loopback: only execute app once in app mode (r:64f58f2d)
|
||||
mod_loopback: fix bug in mod_loopback where bowout=false (r:e9ab5368)
|
||||
|
@ -553,6 +577,8 @@ freeswitch (1.0.7)
|
|||
mod_osp:Changed OSP TCP port from 1080 to 5045. (r:03abefdf)
|
||||
mod_portaudio: Fix inbound state (CS_ROUTING not CS_INIT) (MODENDP-302)
|
||||
mod_portaudio: mod_portaudio improvements and bug fixes (r:33b74ca8/FS-3006)
|
||||
mod_portaudio: Add pa devlist to portaudio webapi (r:e8f10ea3)
|
||||
mod_protovm: This is a very early new prototype voicemail ivr system. You need to copy the sounds.xml and make it loadale in the language folder and protovm.conf.xml inside the autoload_configs folder. Configs file will most definitly change. Once stabilized, we make it install those file by default. (r:fb549777)
|
||||
mod_sangoma_codec: Add sample config file
|
||||
mod_sangoma_codec: added load/noload options for the supported codecs
|
||||
mod_sangoma_codec: rename load/noload to register/noregister
|
||||
|
@ -571,8 +597,10 @@ freeswitch (1.0.7)
|
|||
mod_say_en: introduce new say_string method of doing say and use it in mod_say_en as an example. try: eval ${say_string en.gsm en current_date_time pronounced ${strepoch()}} from the cli with this patch. We can do more to centralize the say things and go back and apply it to other langs, using this method you can set the desired file ext as well which I think is a bounty.... (r:d5ef86d7)
|
||||
mod_say_en: If you only tell SAY CURRENCY to say 100 it should only say 100 dollars without the "0 cents" (r:426a4e76/FS-2922)
|
||||
mod_say_es: fix grammar when saying dates and time (r:6bed19b2/MODAPP-429)
|
||||
mod_say_he: Add Hebrew say module (r:ebd9c83e/FS-3211)
|
||||
mod_say_ja: initial commit, still needs sound files (r:b2423158/FS-2755)
|
||||
mod_say_ru: Fix saying time with +1 hour of current time (r:68d74c31/MODAPP-444)
|
||||
mod_say_ru: now support say_string like mod_say_en. Now support channel variables gender,cases can be set in english and russian for example: <action application="set" data="cases=nominativus/> <action application="set" data="gender=male_h"/> <action application="say" data="ru NUMBER PRONOUNCED 1001"/> (r:8b5ecd2f)
|
||||
mod_say_zh: Number reading should now be OK for the whole range of integers for Cantonese and Mandarin
|
||||
mod_shout: bump mod_shout to use mpg123-1.13.2 to hopefully address unwanted calls to exit() and inherit other upstream fixes (r:079f3f73)
|
||||
mod_silk: Fix mod_silk compliance and performance issues (r:2ddbc457/MODCODEC-20)
|
||||
|
@ -600,6 +628,8 @@ freeswitch (1.0.7)
|
|||
mod_skypopen: making XEvents to works when EARLYMEDIA, and correctly manage threads death
|
||||
mod_skypopen: now answer a call only when directed to do it (before was trying to answer any incoming call). Lot of changes to a messy part, so maybe some problem will come out... (r:45c6c4d3)
|
||||
mod_skypopen: ignore early media sent by channels to be bridged before our channel is answered (r:ef14b78a)
|
||||
mod_skypopen: OSS driver, refinement (r:b0a23f8e)
|
||||
mod_skypopen: deleted osscuse subdir (r:4842a620)
|
||||
mod_snapshot: fix bad codepaths in mod_snapshot (r:844ac220)
|
||||
mod_sndfile: Add support for .alaw and .ulaw to mod_sndfile (r:facf09b8/MODFORM-41)
|
||||
mod_sndfile: return break in mod_sndfile when seek returns failure (r:564dc7e4)
|
||||
|
@ -753,6 +783,13 @@ freeswitch (1.0.7)
|
|||
mod_sofia: New Sofia API to look up the username of a given user (r:7556ec57/FS-3187)
|
||||
mod_sofia: sip_authentication was not cleared after nonce expired -caused sofia_reg_internal.db grow bigger and bigger with time (r:c735e28a/FS-3190)
|
||||
mod_sofia: pass failure across in T.38 passthru mode (r:31273b42)
|
||||
mod_sofia: auto-aleg-full and auto-aleg-domain for from_domain field in gateway (r:fda2283b)
|
||||
mod_sofia: After further review I can concede the point that we should always say partial considering how we do things. With this commit we should at least be sending separate partial updates for each existing dialog to everyone with a subscription. If we need to introduce more data, consolidate them etc. We need to do it in small chunks and keep things sane. (r:7eae7f37/FS-2877)
|
||||
mod_sofia: Fix:Attended transfer with bypass media fails in various ways (r:4b706dac/FS-3227)
|
||||
mod_sofia: SO, If the RFC told you to jump off a cliff......? (r:07b9186d/FS-3226)
|
||||
mod_sofia: Don't assume incoming "gw" contact param is valid (prevent possible DoS) (r:2b6f7070/FS-3244)
|
||||
mod_sofia: offer both avp and savp when using srtp (r:5857495e)
|
||||
mod_sofia: fix race in sla (r:a4ed829d)
|
||||
mod_spandsp: initial checkin of mod_fax/mod_voipcodecs merge into mod_spandsp (r:fa9a59a8)
|
||||
mod_spandsp: rework of new mod_spandsp to have functions broken up into different c files (r:65400642)
|
||||
mod_spandsp: improve duplicate digit detection and add 'min_dup_digit_spacing_ms' channel variable for use with the dtmf detector (r:eab4f246/FSMOD-45)
|
||||
|
@ -765,6 +802,8 @@ freeswitch (1.0.7)
|
|||
mod_spandsp: T.38 reINVITE glare condition causes FAX processing to stop. (r:04aa7ef9/FS-1682)
|
||||
mod_spandsp: improve nat handling when using stun or host as ext-rtp-ip (r:03e74c51/FS-526)
|
||||
mod_spandsp: Fire event when fax is finished; indicates result of fax attempt (r:314a2a1e/FS-3004)
|
||||
mod_spandsp: new option to set sip_execute_on_image to 't38_gateway self nocng' this should skip the tone detection adn go right into the gateway mode so you should be able to do only this and have it work based on remote re-invite (r:9227b538/FS-3252)
|
||||
mod_spandsp: additional fix to this bug and add better fax detect code to mod_spandsp (r:7fe313cf/FS-3252)
|
||||
mod_spidermonkey: allow vars to be set containing vars from languages (r:5cd072a3)
|
||||
mod_spidermonkey: fix seg in js hangup (r:7d554c11)
|
||||
mod_spidermonkey: Fix mod_spidermonkey build on FreeBSD, (Undefined symbol PR_LocalTimeParameters). (r:3edb8419)
|
||||
|
@ -778,6 +817,7 @@ freeswitch (1.0.7)
|
|||
mod_unimrcp: fix truncated TTS (r:e37dd41e/FS-3201)
|
||||
mod_unimrcp: Destroy schannel only *after* cleanup of its contents is done (r:0f17bcc5)
|
||||
mod_unimrcp: add locking to mrcp dtmf generator (r:f5704114/FS-3163)
|
||||
mod_unimrcp: check for NULL recog_hdr (r:478d5186/FS-3247)
|
||||
mod_valet_parking: add event data to valet parking hold event
|
||||
mod_valet_parking: add event for Valet Parking action exit
|
||||
mod_valet_parking: pass hold class on transfer (r:76a065ec)
|
||||
|
@ -797,6 +837,8 @@ freeswitch (1.0.7)
|
|||
mod_voicemail: let vmain-key and operator-key be set empty (r:de49305a)
|
||||
mod_voicemail: add ability to jump to a specific message (r:0f8fb4b1)
|
||||
mod_voicemail: vm-skip-instructions param in xml directory to disable instructions how to record a file (r:ed7e1f39)
|
||||
mod_voicemail: Implement 10 new standard api function call that allow you to control fs voicemail storage system. The goal is to have a standard API set for any additional storage system we wish the voicemail to run off. Current list of added api name are : vm_fsdb_msg_count, vm_fsdb_msg_list, vm_fsdb_msg_get, vm_fsdb_msg_delete, vm_fsdb_msg_undelete, vm_fsdb_msg_purge, vm_fsdb_msg_save, vm_fsdb_pref_greeting_set, vm_fsdb_pref_recname_set, vm_fsdb_pref_password_set. (r:1f4cb488)
|
||||
mod_voicemail: Adding a new voicemail fsdb api vm_fsdb_auth_login that does basic login authentication for a user (r:bfdfac5e)
|
||||
mod_xml_cdr: add force_process_cdr var to process b leg cdr on a case by case basis when b leg cdr is disabled (XML-17)
|
||||
mod_xml_cdr: add leg param to query string (XML-24)
|
||||
mod_xml_cdr: fix locked sessions (XML-26)
|
||||
|
|
|
@ -436,9 +436,24 @@
|
|||
<!-- The following phrases still need to be recorded -->
|
||||
<prompt phrase="Recording started." filename="ivr-recording_started.wav"/>
|
||||
<prompt phrase="Recording stopped." filename="ivr-recording_stopped.wav"/>
|
||||
<prompt phrase="Recording paused." filename="ivr-recording_paused.wav"/>
|
||||
<prompt phrase="Recording deleted." filename="ivr-recording_deleted.wav"/>
|
||||
|
||||
<prompt phrase="You are no longer in line." filename="ivr-no_longer_in_line.wav"/>
|
||||
<prompt phrase="question..." filename="ivr-question.wav"/>
|
||||
<prompt phrase="questions." filename="ivr-questions.wav"/>
|
||||
<prompt phrase="...has been answered." filename="ivr-has_been_answered.wav"/>
|
||||
<prompt phrase="...has been removed." filename="ivr-has_been_removed.wav"/>
|
||||
<prompt phrase="No questions in queue." filename="ivr-no_questions_in_queue.wav"/>
|
||||
<prompt phrase="This conference is in Q&A mode." filename="conference/conf-conference_is_in_qna_mode.wav"/>
|
||||
<prompt phrase="Q&A mode..." filename="conference/conf-qna_mode.wav"/>
|
||||
<prompt phrase="...is on" filename="ivr/ivr_is_on.wav"/>
|
||||
<prompt phrase="...is off" filename="ivr/ivr_is_off.wav"/>
|
||||
<prompt phrase="Entry sound..." filename="conference/conf-entry_sound.wav"/>
|
||||
<prompt phrase="Exit sound..." filename="conference/conf-exit_sound.wav"/>
|
||||
<prompt phrase="The PIN you entered is below the minimum length." filename="voicemail/vm-pin_below_minimum_length.wav"/>
|
||||
<prompt phrase="The minimum PIN length is..." filename="voicemail/vm-minimum_pin_length_is.wav"/>
|
||||
</ivr>
|
||||
|
||||
<misc>
|
||||
<prompt phrase="This call has been secured" filename="call_secured.wav"/>
|
||||
<prompt phrase="Followed by pound" filename="followed.wav"/>
|
||||
|
|
|
@ -752,6 +752,7 @@ fi
|
|||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_csv.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_pg_csv.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_sqlite.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cepstral.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cidlookup.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/conference.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/console.conf.xml
|
||||
|
@ -1064,10 +1065,13 @@ fi
|
|||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/en
|
||||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/en/demo
|
||||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/en/vm
|
||||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/en/dir
|
||||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/en/ivr
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/en/*.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/en/demo/*.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/en/vm/*.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/en/dir/*.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/en/ivr/*.xml
|
||||
%{prefix}/mod/mod_say_en.so*
|
||||
|
||||
%files lang-de
|
||||
|
@ -1085,6 +1089,7 @@ fi
|
|||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/fr
|
||||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/fr/demo
|
||||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/fr/vm
|
||||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/fr/dir
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/fr/*.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/fr/demo/*.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/fr/vm/*.xml
|
||||
|
@ -1096,6 +1101,7 @@ fi
|
|||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/ru
|
||||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/ru/demo
|
||||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/ru/vm
|
||||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/ru/dir
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/ru/*.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/ru/demo/*.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/ru/vm/*.xml
|
||||
|
@ -1107,6 +1113,7 @@ fi
|
|||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/he/
|
||||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/he/demo
|
||||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/he/vm
|
||||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/he/dir
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/he/*.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/he/demo/*.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/he/vm/*.xml
|
||||
|
|
|
@ -839,9 +839,9 @@ static const char *basic_gets(int *cnt)
|
|||
}
|
||||
Sleep(20);
|
||||
}
|
||||
#endif
|
||||
|
||||
return command_buf;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ESL", "esl_lua.2010.vcxproj", "{86B6AB99-A261-455A-9CD6-9142A5A1652E}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Debug|x64.Build.0 = Debug|x64
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Release|Win32.Build.0 = Release|Win32
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Release|x64.ActiveCfg = Release|x64
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,178 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>ESL</ProjectName>
|
||||
<ProjectGuid>{86B6AB99-A261-455A-9CD6-9142A5A1652E}</ProjectGuid>
|
||||
<RootNamespace>esl_lua.2010</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkIncremental>
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\;$(ProjectDir)..\src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>ESL_DECLARE_STATIC;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>esl.lib;lua51.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\$(Platform)\$(Configuration)\;$(ProjectDir)..\..\..\libs\esl\src\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\;$(ProjectDir)..\src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>ESL_DECLARE_STATIC;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>esl.lib;lua51.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\$(Platform)\$(Configuration)\;$(ProjectDir)..\..\..\libs\esl\src\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\;$(ProjectDir)..\src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>ESL_DECLARE_STATIC;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>esl.lib;lua51.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\$(Platform)\$(Configuration);$(ProjectDir)..\..\..\libs\esl\src\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\;$(ProjectDir)..\src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>ESL_DECLARE_STATIC;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>esl.lib;lua51.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\$(Platform)\$(Configuration);$(ProjectDir)..\..\..\libs\esl\src\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\esl_oop.cpp" />
|
||||
<ClCompile Include="esl_wrap.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\esl_oop.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="esl_wrap.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -323,7 +323,7 @@ static void default_logger(const char *file, const char *func, int line, int lev
|
|||
ret = esl_vasprintf(&data, fmt, ap);
|
||||
|
||||
if (ret != -1) {
|
||||
fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], file, line, func, data);
|
||||
fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], fp, line, func, data);
|
||||
free(data);
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ static struct {
|
|||
analog_option_t analog_options;
|
||||
switch_hash_t *ss7_configs;
|
||||
int sip_headers;
|
||||
uint8_t crash_on_assert;
|
||||
int crash_on_assert;
|
||||
} globals;
|
||||
|
||||
/* private data attached to each fs session */
|
||||
|
@ -720,7 +720,6 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
|||
ftdm_size_t len;
|
||||
unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
|
||||
ftdm_wait_flag_t wflags = FTDM_WRITE;
|
||||
ftdm_status_t status;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
|
@ -755,7 +754,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
|||
|
||||
|
||||
wflags = FTDM_WRITE;
|
||||
status = ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 10);
|
||||
ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 10);
|
||||
|
||||
if (!(wflags & FTDM_WRITE)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write not ready)\n");
|
||||
|
@ -1264,6 +1263,12 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
caller_data.ani.plan = (uint8_t)atoi(sipvar);
|
||||
}
|
||||
|
||||
/* Used by ftmod_sangoma_ss7 only */
|
||||
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI-NADI");
|
||||
if (sipvar) {
|
||||
ftdm_usrmsg_add_var(&usrmsg, "ss7_clg_nadi", sipvar);
|
||||
}
|
||||
|
||||
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI2");
|
||||
if (sipvar) {
|
||||
ftdm_set_string(caller_data.aniII, sipvar);
|
||||
|
@ -1284,6 +1289,12 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
caller_data.dnis.plan = (uint8_t)atoi(sipvar);
|
||||
}
|
||||
|
||||
/* Used by ftmod_sangoma_ss7 only */
|
||||
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-DNIS-NADI");
|
||||
if (sipvar) {
|
||||
ftdm_usrmsg_add_var(&usrmsg, "ss7_clg_nadi", sipvar);
|
||||
}
|
||||
|
||||
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS");
|
||||
if (sipvar) {
|
||||
ftdm_set_string(caller_data.rdnis.digits, sipvar);
|
||||
|
@ -1299,6 +1310,12 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
caller_data.rdnis.plan = (uint8_t)atoi(sipvar);
|
||||
}
|
||||
|
||||
/* Used by ftmod_sangoma_ss7 only */
|
||||
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-NADI");
|
||||
if (sipvar) {
|
||||
ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_nadi", sipvar);
|
||||
}
|
||||
|
||||
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-Screen");
|
||||
if (sipvar) {
|
||||
caller_data.screen = (uint8_t)atoi(sipvar);
|
||||
|
@ -1308,6 +1325,8 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
if (sipvar) {
|
||||
caller_data.pres = (uint8_t)atoi(sipvar);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN)) {
|
||||
|
@ -3615,7 +3634,7 @@ void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *
|
|||
"--------------------------------------------------------------------------------\n" \
|
||||
"ftdm list\n" \
|
||||
"ftdm start|stop <span_name|span_id>\n" \
|
||||
"ftdm restart <span_id|span_name> <chan_id>\n" \
|
||||
"ftdm restart <span_id|span_name> [<chan_id>]\n" \
|
||||
"ftdm dump <span_id|span_name> [<chan_id>]\n" \
|
||||
"ftdm sigstatus get|set [<span_id|span_name>] [<channel>] [<sigstatus>]\n" \
|
||||
"ftdm trace <path> <span_id|span_name> [<chan_id>]\n" \
|
||||
|
@ -4141,10 +4160,11 @@ SWITCH_STANDARD_API(ft_function)
|
|||
stream->write_function(stream, "+OK queue sizes set to Rx %d and Tx %d\n", rxsize, txsize);
|
||||
} else if (!strcasecmp(argv[0], "restart")) {
|
||||
uint32_t chan_id = 0;
|
||||
uint32_t ccount = 0;
|
||||
ftdm_channel_t *chan;
|
||||
ftdm_span_t *span = NULL;
|
||||
if (argc < 3) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm restart <span_id> <chan_id>\n");
|
||||
if (argc < 2) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm restart <span_id> [<chan_id>]\n");
|
||||
goto end;
|
||||
}
|
||||
ftdm_span_find_by_name(argv[1], &span);
|
||||
|
@ -4153,14 +4173,31 @@ SWITCH_STANDARD_API(ft_function)
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
chan_id = atoi(argv[2]);
|
||||
if (chan_id > ftdm_span_get_chan_count(span)) {
|
||||
stream->write_function(stream, "-ERR invalid chan\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (chan_id) {
|
||||
chan = ftdm_span_get_channel(span, chan_id);
|
||||
if (!chan) {
|
||||
stream->write_function(stream, "-ERR Could not find chan\n");
|
||||
goto end;
|
||||
}
|
||||
stream->write_function(stream, "Resetting channel %s:%s\n", argv[2], argv[3]);
|
||||
stream->write_function(stream, "Resetting channel %s:%s\n", argv[1], argv[2]);
|
||||
ftdm_channel_reset(chan);
|
||||
} else {
|
||||
uint32_t i = 0;
|
||||
ccount = ftdm_span_get_chan_count(span);
|
||||
for (i = 1; i < ccount; i++) {
|
||||
chan = ftdm_span_get_channel(span, i);
|
||||
stream->write_function(stream, "Resetting channel %s:%d\n", argv[1], i);
|
||||
ftdm_channel_reset(chan);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
char *rply = ftdm_api_execute(cmd);
|
||||
|
|
|
@ -3563,6 +3563,16 @@ static FIO_WRITE_FUNCTION(ftdm_raw_write)
|
|||
static FIO_READ_FUNCTION(ftdm_raw_read)
|
||||
{
|
||||
ftdm_status_t status = ftdmchan->fio->read(ftdmchan, data, datalen);
|
||||
|
||||
if (status == FTDM_SUCCESS && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_USE_RX_GAIN)
|
||||
&& (ftdmchan->native_codec == FTDM_CODEC_ALAW || ftdmchan->native_codec == FTDM_CODEC_ULAW)) {
|
||||
ftdm_size_t i = 0;
|
||||
unsigned char *rdata = data;
|
||||
for (i = 0; i < *datalen; i++) {
|
||||
rdata[i] = ftdmchan->rxgain_table[rdata[i]];
|
||||
}
|
||||
}
|
||||
|
||||
if (status == FTDM_SUCCESS && ftdmchan->fds[FTDM_READ_TRACE_INDEX] > -1) {
|
||||
ftdm_size_t dlen = *datalen;
|
||||
if ((ftdm_size_t)write(ftdmchan->fds[FTDM_READ_TRACE_INDEX], data, (int)dlen) != dlen) {
|
||||
|
@ -3730,7 +3740,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data
|
|||
ftdm_status_t status = FTDM_FAIL;
|
||||
fio_codec_t codec_func = NULL;
|
||||
ftdm_size_t max = *datalen;
|
||||
unsigned i = 0;
|
||||
|
||||
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "ftdmchan is null\n");
|
||||
ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "No I/O module attached to ftdmchan\n");
|
||||
|
@ -3769,13 +3778,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_USE_RX_GAIN)
|
||||
&& (ftdmchan->native_codec == FTDM_CODEC_ALAW || ftdmchan->native_codec == FTDM_CODEC_ULAW)) {
|
||||
unsigned char *rdata = data;
|
||||
for (i = 0; i < *datalen; i++) {
|
||||
rdata[i] = ftdmchan->rxgain_table[rdata[i]];
|
||||
}
|
||||
}
|
||||
handle_tone_generation(ftdmchan);
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) {
|
||||
|
|
|
@ -854,7 +854,6 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
|
|||
{
|
||||
ftdm_span_t *span = spri->span;
|
||||
ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->hangup.channel);
|
||||
q931_call *call = NULL;
|
||||
|
||||
if (!chan) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "-- Hangup on channel %d:%d %s but it's not in use?\n", ftdm_span_get_id(spri->span), pevent->hangup.channel);
|
||||
|
@ -868,22 +867,13 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (!chan->call_data) {
|
||||
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Ignoring remote hangup in state %s with no call data\n", ftdm_channel_get_state_str(chan));
|
||||
goto done;
|
||||
}
|
||||
|
||||
call = (q931_call *)chan->call_data;
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n", ftdm_span_get_id(spri->span), pevent->hangup.channel);
|
||||
|
||||
pri_release(spri->pri, call, 0);
|
||||
pri_destroycall(spri->pri, call);
|
||||
pri_hangup(spri->pri, pevent->hangup.call, -1);
|
||||
|
||||
chan->caller_data.hangup_cause = pevent->hangup.cause;
|
||||
chan->call_data = NULL;
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
|
||||
ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
done:
|
||||
ftdm_channel_unlock(chan);
|
||||
return 0;
|
||||
|
|
|
@ -996,11 +996,15 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
|
|||
ftdm_clear_flag(span, FTDM_SPAN_STOP_THREAD);
|
||||
ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD);
|
||||
|
||||
if (signal_data->raw_trace_q921 == SNGISDN_OPT_TRUE) {
|
||||
if (signal_data->trace_q921 == SNGISDN_OPT_TRUE ||
|
||||
signal_data->raw_trace_q921 == SNGISDN_OPT_TRUE) {
|
||||
|
||||
sngisdn_activate_trace(span, SNGISDN_TRACE_Q921);
|
||||
}
|
||||
|
||||
if (signal_data->raw_trace_q931 == SNGISDN_OPT_TRUE) {
|
||||
if (signal_data->trace_q931 == SNGISDN_OPT_TRUE ||
|
||||
signal_data->raw_trace_q931 == SNGISDN_OPT_TRUE) {
|
||||
|
||||
sngisdn_activate_trace(span, SNGISDN_TRACE_Q931);
|
||||
}
|
||||
|
||||
|
|
|
@ -213,6 +213,8 @@ typedef struct sngisdn_span_data {
|
|||
int8_t facility_timeout;
|
||||
uint8_t num_local_numbers;
|
||||
uint8_t ignore_cause_value;
|
||||
uint8_t trace_q931; /* TODO: combine with trace_flags */
|
||||
uint8_t trace_q921; /* TODO: combine with trace_flags */
|
||||
uint8_t raw_trace_q931; /* TODO: combine with trace_flags */
|
||||
uint8_t raw_trace_q921; /* TODO: combine with trace_flags */
|
||||
uint8_t timer_t3;
|
||||
|
|
|
@ -369,6 +369,10 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
parse_yesno(var, val, &signal_data->facility_ie_decode);
|
||||
} else if (!strcasecmp(var, "ignore-cause-value")) {
|
||||
parse_yesno(var, val, &signal_data->ignore_cause_value);
|
||||
} else if (!strcasecmp(var, "q931-trace")) {
|
||||
parse_yesno(var, val, &signal_data->trace_q931);
|
||||
} else if (!strcasecmp(var, "q921-trace")) {
|
||||
parse_yesno(var, val, &signal_data->trace_q921);
|
||||
} else if (!strcasecmp(var, "q931-raw-trace")) {
|
||||
parse_yesno(var, val, &signal_data->raw_trace_q931);
|
||||
} else if (!strcasecmp(var, "q921-raw-trace")) {
|
||||
|
|
|
@ -207,9 +207,10 @@ int ft_to_sngss7_cfg_all(void)
|
|||
|
||||
/* go through all the relays channels and configure it */
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.relay[x].id != 0) {
|
||||
while (x < (MAX_RELAY_CHANNELS)) {
|
||||
/* check if this relay channel has been configured already */
|
||||
if (!(g_ftdm_sngss7_data.cfg.relay[x].flags & SNGSS7_CONFIGURED)) {
|
||||
if ((g_ftdm_sngss7_data.cfg.relay[x].id != 0) &&
|
||||
(!(g_ftdm_sngss7_data.cfg.relay[x].flags & SNGSS7_CONFIGURED))) {
|
||||
|
||||
/* send the specific configuration */
|
||||
if (ftmod_ss7_relay_chan_config(x)) {
|
||||
|
@ -223,13 +224,13 @@ int ft_to_sngss7_cfg_all(void)
|
|||
g_ftdm_sngss7_data.cfg.relay[x].flags |= SNGSS7_CONFIGURED;
|
||||
} /* if !SNGSS7_CONFIGURED */
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.relay[x].id != 0) */
|
||||
} /* while (x < (MAX_RELAY_CHANNELS)) */
|
||||
|
||||
x = 1;
|
||||
while (x < (MAX_MTP_LINKS + 1)) {
|
||||
while (x < (MAX_MTP_LINKS)) {
|
||||
/* check if this link has been configured already */
|
||||
if (!(g_ftdm_sngss7_data.cfg.mtp1Link[x].flags & SNGSS7_CONFIGURED) &&
|
||||
(g_ftdm_sngss7_data.cfg.mtp1Link[x].id != 0)) {
|
||||
if ((g_ftdm_sngss7_data.cfg.mtp1Link[x].id != 0) &&
|
||||
(!(g_ftdm_sngss7_data.cfg.mtp1Link[x].flags & SNGSS7_CONFIGURED))) {
|
||||
|
||||
/* configure mtp1 */
|
||||
if (ftmod_ss7_mtp1_psap_config(x)) {
|
||||
|
@ -243,13 +244,13 @@ int ft_to_sngss7_cfg_all(void)
|
|||
g_ftdm_sngss7_data.cfg.mtp1Link[x].flags |= SNGSS7_CONFIGURED;
|
||||
}
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.mtp1Link[x].id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
x = 1;
|
||||
while (x < (MAX_MTP_LINKS + 1)) {
|
||||
while (x < (MAX_MTP_LINKS)) {
|
||||
/* check if this link has been configured already */
|
||||
if (!(g_ftdm_sngss7_data.cfg.mtp2Link[x].flags & SNGSS7_CONFIGURED) &&
|
||||
(g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0)) {
|
||||
if ((g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) &&
|
||||
(!(g_ftdm_sngss7_data.cfg.mtp2Link[x].flags & SNGSS7_CONFIGURED))) {
|
||||
|
||||
/* configure mtp2 */
|
||||
if (ftmod_ss7_mtp2_dlsap_config(x)) {
|
||||
|
@ -263,13 +264,13 @@ int ft_to_sngss7_cfg_all(void)
|
|||
g_ftdm_sngss7_data.cfg.mtp2Link[x].flags |= SNGSS7_CONFIGURED;
|
||||
}
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
x = 1;
|
||||
while (x < (MAX_MTP_LINKS + 1)) {
|
||||
while (x < (MAX_MTP_LINKS)) {
|
||||
/* check if this link has been configured already */
|
||||
if (!(g_ftdm_sngss7_data.cfg.mtp3Link[x].flags & SNGSS7_CONFIGURED) &&
|
||||
(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0)) {
|
||||
if ((g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) &&
|
||||
(!(g_ftdm_sngss7_data.cfg.mtp3Link[x].flags & SNGSS7_CONFIGURED))) {
|
||||
|
||||
/* configure mtp3 */
|
||||
if (ftmod_ss7_mtp3_dlsap_config(x)) {
|
||||
|
@ -284,12 +285,13 @@ int ft_to_sngss7_cfg_all(void)
|
|||
}
|
||||
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.nsap[x].id != 0) {
|
||||
while (x < (MAX_NSAPS)) {
|
||||
/* check if this link has been configured already */
|
||||
if (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_CONFIGURED)) {
|
||||
if ((g_ftdm_sngss7_data.cfg.nsap[x].id != 0) &&
|
||||
(!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_CONFIGURED))) {
|
||||
|
||||
ret = ftmod_ss7_mtp3_nsap_config(x);
|
||||
if (ret) {
|
||||
|
@ -312,12 +314,13 @@ int ft_to_sngss7_cfg_all(void)
|
|||
} /* if !SNGSS7_CONFIGURED */
|
||||
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.nsap[x].id != 0) */
|
||||
} /* while (x < (MAX_NSAPS)) */
|
||||
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) {
|
||||
while (x < (MAX_MTP_LINKSETS+1)) {
|
||||
/* check if this link has been configured already */
|
||||
if (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_CONFIGURED)) {
|
||||
if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) &&
|
||||
(!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_CONFIGURED))) {
|
||||
|
||||
if (ftmod_ss7_mtp3_linkset_config(x)) {
|
||||
SS7_CRITICAL("MTP3 LINKSET %d configuration FAILED!\n", x);
|
||||
|
@ -331,12 +334,13 @@ int ft_to_sngss7_cfg_all(void)
|
|||
} /* if !SNGSS7_CONFIGURED */
|
||||
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKSETS+1)) */
|
||||
|
||||
x = 1;
|
||||
while ((g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0)) {
|
||||
while (x < (MAX_MTP_ROUTES+1)) {
|
||||
/* check if this link has been configured already */
|
||||
if (!(g_ftdm_sngss7_data.cfg.mtpRoute[x].flags & SNGSS7_CONFIGURED)) {
|
||||
if ((g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) &&
|
||||
(!(g_ftdm_sngss7_data.cfg.mtpRoute[x].flags & SNGSS7_CONFIGURED))) {
|
||||
|
||||
if (ftmod_ss7_mtp3_route_config(x)) {
|
||||
SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x);
|
||||
|
@ -350,12 +354,13 @@ int ft_to_sngss7_cfg_all(void)
|
|||
} /* if !SNGSS7_CONFIGURED */
|
||||
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) */
|
||||
} /* while (x < (MAX_MTP_ROUTES+1)) */
|
||||
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.isap[x].id != 0) {
|
||||
while (x < (MAX_ISAPS)) {
|
||||
/* check if this link has been configured already */
|
||||
if (!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_CONFIGURED)) {
|
||||
if ((g_ftdm_sngss7_data.cfg.isap[x].id != 0) &&
|
||||
(!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_CONFIGURED))) {
|
||||
|
||||
if (ftmod_ss7_isup_isap_config(x)) {
|
||||
SS7_CRITICAL("ISUP ISAP %d configuration FAILED!\n", x);
|
||||
|
@ -369,13 +374,14 @@ int ft_to_sngss7_cfg_all(void)
|
|||
} /* if !SNGSS7_CONFIGURED */
|
||||
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.isap[x].id != 0) */
|
||||
} /* while (x < (MAX_ISAPS)) */
|
||||
|
||||
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) {
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) {
|
||||
while (x < (MAX_ISUP_INFS)) {
|
||||
/* check if this link has been configured already */
|
||||
if (!(g_ftdm_sngss7_data.cfg.isupIntf[x].flags & SNGSS7_CONFIGURED)) {
|
||||
if ((g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) &&
|
||||
(!(g_ftdm_sngss7_data.cfg.isupIntf[x].flags & SNGSS7_CONFIGURED))) {
|
||||
|
||||
if (ftmod_ss7_isup_intf_config(x)) {
|
||||
SS7_CRITICAL("ISUP INTF %d configuration FAILED!\n", x);
|
||||
|
@ -391,11 +397,14 @@ int ft_to_sngss7_cfg_all(void)
|
|||
} /* if !SNGSS7_CONFIGURED */
|
||||
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) */
|
||||
} /* while (x < (MAX_ISUP_INFS)) */
|
||||
} /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) */
|
||||
|
||||
x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1;
|
||||
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
|
||||
/* check if this link has been configured already */
|
||||
if ((g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) &&
|
||||
(!(g_ftdm_sngss7_data.cfg.isupCkt[x].flags & SNGSS7_CONFIGURED))) {
|
||||
|
||||
if (ftmod_ss7_isup_ckt_config(x)) {
|
||||
SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x);
|
||||
|
@ -406,6 +415,7 @@ int ft_to_sngss7_cfg_all(void)
|
|||
|
||||
/* set the SNGSS7_CONFIGURED flag */
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].flags |= SNGSS7_CONFIGURED;
|
||||
} /* if !SNGSS7_CONFIGURED */
|
||||
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */
|
||||
|
|
|
@ -724,6 +724,9 @@ static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream)
|
|||
stream->write_function(stream, "ftdm ss7 lpo link X\n");
|
||||
stream->write_function(stream, "ftdm ss7 lpr link X\n");
|
||||
stream->write_function(stream, "\n");
|
||||
stream->write_function(stream, "Ftmod_sangoma_ss7 Relay status:\n");
|
||||
stream->write_function(stream, "ftdm ss7 show status relay X\n");
|
||||
stream->write_function(stream, "\n");
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
@ -1207,8 +1210,8 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span,
|
|||
stream->write_function(stream, "r_hw=N|");
|
||||
}
|
||||
|
||||
if (sngss7_test_ckt_flag(ss7_info, FLAG_RELAY_DOWN)) {
|
||||
stream->write_function(stream, "relay=Y");
|
||||
if (sngss7_test_ckt_blk_flag(ss7_info, FLAG_RELAY_DOWN)) {
|
||||
stream->write_function(stream, "relay=Y|");
|
||||
}else {
|
||||
stream->write_function(stream, "relay=N");
|
||||
}
|
||||
|
@ -1366,7 +1369,7 @@ static ftdm_status_t handle_status_mtp3link(ftdm_stream_handle_t *stream, char *
|
|||
|
||||
/* find the link request by it's name */
|
||||
x = 1;
|
||||
while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) {
|
||||
while(x < (MAX_MTP_LINKS+1)) {
|
||||
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) {
|
||||
|
||||
/* send the status request */
|
||||
|
@ -1392,7 +1395,7 @@ static ftdm_status_t handle_status_mtp3link(ftdm_stream_handle_t *stream, char *
|
|||
|
||||
/* move to the next link */
|
||||
x++;
|
||||
} /* while (id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
stream->write_function(stream, "Failed to find link=\"%s\"\n", name);
|
||||
|
||||
|
@ -1408,7 +1411,7 @@ static ftdm_status_t handle_status_mtp2link(ftdm_stream_handle_t *stream, char *
|
|||
|
||||
/* find the link request by it's name */
|
||||
x = 1;
|
||||
while(g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) {
|
||||
while(x < (MAX_MTP_LINKS+1)) {
|
||||
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp2Link[x].name, name)) {
|
||||
|
||||
/* send the status request */
|
||||
|
@ -1436,7 +1439,7 @@ static ftdm_status_t handle_status_mtp2link(ftdm_stream_handle_t *stream, char *
|
|||
|
||||
/* move to the next link */
|
||||
x++;
|
||||
} /* while (id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
stream->write_function(stream, "Failed to find link=\"%s\"\n", name);
|
||||
|
||||
|
@ -1452,7 +1455,7 @@ static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *n
|
|||
|
||||
/* find the linkset request by it's name */
|
||||
x = 1;
|
||||
while(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) {
|
||||
while(x < (MAX_MTP_LINKSETS+1)) {
|
||||
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, name)) {
|
||||
|
||||
/* send the status request */
|
||||
|
@ -1487,7 +1490,7 @@ static ftdm_status_t handle_set_inhibit(ftdm_stream_handle_t *stream, char *name
|
|||
|
||||
/* find the link request by it's name */
|
||||
x = 1;
|
||||
while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) {
|
||||
while(x < (MAX_MTP_LINKS+1)) {
|
||||
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) {
|
||||
|
||||
/* send the inhibit request */
|
||||
|
@ -1504,7 +1507,7 @@ static ftdm_status_t handle_set_inhibit(ftdm_stream_handle_t *stream, char *name
|
|||
|
||||
/* move to the next linkset */
|
||||
x++;
|
||||
} /* while (id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
stream->write_function(stream, "Failed to find link=\"%s\"\n", name);
|
||||
|
||||
|
@ -1519,7 +1522,7 @@ static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *na
|
|||
|
||||
/* find the link request by it's name */
|
||||
x = 1;
|
||||
while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) {
|
||||
while(x < (MAX_MTP_LINKS+1)) {
|
||||
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) {
|
||||
|
||||
/* send the uninhibit request */
|
||||
|
@ -1536,7 +1539,7 @@ static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *na
|
|||
|
||||
/* move to the next linkset */
|
||||
x++;
|
||||
} /* while (id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
stream->write_function(stream, "Failed to find link=\"%s\"\n", name);
|
||||
|
||||
|
@ -1891,7 +1894,7 @@ static ftdm_status_t handle_bind_link(ftdm_stream_handle_t *stream, char *name)
|
|||
|
||||
/* find the link request by it's name */
|
||||
x = 1;
|
||||
while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) {
|
||||
while(x < (MAX_MTP_LINKS+1)) {
|
||||
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) {
|
||||
|
||||
/* send the uninhibit request */
|
||||
|
@ -1907,7 +1910,7 @@ static ftdm_status_t handle_bind_link(ftdm_stream_handle_t *stream, char *name)
|
|||
|
||||
/* move to the next link */
|
||||
x++;
|
||||
} /* while (id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
stream->write_function(stream, "Could not find link=%s\n", name);
|
||||
|
||||
|
@ -1922,7 +1925,7 @@ static ftdm_status_t handle_unbind_link(ftdm_stream_handle_t *stream, char *name
|
|||
|
||||
/* find the link request by it's name */
|
||||
x = 1;
|
||||
while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) {
|
||||
while(x < (MAX_MTP_LINKS+1)) {
|
||||
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) {
|
||||
|
||||
/* send the uninhibit request */
|
||||
|
@ -1938,7 +1941,7 @@ static ftdm_status_t handle_unbind_link(ftdm_stream_handle_t *stream, char *name
|
|||
|
||||
/* move to the next link */
|
||||
x++;
|
||||
} /* while (id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
stream->write_function(stream, "Could not find link=%s\n", name);
|
||||
|
||||
|
@ -1953,7 +1956,7 @@ static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *na
|
|||
|
||||
/* find the link request by it's name */
|
||||
x = 1;
|
||||
while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) {
|
||||
while(x < (MAX_MTP_LINKS+1)) {
|
||||
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) {
|
||||
|
||||
/* send the uninhibit request */
|
||||
|
@ -1969,7 +1972,7 @@ static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *na
|
|||
|
||||
/* move to the next link */
|
||||
x++;
|
||||
} /* while (id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
stream->write_function(stream, "Could not find link=%s\n", name);
|
||||
|
||||
|
@ -1984,7 +1987,7 @@ static ftdm_status_t handle_deactivate_link(ftdm_stream_handle_t *stream, char *
|
|||
|
||||
/* find the link request by it's name */
|
||||
x = 1;
|
||||
while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) {
|
||||
while(x < (MAX_MTP_LINKS+1)) {
|
||||
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) {
|
||||
|
||||
/* send the deactivate request */
|
||||
|
@ -2000,7 +2003,7 @@ static ftdm_status_t handle_deactivate_link(ftdm_stream_handle_t *stream, char *
|
|||
|
||||
/* move to the next link */
|
||||
x++;
|
||||
} /* while (id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
stream->write_function(stream, "Could not find link=%s\n", name);
|
||||
|
||||
|
@ -2015,7 +2018,7 @@ static ftdm_status_t handle_activate_linkset(ftdm_stream_handle_t *stream, char
|
|||
|
||||
/* find the linkset request by it's name */
|
||||
x = 1;
|
||||
while(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) {
|
||||
while(x < (MAX_MTP_LINKSETS+1)) {
|
||||
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, name)) {
|
||||
|
||||
/* send the activate request */
|
||||
|
@ -2046,7 +2049,7 @@ static ftdm_status_t handle_deactivate_linkset(ftdm_stream_handle_t *stream, cha
|
|||
|
||||
/* find the linkset request by it's name */
|
||||
x = 1;
|
||||
while(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) {
|
||||
while(x < (MAX_MTP_LINKSETS+1)) {
|
||||
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, name)) {
|
||||
|
||||
/* send the deactivate request */
|
||||
|
@ -2078,7 +2081,7 @@ static ftdm_status_t handle_tx_lpo(ftdm_stream_handle_t *stream, char *name)
|
|||
|
||||
/* find the link request by it's name */
|
||||
x = 1;
|
||||
while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) {
|
||||
while(x < (MAX_MTP_LINKS+1)) {
|
||||
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) {
|
||||
|
||||
/* send the uninhibit request */
|
||||
|
@ -2094,7 +2097,7 @@ static ftdm_status_t handle_tx_lpo(ftdm_stream_handle_t *stream, char *name)
|
|||
|
||||
/* move to the next link */
|
||||
x++;
|
||||
} /* while (id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
stream->write_function(stream, "Could not find link=%s\n", name);
|
||||
|
||||
|
@ -2109,7 +2112,7 @@ static ftdm_status_t handle_tx_lpr(ftdm_stream_handle_t *stream, char *name)
|
|||
|
||||
/* find the link request by it's name */
|
||||
x = 1;
|
||||
while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) {
|
||||
while(x < (MAX_MTP_LINKS+1)) {
|
||||
if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) {
|
||||
|
||||
/* send the uninhibit request */
|
||||
|
@ -2125,7 +2128,7 @@ static ftdm_status_t handle_tx_lpr(ftdm_stream_handle_t *stream, char *name)
|
|||
|
||||
/* move to the next link */
|
||||
x++;
|
||||
} /* while (id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKS+1)) */
|
||||
|
||||
stream->write_function(stream, "Could not find link=%s\n", name);
|
||||
|
||||
|
@ -2144,7 +2147,7 @@ static ftdm_status_t handle_status_relay(ftdm_stream_handle_t *stream, char *nam
|
|||
|
||||
/* find the channel request by it's name */
|
||||
x = 1;
|
||||
while(g_ftdm_sngss7_data.cfg.relay[x].id != 0) {
|
||||
while(x < (MAX_RELAY_CHANNELS)) {
|
||||
if (!strcasecmp(g_ftdm_sngss7_data.cfg.relay[x].name, name)) {
|
||||
|
||||
if (ftmod_ss7_relay_status(g_ftdm_sngss7_data.cfg.relay[x].id, &sta)) {
|
||||
|
@ -2168,7 +2171,7 @@ static ftdm_status_t handle_status_relay(ftdm_stream_handle_t *stream, char *nam
|
|||
/* move to the next link */
|
||||
x++;
|
||||
|
||||
} /* g_ftdm_sngss7_data.cfg.relay[x].id */
|
||||
} /* x < (MAX_RELAY_CHANNELS) */
|
||||
|
||||
success:
|
||||
return FTDM_SUCCESS;
|
||||
|
|
|
@ -85,9 +85,10 @@ int ft_to_sngss7_activate_all(void)
|
|||
int x;
|
||||
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.isap[x].id != 0) {
|
||||
while (x < (MAX_ISAPS)) {
|
||||
/* check if this link has already been actived */
|
||||
if (!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_ACTIVE)) {
|
||||
if ((g_ftdm_sngss7_data.cfg.isap[x].id != 0) &&
|
||||
(!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_ACTIVE))) {
|
||||
|
||||
if (ftmod_ss7_enable_isap(x)) {
|
||||
SS7_CRITICAL("ISAP %d Enable: NOT OK\n", x);
|
||||
|
@ -101,12 +102,13 @@ int ft_to_sngss7_activate_all(void)
|
|||
} /* if !SNGSS7_ACTIVE */
|
||||
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.isap[x].id != 0) */
|
||||
} /* while (x < (MAX_ISAPS)) */
|
||||
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.nsap[x].id != 0) {
|
||||
while (x < (MAX_NSAPS)) {
|
||||
/* check if this link has already been actived */
|
||||
if (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_ACTIVE)) {
|
||||
if ((g_ftdm_sngss7_data.cfg.nsap[x].id != 0) &&
|
||||
(!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_ACTIVE))) {
|
||||
|
||||
if (ftmod_ss7_enable_nsap(x)) {
|
||||
SS7_CRITICAL("NSAP %d Enable: NOT OK\n", x);
|
||||
|
@ -120,13 +122,14 @@ int ft_to_sngss7_activate_all(void)
|
|||
} /* if !SNGSS7_ACTIVE */
|
||||
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.nsap[x].id != 0) */
|
||||
} /* while (x < (MAX_NSAPS)) */
|
||||
|
||||
if (g_ftdm_sngss7_data.cfg.mtpRoute[1].id != 0) {
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) {
|
||||
while (x < (MAX_MTP_LINKSETS+1)) {
|
||||
/* check if this link has already been actived */
|
||||
if (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_ACTIVE)) {
|
||||
if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) &&
|
||||
(!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_ACTIVE))) {
|
||||
|
||||
if (ftmod_ss7_enable_mtpLinkSet(x)) {
|
||||
SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
|
||||
|
@ -140,7 +143,7 @@ int ft_to_sngss7_activate_all(void)
|
|||
} /* if !SNGSS7_ACTIVE */
|
||||
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) */
|
||||
} /* while (x < (MAX_MTP_LINKSETS+1)) */
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1565,6 +1565,9 @@ ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
/* throw the unblock flag */
|
||||
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_RX);
|
||||
|
||||
/* clear the block flag */
|
||||
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
|
||||
|
||||
/* set the channel to suspended state */
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
|
||||
/* find the name for the sap in question */
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) {
|
||||
while (x < (MAX_MTP_LINKS+1)) {
|
||||
if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) {
|
||||
break;
|
||||
}
|
||||
|
@ -149,22 +149,17 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
|
||||
|
||||
switch (sta->t.usta.alarm.cause) {
|
||||
/******************************************************************/
|
||||
case (LCM_CAUSE_UNKNOWN):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s\n",
|
||||
buf,
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event));
|
||||
break;
|
||||
/******************************************************************/
|
||||
case (LCM_CAUSE_MGMT_INITIATED):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s[MGMT] %s\n",
|
||||
ftdm_log(FTDM_LOG_DEBUG,"[MTP2]%s[MGMT] cause:%s event:%s\n",
|
||||
buf,
|
||||
DECODE_LCM_CAUSE(sta->t.usta.alarm.cause),
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event));
|
||||
break;
|
||||
/******************************************************************/
|
||||
case (LCM_CAUSE_UNKNOWN):
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s (***unknown cause***)\n",
|
||||
ftdm_log(FTDM_LOG_DEBUG,"[MTP2]%s cause:%s event:%s\n",
|
||||
buf,
|
||||
DECODE_LCM_CAUSE(sta->t.usta.alarm.cause),
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event));
|
||||
break;
|
||||
/******************************************************************/
|
||||
|
@ -175,7 +170,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
|
||||
/* find the name for the sap in question */
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) {
|
||||
while (x < (MAX_MTP_LINKS+1)) {
|
||||
if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) {
|
||||
break;
|
||||
}
|
||||
|
@ -198,7 +193,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
|
||||
/* find the name for the sap in question */
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) {
|
||||
while (x < (MAX_MTP_LINKS+1)) {
|
||||
if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) {
|
||||
break;
|
||||
}
|
||||
|
@ -211,7 +206,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name);
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n",
|
||||
ftdm_log(FTDM_LOG_DEBUG,"[MTP2]%s %s : %s\n",
|
||||
buf,
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_DISC_REASON(sta->t.usta.evntParm[1]));
|
||||
|
@ -222,7 +217,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
|
||||
/* find the name for the sap in question */
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) {
|
||||
while (x < (MAX_MTP_LINKS+1)) {
|
||||
if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) {
|
||||
break;
|
||||
}
|
||||
|
@ -248,7 +243,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
|
||||
/* find the name for the sap in question */
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) {
|
||||
while (x < (MAX_MTP_LINKS+1)) {
|
||||
if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) {
|
||||
break;
|
||||
}
|
||||
|
@ -271,7 +266,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
|||
|
||||
/* find the name for the sap in question */
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) {
|
||||
while (x < (MAX_MTP_LINKS+1)) {
|
||||
if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) {
|
||||
break;
|
||||
}
|
||||
|
@ -366,7 +361,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
|
|||
|
||||
/* find the name for the sap in question */
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) {
|
||||
while (x < (MAX_MTP_LINKS+1)) {
|
||||
if (g_ftdm_sngss7_data.cfg.mtp3Link[x].id == sta->hdr.elmId.elmntInst1) {
|
||||
break;
|
||||
}
|
||||
|
@ -402,7 +397,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
|
|||
break;
|
||||
/**********************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s(%d) : %s(%d)\n",
|
||||
ftdm_log(FTDM_LOG_DEBUG,"[MTP3]%s %s(%d) : %s(%d)\n",
|
||||
buf,
|
||||
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
|
||||
sta->t.usta.alarm.event,
|
||||
|
@ -421,7 +416,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
|
|||
break;
|
||||
/**************************************************************************/
|
||||
case (STLNKSET):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP3][LNKSET:%d] %s : %s\n",
|
||||
ftdm_log(FTDM_LOG_DEBUG,"[MTP3][LNKSET:%d] %s : %s\n",
|
||||
sta->hdr.elmId.elmntInst1,
|
||||
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause));
|
||||
|
|
|
@ -109,7 +109,15 @@ ftdm_state_map_t sangoma_ss7_state_map = {
|
|||
{FTDM_CHANNEL_STATE_RING, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
|
||||
FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
|
||||
FTDM_CHANNEL_STATE_PROGRESS, FTDM_END}
|
||||
FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_RINGING, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
|
||||
FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
|
||||
FTDM_CHANNEL_STATE_UP, FTDM_END},
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
|
@ -609,6 +617,8 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
break;
|
||||
/**************************************************************************/
|
||||
/* We handle RING indication the same way we would indicate PROGRESS */
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
|
||||
if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
|
||||
|
@ -626,8 +636,11 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
} else {
|
||||
/* inbound call so we need to send out ACM */
|
||||
if (!sngss7_test_ckt_flag(sngss7_info, FLAG_SENT_ACM)) {
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_SENT_ACM);
|
||||
ft_to_sngss7_acm(ftdmchan);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
/**************************************************************************/
|
||||
|
@ -877,6 +890,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
/* clear any call related flags */
|
||||
sngss7_clear_ckt_flag (sngss7_info, FLAG_REMOTE_REL);
|
||||
sngss7_clear_ckt_flag (sngss7_info, FLAG_LOCAL_REL);
|
||||
sngss7_clear_ckt_flag (sngss7_info, FLAG_SENT_ACM);
|
||||
|
||||
|
||||
if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OPEN)) {
|
||||
|
@ -1049,18 +1063,20 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
}
|
||||
} /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) */
|
||||
|
||||
if ((sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) &&
|
||||
(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) {
|
||||
if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) {
|
||||
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Processing PAUSE%s\n", "");
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
/* bring the sig status down */
|
||||
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN);
|
||||
}
|
||||
} /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) { */
|
||||
|
||||
/**********************************************************************/
|
||||
if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX) &&
|
||||
if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_BLOCK_RX) &&
|
||||
!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN)) {
|
||||
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_RX flag %s\n", "");
|
||||
|
||||
/* bring the sig status down */
|
||||
|
@ -1076,8 +1092,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
goto suspend_goto_last;
|
||||
}
|
||||
|
||||
if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX) &&
|
||||
!sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX_DN)){
|
||||
if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX)){
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_UNBLK_RX flag %s\n", "");
|
||||
|
||||
/* clear the block flags */
|
||||
|
@ -1100,6 +1115,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
/**********************************************************************/
|
||||
if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX) &&
|
||||
!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX_DN)) {
|
||||
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_TX flag %s\n", "");
|
||||
|
||||
/* bring the sig status down */
|
||||
|
@ -1115,8 +1131,8 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
goto suspend_goto_last;
|
||||
}
|
||||
|
||||
if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX) &&
|
||||
!sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX_DN)){
|
||||
if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX)) {
|
||||
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_UNBLK_TX flag %s\n", "");
|
||||
|
||||
/* clear the block flags */
|
||||
|
@ -1139,6 +1155,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
/**********************************************************************/
|
||||
if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX) &&
|
||||
!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX_DN)) {
|
||||
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_LC_BLOCK_RX flag %s\n", "");
|
||||
|
||||
/* send a BLA */
|
||||
|
@ -1151,8 +1168,8 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
goto suspend_goto_last;
|
||||
}
|
||||
|
||||
if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX) &&
|
||||
!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX_DN)) {
|
||||
if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_LC_UNBLK_RX)) {
|
||||
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_LC_UNBLK_RX flag %s\n", "");
|
||||
|
||||
/* clear the block flags */
|
||||
|
@ -1172,6 +1189,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
/**********************************************************************/
|
||||
if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_UCIC_BLOCK) &&
|
||||
!sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_UCIC_BLOCK_DN)) {
|
||||
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_BLOCK flag %s\n", "");
|
||||
|
||||
/* bring the channel signaling status to down */
|
||||
|
@ -1192,8 +1210,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
goto suspend_goto_last;
|
||||
}
|
||||
|
||||
if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK) &&
|
||||
!sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK_DN)) {
|
||||
if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_UNBLK flag %s\n", "");
|
||||
|
||||
/* remove the UCIC block flag */
|
||||
|
@ -1210,7 +1227,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
goto suspend_goto_restart;
|
||||
}
|
||||
|
||||
SS7_ERROR_CHAN(ftdmchan,"No block flag processed!%s\n", "");
|
||||
SS7_DEBUG_CHAN(ftdmchan,"No block flag processed!%s\n", "");
|
||||
|
||||
suspend_goto_last:
|
||||
state_flag = 0;
|
||||
|
@ -1370,6 +1387,9 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span)
|
|||
ftdm_clear_flag (span, FTDM_SPAN_STOP_THREAD);
|
||||
ftdm_clear_flag (span, FTDM_SPAN_IN_THREAD);
|
||||
|
||||
/* check the status of all isup interfaces */
|
||||
check_status_of_all_isup_intf();
|
||||
|
||||
/* throw the channels in pause */
|
||||
for (x = 1; x < (span->chan_count + 1); x++) {
|
||||
/* extract the channel structure and sngss7 channel data */
|
||||
|
@ -1632,7 +1652,7 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_ss7_unload)
|
|||
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY)) {
|
||||
/* go through all the relays channels and configure it */
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.relay[x].id != 0) {
|
||||
while (x < (MAX_RELAY_CHANNELS)) {
|
||||
/* check if this relay channel has been configured already */
|
||||
if ((g_ftdm_sngss7_data.cfg.relay[x].flags & SNGSS7_CONFIGURED)) {
|
||||
|
||||
|
@ -1648,7 +1668,7 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_ss7_unload)
|
|||
g_ftdm_sngss7_data.cfg.relay[x].flags &= !SNGSS7_CONFIGURED;
|
||||
} /* if !SNGSS7_CONFIGURED */
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.relay[x].id != 0) */
|
||||
} /* while (x < (MAX_RELAY_CHANNELS)) */
|
||||
|
||||
ftmod_ss7_shutdown_relay();
|
||||
sng_isup_free_relay();
|
||||
|
|
|
@ -316,8 +316,11 @@ typedef struct sng_isup_ckt {
|
|||
uint32_t typeCntrl;
|
||||
uint32_t ssf;
|
||||
uint32_t switchType;
|
||||
|
||||
uint32_t clg_nadi;
|
||||
uint32_t cld_nadi;
|
||||
uint8_t rdnis_nadi;
|
||||
|
||||
uint32_t min_digits;
|
||||
void *obj;
|
||||
uint16_t t3;
|
||||
|
@ -503,6 +506,7 @@ typedef enum {
|
|||
FLAG_GLARE = (1 << 13),
|
||||
FLAG_INFID_RESUME = (1 << 14),
|
||||
FLAG_INFID_PAUSED = (1 << 15),
|
||||
FLAG_SENT_ACM = (1 << 16),
|
||||
FLAG_RELAY_DOWN = (1 << 30),
|
||||
FLAG_CKT_RECONFIG = (1 << 31)
|
||||
} sng_ckt_flag_t;
|
||||
|
@ -524,6 +528,7 @@ typedef enum {
|
|||
"GLARE", \
|
||||
"INF_RESUME", \
|
||||
"INF_PAUSED", \
|
||||
"TX_ACM_SENT" \
|
||||
"RELAY_DOWN", \
|
||||
"CKT_RECONFIG"
|
||||
FTDM_STR2ENUM_P(ftmod_ss7_ckt_state2flag, ftmod_ss7_ckt_flag2str, sng_ckt_flag_t)
|
||||
|
@ -784,8 +789,12 @@ uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum
|
|||
uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
|
||||
uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
|
||||
uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
|
||||
uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
|
||||
uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
|
||||
ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum);
|
||||
|
||||
|
||||
ftdm_status_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
|
||||
ftdm_status_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
|
||||
ftdm_status_t copy_tknStr_to_sngss7(char* str, TknStr *tknStr, TknU8 *oddEven);
|
||||
|
||||
int check_for_state_change(ftdm_channel_t *ftdmchan);
|
||||
int check_cics_in_range(sngss7_chan_data_t *sngss7_info);
|
||||
|
|
|
@ -183,7 +183,6 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
|||
copy_cdPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cdPtyNum);
|
||||
|
||||
/* copy down the calling number information */
|
||||
|
||||
copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum);
|
||||
|
||||
/* check if the user would like a custom NADI value for the calling Pty Num */
|
||||
|
@ -244,6 +243,8 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
|||
} /* if (subAddrIE[0] != '0') */
|
||||
}
|
||||
|
||||
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
|
||||
|
||||
/* check if the user would like us to send a cld_sub-address */
|
||||
cld_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_cld_subaddr");
|
||||
if ((cld_subAddr != NULL) && (*cld_subAddr)) {
|
||||
|
|
|
@ -43,13 +43,6 @@ uint32_t sngss7_id;
|
|||
/******************************************************************************/
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
|
||||
uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
|
||||
uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
|
||||
uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
|
||||
uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
|
||||
uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
|
||||
|
||||
int check_for_state_change(ftdm_channel_t *ftdmchan);
|
||||
int check_cics_in_range(sngss7_chan_data_t *sngss7_info);
|
||||
int check_for_reset(sngss7_chan_data_t *sngss7_info);
|
||||
|
@ -139,6 +132,7 @@ uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum)
|
|||
* it finds the \0...since tmp is on the stack it will start going through the
|
||||
* possibly causing corruption. Hard code a \0 to prevent this
|
||||
*/
|
||||
|
||||
tmp[1] = '\0';
|
||||
k = 0;
|
||||
j = 0;
|
||||
|
@ -334,8 +328,68 @@ uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
|
||||
|
||||
ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum)
|
||||
{
|
||||
const char* val = NULL;
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
uint8_t len = strlen(caller_data->rdnis.digits);
|
||||
if (!len) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Redirecting Number %s\n", caller_data->rdnis.digits);
|
||||
|
||||
redirgNum->eh.pres = PRSNT_NODEF;
|
||||
|
||||
/* Nature of address indicator */
|
||||
redirgNum->natAddr.pres = PRSNT_NODEF;
|
||||
|
||||
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_nadi");
|
||||
if (!ftdm_strlen_zero(val)) {
|
||||
redirgNum->natAddr.val = atoi(val);
|
||||
} else {
|
||||
redirgNum->natAddr.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].rdnis_nadi;
|
||||
}
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Redirecting Number NADI:%d\n", redirgNum->natAddr.val);
|
||||
|
||||
/* Screening indicator */
|
||||
redirgNum->scrInd.pres = PRSNT_NODEF;
|
||||
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_screen_ind");
|
||||
if (!ftdm_strlen_zero(val)) {
|
||||
redirgNum->scrInd.val = atoi(val);
|
||||
} else {
|
||||
redirgNum->scrInd.val = FTDM_SCREENING_VERIFIED_PASSED;
|
||||
}
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Redirecting Number Screening Ind:%d\n", redirgNum->scrInd.val);
|
||||
|
||||
/* Address presentation restricted ind */
|
||||
redirgNum->presRest.pres = PRSNT_NODEF;
|
||||
|
||||
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_pres_ind");
|
||||
if (!ftdm_strlen_zero(val)) {
|
||||
redirgNum->presRest.val = atoi(val);
|
||||
} else {
|
||||
redirgNum->presRest.val = FTDM_PRES_ALLOWED;
|
||||
}
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Redirecting Number Address Presentation Restricted Ind:%d\n", redirgNum->presRest.val);
|
||||
|
||||
/* Numbering plan */
|
||||
redirgNum->numPlan.pres = PRSNT_NODEF;
|
||||
|
||||
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_plan");
|
||||
if (!ftdm_strlen_zero(val)) {
|
||||
redirgNum->numPlan.val = atoi(val);
|
||||
} else {
|
||||
redirgNum->numPlan.val = caller_data->rdnis.plan;
|
||||
}
|
||||
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Redirecting Number Numbering plan:%d\n", redirgNum->numPlan.val);
|
||||
|
||||
return copy_tknStr_to_sngss7(caller_data->rdnis.digits, &redirgNum->addrSig, &redirgNum->oddEven);
|
||||
}
|
||||
|
||||
ftdm_status_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t j;
|
||||
|
@ -362,14 +416,14 @@ uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
|
|||
|
||||
} else {
|
||||
SS7_ERROR("Asked to copy tknStr that is not present!\n");
|
||||
return 1;
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
|
||||
ftdm_status_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
|
||||
{
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
@ -382,7 +436,7 @@ uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
|
|||
/* confirm that we found an acceptable length */
|
||||
if ( j > 25 ) {
|
||||
SS7_ERROR("string length exceeds maxium value...aborting append!\n");
|
||||
return 1;
|
||||
return FTDM_FAIL;
|
||||
} /* if ( j > 25 ) */
|
||||
|
||||
/* copy in digits */
|
||||
|
@ -405,12 +459,100 @@ uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
|
|||
} /* if ((oddEven.pres == 1) && (oddEven.val == 1)) */
|
||||
} else {
|
||||
SS7_ERROR("Asked to copy tknStr that is not present!\n");
|
||||
return 1;
|
||||
return FTDM_FAIL;
|
||||
} /* if (str.pres == 1) */
|
||||
|
||||
return 0;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ftdm_status_t copy_tknStr_to_sngss7(char* val, TknStr *tknStr, TknU8 *oddEven)
|
||||
{
|
||||
char tmp[2];
|
||||
int k = 0;
|
||||
int j = 0;
|
||||
uint8_t flag = 0;
|
||||
uint8_t odd = 0;
|
||||
|
||||
uint8_t lower = 0x0;
|
||||
uint8_t upper = 0x0;
|
||||
|
||||
tknStr->pres = PRSNT_NODEF;
|
||||
|
||||
/* atoi will search through memory starting from the pointer it is given until
|
||||
* it finds the \0...since tmp is on the stack it will start going through the
|
||||
* possibly causing corruption. Hard code a \0 to prevent this
|
||||
*/
|
||||
tmp[1] = '\0';
|
||||
|
||||
while (1) {
|
||||
/* grab a digit from the ftdm digits */
|
||||
tmp[0] = val[k];
|
||||
|
||||
/* check if the digit is a number and that is not null */
|
||||
while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) {
|
||||
SS7_INFO("Dropping invalid digit: %c\n", tmp[0]);
|
||||
/* move on to the next value */
|
||||
k++;
|
||||
tmp[0] = val[k];
|
||||
} /* while(!(isdigit(tmp))) */
|
||||
|
||||
/* check if tmp is null or a digit */
|
||||
if (tmp[0] != '\0') {
|
||||
/* push it into the lower nibble */
|
||||
lower = strtol(&tmp[0], (char **)NULL, 16);
|
||||
/* move to the next digit */
|
||||
k++;
|
||||
/* grab a digit from the ftdm digits */
|
||||
tmp[0] = val[k];
|
||||
|
||||
/* check if the digit is a number and that is not null */
|
||||
while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) {
|
||||
SS7_INFO("Dropping invalid digit: %c\n", tmp[0]);
|
||||
k++;
|
||||
tmp[0] = val[k];
|
||||
} /* while(!(isdigit(tmp))) */
|
||||
|
||||
/* check if tmp is null or a digit */
|
||||
if (tmp[0] != '\0') {
|
||||
/* push the digit into the upper nibble */
|
||||
upper = (strtol(&tmp[0], (char **)NULL, 16)) << 4;
|
||||
} else {
|
||||
/* there is no upper ... fill in 0 */
|
||||
upper = 0x0;
|
||||
/* throw the odd flag */
|
||||
odd = 1;
|
||||
/* throw the end flag */
|
||||
flag = 1;
|
||||
} /* if (tmp != '\0') */
|
||||
} else {
|
||||
/* keep the odd flag down */
|
||||
odd = 0;
|
||||
/* break right away since we don't need to write the digits */
|
||||
break;
|
||||
}
|
||||
|
||||
/* push the digits into the trillium structure */
|
||||
tknStr->val[j] = upper | lower;
|
||||
|
||||
/* increment the trillium pointer */
|
||||
j++;
|
||||
|
||||
/* if the flag is up we're through all the digits */
|
||||
if (flag) break;
|
||||
|
||||
/* move to the next digit */
|
||||
k++;
|
||||
} /* while(1) */
|
||||
|
||||
tknStr->len = j;
|
||||
oddEven->pres = PRSNT_NODEF;
|
||||
oddEven->val = odd;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
int check_for_state_change(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
|
@ -1319,7 +1461,7 @@ ftdm_status_t check_status_of_all_isup_intf(void)
|
|||
|
||||
/* go through all the isupIntfs and ask the stack to give their current state */
|
||||
x = 1;
|
||||
for (x = 1; x < (MAX_ISUP_INFS + 1); x++) {
|
||||
for (x = 1; x < (MAX_ISUP_INFS); x++) {
|
||||
/**************************************************************************/
|
||||
|
||||
if (g_ftdm_sngss7_data.cfg.isupIntf[x].id == 0) continue;
|
||||
|
@ -1376,7 +1518,7 @@ ftdm_status_t check_status_of_all_isup_intf(void)
|
|||
} /* switch (status) */
|
||||
|
||||
/**************************************************************************/
|
||||
} /* for (x = 1; x < MAX_ISUP_INFS + 1); i++) */
|
||||
} /* for (x = 1; x < MAX_ISUP_INFS); i++) */
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -122,6 +122,7 @@ typedef struct sng_ccSpan
|
|||
uint32_t ssf;
|
||||
uint32_t clg_nadi;
|
||||
uint32_t cld_nadi;
|
||||
uint32_t rdnis_nadi;
|
||||
uint32_t min_digits;
|
||||
uint32_t t3;
|
||||
uint32_t t12;
|
||||
|
@ -1215,7 +1216,7 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset)
|
|||
|
||||
/* go through all the mtp3 links and fill in the apc */
|
||||
i = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.mtp3Link[i].id != 0) {
|
||||
while (i < (MAX_MTP_LINKS)) {
|
||||
if (g_ftdm_sngss7_data.cfg.mtp3Link[i].linkSetId == mtpLinkSet.id) {
|
||||
g_ftdm_sngss7_data.cfg.mtp3Link[i].apc = mtpLinkSet.apc;
|
||||
}
|
||||
|
@ -1757,7 +1758,7 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
|
|||
/**************************************************************************/
|
||||
/* go through all the links and check if they belong to this linkset*/
|
||||
i = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.mtp3Link[i].id != 0) {
|
||||
while (i < (MAX_MTP_LINKS)) {
|
||||
/* check if this link is in the linkset */
|
||||
if (g_ftdm_sngss7_data.cfg.mtp3Link[i].linkSetId == lnkSet->lsId) {
|
||||
/* fill in the spc */
|
||||
|
@ -1841,6 +1842,7 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
|
|||
int num_parms = cc_span->n_parameters;
|
||||
int flag_clg_nadi = 0;
|
||||
int flag_cld_nadi = 0;
|
||||
int flag_rdnis_nadi = 0;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
|
@ -1891,28 +1893,6 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
|
|||
SS7_DEBUG("Found an ccSpan typeCntrl = %s\n", sng_cic_cntrl_type_map[ret].sng_type);
|
||||
}
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "ssf")) {
|
||||
/**********************************************************************/
|
||||
ret = find_ssf_type_in_map(parm->val);
|
||||
if (ret == -1) {
|
||||
SS7_ERROR("Found an invalid ccSpan ssf = %s\n", parm->var);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
sng_ccSpan.ssf = sng_ssf_type_map[ret].tril_type;
|
||||
SS7_DEBUG("Found an ccSpan ssf = %s\n", sng_ssf_type_map[ret].sng_type);
|
||||
}
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "switchType")) {
|
||||
/**********************************************************************/
|
||||
ret = find_switch_type_in_map(parm->val);
|
||||
if (ret == -1) {
|
||||
SS7_ERROR("Found an invalid ccSpan switchType = %s\n", parm->var);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
sng_ccSpan.switchType = sng_switch_type_map[ret].tril_isup_type;
|
||||
SS7_DEBUG("Found an ccSpan switchType = %s\n", sng_switch_type_map[ret].sng_type);
|
||||
}
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "cicbase")) {
|
||||
/**********************************************************************/
|
||||
sng_ccSpan.cicbase = atoi(parm->val);
|
||||
|
@ -1934,16 +1914,17 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
|
|||
flag_clg_nadi = 1;
|
||||
sng_ccSpan.clg_nadi = atoi(parm->val);
|
||||
SS7_DEBUG("Found default CLG_NADI parm->value = %d\n", sng_ccSpan.clg_nadi);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "cld_nadi")) {
|
||||
/**********************************************************************/
|
||||
/* throw the flag so that we know we got this optional parameter */
|
||||
flag_cld_nadi = 1;
|
||||
sng_ccSpan.cld_nadi = atoi(parm->val);
|
||||
SS7_DEBUG("Found default CLD_NADI parm->value = %d\n", sng_ccSpan.cld_nadi);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "rdnis_nadi")) {
|
||||
/* throw the flag so that we know we got this optional parameter */
|
||||
flag_rdnis_nadi = 1;
|
||||
sng_ccSpan.rdnis_nadi = atoi(parm->val);
|
||||
SS7_DEBUG("Found default RDNIS_NADI parm->value = %d\n", sng_ccSpan.rdnis_nadi);
|
||||
} else if (!strcasecmp(parm->var, "obci_bita")) {
|
||||
/**********************************************************************/
|
||||
if (*parm->val == '1') {
|
||||
sngss7_set_options(&sng_ccSpan, SNGSS7_ACM_OBCI_BITA);
|
||||
SS7_DEBUG("Found Optional Backwards Indicator: Bit A (early media) enable option\n");
|
||||
|
@ -2034,6 +2015,15 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
|
|||
sng_ccSpan.clg_nadi = 0x03;
|
||||
}
|
||||
|
||||
if (!flag_rdnis_nadi) {
|
||||
/* default the nadi value to national */
|
||||
sng_ccSpan.rdnis_nadi = 0x03;
|
||||
}
|
||||
|
||||
/* pull up the SSF and Switchtype from the isup interface */
|
||||
sng_ccSpan.ssf = g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf].ssf;
|
||||
sng_ccSpan.switchType = g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf].switchType;
|
||||
|
||||
/* add this span to our global listing */
|
||||
ftmod_ss7_fill_in_ccSpan(&sng_ccSpan);
|
||||
|
||||
|
@ -2461,7 +2451,7 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i
|
|||
{
|
||||
int i = 1;
|
||||
|
||||
while (g_ftdm_sngss7_data.cfg.mtpRoute[i].id != 0) {
|
||||
while (i < (MAX_MTP_ROUTES)) {
|
||||
if (g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc == spc) {
|
||||
/* we have a match so break out of this loop */
|
||||
break;
|
||||
|
@ -2471,6 +2461,16 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i
|
|||
}
|
||||
|
||||
if (g_ftdm_sngss7_data.cfg.mtpRoute[i].id == 0) {
|
||||
/* this is a new route...find the first free spot */
|
||||
i = 1;
|
||||
while (i < (MAX_MTP_ROUTES)) {
|
||||
if (g_ftdm_sngss7_data.cfg.mtpRoute[i].id == 0) {
|
||||
/* we have a match so break out of this loop */
|
||||
break;
|
||||
}
|
||||
/* move on to the next one */
|
||||
i++;
|
||||
}
|
||||
g_ftdm_sngss7_data.cfg.mtpRoute[i].id = i;
|
||||
SS7_DEBUG("found new mtp3 self route\n");
|
||||
} else {
|
||||
|
@ -2909,6 +2909,7 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
|
|||
g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = ccSpan->ssf;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].cld_nadi = ccSpan->cld_nadi;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].clg_nadi = ccSpan->clg_nadi;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].rdnis_nadi = ccSpan->rdnis_nadi;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].options = ccSpan->options;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].switchType = ccSpan->switchType;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].min_digits = ccSpan->min_digits;
|
||||
|
|
|
@ -321,7 +321,7 @@ static char *my_strdup (const char *s)
|
|||
TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cmd)
|
||||
{
|
||||
char *data = NULL, *cur = NULL, *end = NULL;
|
||||
int var = 0, LOOPING = 0;
|
||||
int LOOPING = 0;
|
||||
|
||||
if (!cmd) {
|
||||
return -1;
|
||||
|
@ -335,7 +335,6 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm
|
|||
cur = data;
|
||||
|
||||
while (*cur) {
|
||||
var = 0;
|
||||
if (*cur == ' ' || *cur == '\r' || *cur == '\n') {
|
||||
cur++;
|
||||
continue;
|
||||
|
@ -346,7 +345,6 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm
|
|||
}
|
||||
|
||||
if (*(cur + 1) == '=') {
|
||||
var = 1;
|
||||
switch(*cur) {
|
||||
case 'c':
|
||||
ts->channels = atoi(cur + 2);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Tue Mar 22 15:01:49 CDT 2011
|
||||
Wed Apr 27 11:49:37 CDT 2011
|
||||
|
|
|
@ -182,7 +182,7 @@ int time_d(char const **ss,
|
|||
issize_t msg_date_d(char const **ss, msg_time_t *date)
|
||||
{
|
||||
char const *s = *ss;
|
||||
char const *wkday;
|
||||
//char const *wkday;
|
||||
char const *tz;
|
||||
unsigned long day, year, hour, min, sec;
|
||||
int mon;
|
||||
|
@ -190,7 +190,8 @@ issize_t msg_date_d(char const **ss, msg_time_t *date)
|
|||
if (!IS_TOKEN(*s) || !date)
|
||||
return -1;
|
||||
|
||||
wkday = s; skip_token(&s); if (*s == ',') s++;
|
||||
//wkday = s;
|
||||
skip_token(&s); if (*s == ',') s++;
|
||||
while (IS_LWS(*s)) s++;
|
||||
|
||||
if (is_digit(*s)) {
|
||||
|
|
|
@ -550,7 +550,7 @@ int nea_server_shutdown(nea_server_t *nes,
|
|||
int retry_after)
|
||||
{
|
||||
nea_sub_t *s;
|
||||
int status = 200;
|
||||
// int status = 200;
|
||||
int in_callback;
|
||||
|
||||
if (nes == NULL)
|
||||
|
@ -576,8 +576,8 @@ int nea_server_shutdown(nea_server_t *nes,
|
|||
TAG_IF(!retry_after, NEATAG_REASON("deactivated")),
|
||||
TAG_IF(retry_after, NEATAG_RETRY_AFTER(retry_after)),
|
||||
TAG_END());
|
||||
else
|
||||
status = 180;
|
||||
//else
|
||||
//status = 180;
|
||||
}
|
||||
|
||||
nes->nes_in_callback = in_callback;
|
||||
|
|
|
@ -2307,7 +2307,7 @@ int agent_init_via(nta_agent_t *self, tport_t *primaries, int use_maddr)
|
|||
|
||||
/* Set via fields for the tports */
|
||||
for (tp = primaries; tp; tp = tport_next(tp)) {
|
||||
int maddr, first_via;
|
||||
int maddr;
|
||||
tp_name_t tpn[1];
|
||||
char const *comp = NULL;
|
||||
|
||||
|
@ -2339,8 +2339,6 @@ int agent_init_via(nta_agent_t *self, tport_t *primaries, int use_maddr)
|
|||
|
||||
if (tport_has_tls(tp)) self->sa_tport_tls = 1;
|
||||
|
||||
first_via = 1;
|
||||
|
||||
ai = tport_get_address(tp);
|
||||
|
||||
for (; ai; ai = ai->ai_next) {
|
||||
|
|
|
@ -1879,14 +1879,14 @@ int nua_registration_process_request(nua_registration_t *list,
|
|||
nta_incoming_t *irq,
|
||||
sip_t const *sip)
|
||||
{
|
||||
sip_call_id_t *i;
|
||||
//sip_call_id_t *i;
|
||||
nua_registration_t *nr;
|
||||
|
||||
if (!outbound_targeted_request(sip))
|
||||
return 0;
|
||||
|
||||
/* Process by outbound... */
|
||||
i = sip->sip_call_id;
|
||||
//i = sip->sip_call_id;
|
||||
|
||||
for (nr = list; nr; nr = nr->nr_next) {
|
||||
outbound_t *ob = nr->nr_ob;
|
||||
|
|
|
@ -1743,7 +1743,7 @@ static int nua_prack_client_request(nua_client_request_t *cr,
|
|||
nua_client_request_t *cri;
|
||||
int offer_sent = 0, answer_sent = 0, retval;
|
||||
int status = 0; char const *phrase = "PRACK Sent";
|
||||
uint32_t rseq = 0;
|
||||
//uint32_t rseq = 0;
|
||||
|
||||
if (du == NULL) /* Call terminated */
|
||||
return nua_client_return(cr, SIP_481_NO_TRANSACTION, msg);
|
||||
|
@ -1754,8 +1754,8 @@ static int nua_prack_client_request(nua_client_request_t *cr,
|
|||
|
||||
cri = du->du_cr;
|
||||
|
||||
if (sip->sip_rack)
|
||||
rseq = sip->sip_rack->ra_response;
|
||||
// if (sip->sip_rack)
|
||||
// rseq = sip->sip_rack->ra_response;
|
||||
|
||||
if (cri->cr_offer_recv && !cri->cr_answer_sent) {
|
||||
if (nh->nh_soa == NULL)
|
||||
|
|
|
@ -1883,12 +1883,11 @@ static char *next(char **message, const char *sep, const char *strip)
|
|||
|
||||
static int parsing_error(sdp_parser_t *p, char const *fmt, ...)
|
||||
{
|
||||
int n;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
memset(p->pr_error, 0, sizeof(p->pr_error));
|
||||
n = vsnprintf(p->pr_error, sizeof(p->pr_error), fmt, ap);
|
||||
vsnprintf(p->pr_error, sizeof(p->pr_error), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
p->pr_ok = 0;
|
||||
|
|
|
@ -685,9 +685,8 @@ static void printing_error(sdp_printer_t *p, const char *fmt, ...)
|
|||
va_list ap;
|
||||
|
||||
if (p->pr_ok) {
|
||||
int n;
|
||||
va_start(ap, fmt);
|
||||
n = vsnprintf(p->pr_buffer, p->pr_bsiz, fmt, ap);
|
||||
vsnprintf(p->pr_buffer, p->pr_bsiz, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
|
|
@ -1010,7 +1010,6 @@ int soa_sdp_mode_set(sdp_session_t const *user,
|
|||
int retval = 0, i, j;
|
||||
int hold_all;
|
||||
int inactive_all;
|
||||
int inactive = 0;
|
||||
char const *hold_media = NULL;
|
||||
sdp_mode_t send_mode, recv_mode;
|
||||
|
||||
|
@ -1029,7 +1028,6 @@ int soa_sdp_mode_set(sdp_session_t const *user,
|
|||
|
||||
for (sm = session->sdp_media; sm; sm = sm->m_next, rm = rm_next, i++) {
|
||||
rm_next = rm ? rm->m_next : NULL;
|
||||
inactive = 0;
|
||||
|
||||
if (sm->m_rejected)
|
||||
continue;
|
||||
|
|
|
@ -3636,6 +3636,10 @@ sres_decode_msg(sres_resolver_t *res,
|
|||
m_get_domain(name, sizeof(name), m, 0); /* Query domain */
|
||||
qtype = m_get_uint16(m); /* Query type */
|
||||
qclass = m_get_uint16(m); /* Query class */
|
||||
if (qtype && qclass) {
|
||||
/* XXX: never mind these useless check, this is done to make compiler happy about unused value */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (m->m_error) {
|
||||
|
|
|
@ -673,12 +673,12 @@ static stun_request_t *stun_request_create(stun_discovery_t *sd)
|
|||
|
||||
void stun_request_destroy(stun_request_t *req)
|
||||
{
|
||||
stun_handle_t *sh;
|
||||
//stun_handle_t *sh;
|
||||
assert(req);
|
||||
|
||||
enter;
|
||||
|
||||
sh = req->sr_handle;
|
||||
//sh = req->sr_handle;
|
||||
|
||||
if (x_is_inserted(req, sr))
|
||||
x_remove(req, sr);
|
||||
|
@ -1140,14 +1140,14 @@ static stun_discovery_t *stun_discovery_create(stun_handle_t *sh,
|
|||
|
||||
static int stun_discovery_destroy(stun_discovery_t *sd)
|
||||
{
|
||||
stun_handle_t *sh;
|
||||
//stun_handle_t *sh;
|
||||
|
||||
enter;
|
||||
|
||||
if (!sd)
|
||||
return errno = EFAULT, -1;
|
||||
|
||||
sh = sd->sd_handle;
|
||||
//sh = sd->sd_handle;
|
||||
|
||||
if (sd->sd_timer)
|
||||
su_timer_destroy(sd->sd_timer), sd->sd_timer = NULL;
|
||||
|
@ -1883,7 +1883,7 @@ static int process_test_lifetime(stun_request_t *req, stun_msg_t *binding_respon
|
|||
stun_discovery_t *sd = req->sr_discovery;
|
||||
stun_request_t *new;
|
||||
stun_handle_t *sh = req->sr_handle;
|
||||
su_localinfo_t *li;
|
||||
//su_localinfo_t *li;
|
||||
su_sockaddr_t *sa;
|
||||
su_timer_t *sockfdy_timer = NULL;
|
||||
su_socket_t sockfdy = sd->sd_socket2;
|
||||
|
@ -1954,7 +1954,7 @@ static int process_test_lifetime(stun_request_t *req, stun_msg_t *binding_respon
|
|||
/* Rock, we come from sockfdx */
|
||||
process_binding_request(req, binding_response);
|
||||
|
||||
li = &req->sr_localinfo;
|
||||
//li = &req->sr_localinfo;
|
||||
sa = req->sr_local_addr;
|
||||
stun_free_message(binding_response);
|
||||
|
||||
|
@ -1981,7 +1981,7 @@ static int process_test_lifetime(stun_request_t *req, stun_msg_t *binding_respon
|
|||
|
||||
static int action_bind(stun_request_t *req, stun_msg_t *binding_response)
|
||||
{
|
||||
su_localinfo_t *li = NULL;
|
||||
//su_localinfo_t *li = NULL;
|
||||
su_sockaddr_t *sa = NULL;
|
||||
stun_discovery_t *sd = req->sr_discovery;
|
||||
stun_handle_t *sh = req->sr_handle;
|
||||
|
@ -1992,7 +1992,7 @@ static int action_bind(stun_request_t *req, stun_msg_t *binding_response)
|
|||
|
||||
process_binding_request(req, binding_response);
|
||||
|
||||
li = &req->sr_localinfo;
|
||||
//li = &req->sr_localinfo;
|
||||
sa = req->sr_local_addr;
|
||||
|
||||
memcpy(sd->sd_addr_seen_outside, sa, sizeof(su_sockaddr_t));
|
||||
|
@ -3039,7 +3039,7 @@ int stun_process_request(su_socket_t s, stun_msg_t *req,
|
|||
su_sockaddr_t mod_addr[1] = {{ 0 }}, src_addr[1] = {{ 0 }}, chg_addr[1] = {{ 0 }};
|
||||
stun_attr_t *tmp, m_attr[1], s_attr[1], c_attr[1], **p;
|
||||
su_sockaddr_t to_addr;
|
||||
int c, i;
|
||||
int i;
|
||||
|
||||
tmp = stun_get_attr(req->stun_attr, RESPONSE_ADDRESS);
|
||||
|
||||
|
@ -3071,20 +3071,20 @@ int stun_process_request(su_socket_t s, stun_msg_t *req,
|
|||
/* SOURCE-ADDRESS depends on CHANGE_REQUEST */
|
||||
tmp = stun_get_attr(req->stun_attr, CHANGE_REQUEST);
|
||||
if (!tmp) {
|
||||
c = 0;
|
||||
//c = 0;
|
||||
}
|
||||
else {
|
||||
switch (((stun_attr_changerequest_t *) tmp->pattr)->value) {
|
||||
case STUN_CR_CHANGE_IP:
|
||||
c = 1;
|
||||
//c = 1;
|
||||
break;
|
||||
|
||||
case STUN_CR_CHANGE_PORT:
|
||||
c = 2;
|
||||
//c = 2;
|
||||
break;
|
||||
|
||||
case STUN_CR_CHANGE_IP | STUN_CR_CHANGE_PORT: /* bitwise or */
|
||||
c = 3;
|
||||
//c = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -163,7 +163,10 @@ stun_dns_lookup_t *stun_dns_lookup(stun_magic_t *magic,
|
|||
query = sres_query(self->stun_sres, priv_sres_cb, self,
|
||||
sres_type_srv,
|
||||
srvname);
|
||||
if (query) {
|
||||
/* TODO Just so compiler doesn't give error */
|
||||
}
|
||||
}
|
||||
else {
|
||||
su_free(NULL, self), self = NULL;
|
||||
}
|
||||
|
|
|
@ -429,13 +429,13 @@ void *sub_alloc(su_home_t *home,
|
|||
|
||||
if (sub == NULL || 3 * sub->sub_used > 2 * sub->sub_n) {
|
||||
/* Resize the hash table */
|
||||
size_t i, n, n2, used;
|
||||
size_t i, n, n2;
|
||||
su_block_t *b2;
|
||||
|
||||
if (sub)
|
||||
n = home->suh_blocks->sub_n, n2 = 4 * n + 3, used = sub->sub_used;
|
||||
n = home->suh_blocks->sub_n, n2 = 4 * n + 3; //, used = sub->sub_used;
|
||||
else
|
||||
n = 0, n2 = SUB_N, used = 0;
|
||||
n = 0, n2 = SUB_N; //, used = 0;
|
||||
|
||||
#if 0
|
||||
printf("su_alloc(home = %p): realloc block hash of size %d\n", home, n2);
|
||||
|
|
|
@ -194,7 +194,8 @@ static void li_sort(su_localinfo_t *i, su_localinfo_t **rresult);
|
|||
int su_getlocalinfo(su_localinfo_t const *hints,
|
||||
su_localinfo_t **return_localinfo)
|
||||
{
|
||||
int error = 0, ip4 = 0, ip6 = 0;
|
||||
int error = 0, ip4 = 0;
|
||||
int ip6 = 0;
|
||||
su_localinfo_t *result = NULL, **rr = &result;
|
||||
su_localinfo_t hh[1] = {{ 0 }};
|
||||
|
||||
|
@ -231,7 +232,11 @@ int su_getlocalinfo(su_localinfo_t const *hints,
|
|||
break;
|
||||
|
||||
case 0:
|
||||
ip6 = ip4 = 1;
|
||||
ip4 = 1;
|
||||
#if SU_HAVE_IN6
|
||||
ip6 = 1;
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -260,6 +265,9 @@ int su_getlocalinfo(su_localinfo_t const *hints,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (ip6) {
|
||||
/* Required to make compiler happy */
|
||||
}
|
||||
if (!result)
|
||||
error = ELI_NOADDRESS;
|
||||
|
||||
|
|
|
@ -1595,7 +1595,7 @@ int tport_bind_server(tport_master_t *mr,
|
|||
{
|
||||
char hostname[TPORT_HOSTPORTSIZE];
|
||||
char const *canon = NULL, *host, *service;
|
||||
int error = 0, not_supported, family = 0;
|
||||
int error = 0, family = 0;
|
||||
tport_primary_t *pri = NULL, **tbf;
|
||||
su_addrinfo_t *ai, *res = NULL;
|
||||
unsigned port, port0, port1, old;
|
||||
|
@ -1691,8 +1691,6 @@ int tport_bind_server(tport_master_t *mr,
|
|||
break;
|
||||
}
|
||||
|
||||
not_supported = 0;
|
||||
|
||||
if (port0 == 0 && port == 0) {
|
||||
port = port1 = ntohs(su->su_port);
|
||||
assert(public != tport_type_server || port != 0);
|
||||
|
|
|
@ -170,10 +170,10 @@ void tport_stun_bind_cb(tport_primary_t *pri,
|
|||
stun_action_t action,
|
||||
stun_state_t event)
|
||||
{
|
||||
tport_master_t *mr;
|
||||
//tport_master_t *mr;
|
||||
SU_DEBUG_3(("%s: %s\n", __func__, stun_str_state(event)));
|
||||
|
||||
mr = pri->pri_master;
|
||||
//mr = pri->pri_master;
|
||||
|
||||
if (event == stun_discovery_done) {
|
||||
tport_stun_bind_done(pri, sh, sd);
|
||||
|
|
|
@ -567,7 +567,7 @@ static
|
|||
int _url_d(url_t *url, char *s)
|
||||
{
|
||||
size_t n, p;
|
||||
char *s0, rest_c, *host, *user;
|
||||
char rest_c, *host, *user;
|
||||
int have_authority = 1;
|
||||
|
||||
memset(url, 0, sizeof(*url));
|
||||
|
@ -578,8 +578,6 @@ int _url_d(url_t *url, char *s)
|
|||
return 0;
|
||||
}
|
||||
|
||||
s0 = s;
|
||||
|
||||
n = strcspn(s, ":/?#");
|
||||
|
||||
if (n && s[n] == ':') {
|
||||
|
|
|
@ -165,10 +165,10 @@ SPAN_DECLARE(int) plc_fillin(plc_state_t *s, int16_t amp[], int len)
|
|||
float old_weight;
|
||||
float new_weight;
|
||||
float gain;
|
||||
int16_t *orig_amp;
|
||||
//int16_t *orig_amp;
|
||||
int orig_len;
|
||||
|
||||
orig_amp = amp;
|
||||
//orig_amp = amp;
|
||||
orig_len = len;
|
||||
if (s->missing_samples == 0)
|
||||
{
|
||||
|
|
|
@ -297,7 +297,7 @@ static inline char *strndup_lite(const char *s, size_t n)
|
|||
#define sqliteMalloc(x) zmalloc(x)//sqlite3Malloc(x,1)
|
||||
#define sqliteMallocRaw(x) malloc(x)//sqlite3MallocRaw(x,1)
|
||||
#define sqliteRealloc(x,y) realloc(x, y)//sqlite3Realloc(x,y)
|
||||
#define sqliteStrDup(x) strdup(x)//sqlite3StrDup(x)
|
||||
#define sqliteStrDup(x) (x?strdup(x):NULL)//sqlite3StrDup(x)
|
||||
#define sqliteStrNDup(x,y) strndup_lite(x,y) //sqlite3StrNDup(x,y)
|
||||
#define sqliteReallocOrFree(x,y) sqlite3ReallocOrFree(x,y)
|
||||
|
||||
|
|
|
@ -506,9 +506,9 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void
|
|||
i->diff_total += i->diff;
|
||||
|
||||
if ((i->period_packet_in_count > i->period_time)) {
|
||||
uint32_t avg;
|
||||
//uint32_t avg;
|
||||
|
||||
avg = i->diff_total / least1(i->period_packet_in_count);
|
||||
//avg = i->diff_total / least1(i->period_packet_in_count);
|
||||
|
||||
i->period_packet_in_count = 0;
|
||||
|
||||
|
@ -904,7 +904,7 @@ static void default_logger(const char *file, const char *func, int line, int lev
|
|||
ret = stfu_vasprintf(&data, fmt, ap);
|
||||
|
||||
if (ret != -1) {
|
||||
fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], file, line, func, data);
|
||||
fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], fp, line, func, data);
|
||||
free(data);
|
||||
}
|
||||
|
||||
|
|
|
@ -240,6 +240,7 @@ struct switch_runtime {
|
|||
uint32_t debug_level;
|
||||
uint32_t runlevel;
|
||||
uint32_t tipping_point;
|
||||
uint32_t microseconds_per_tick;
|
||||
int32_t timer_affinity;
|
||||
switch_profile_timer_t *profile_timer;
|
||||
double profile_time;
|
||||
|
@ -248,6 +249,7 @@ struct switch_runtime {
|
|||
int max_sql_buffer_len;
|
||||
switch_dbtype_t odbc_dbtype;
|
||||
char hostname[256];
|
||||
char *switchname;
|
||||
int multiple_registrations;
|
||||
uint32_t max_db_handles;
|
||||
uint32_t db_handle_timeout;
|
||||
|
|
|
@ -49,6 +49,7 @@ SWITCH_BEGIN_EXTERN_C struct switch_channel_timetable {
|
|||
switch_time_t hungup;
|
||||
switch_time_t transferred;
|
||||
switch_time_t resurrected;
|
||||
switch_time_t bridged;
|
||||
struct switch_channel_timetable *next;
|
||||
};
|
||||
|
||||
|
@ -597,7 +598,7 @@ SWITCH_DECLARE(int) switch_channel_test_app_flag_key(const char *app, switch_cha
|
|||
#define switch_channel_clear_app_flag(_c, _f) switch_channel_clear_app_flag_key(__FILE__, _c, _f)
|
||||
#define switch_channel_test_app_flag(_c, _f) switch_channel_test_app_flag_key(__FILE__, _c, _f)
|
||||
|
||||
|
||||
SWITCH_DECLARE(void) switch_channel_set_bridge_time(switch_channel_t *channel);
|
||||
SWITCH_DECLARE(void) switch_channel_set_hangup_time(switch_channel_t *channel);
|
||||
SWITCH_DECLARE(switch_call_direction_t) switch_channel_direction(switch_channel_t *channel);
|
||||
SWITCH_DECLARE(switch_core_session_t *) switch_channel_get_session(switch_channel_t *channel);
|
||||
|
|
|
@ -762,6 +762,7 @@ SWITCH_DECLARE(char *) switch_core_get_variable(_In_z_ const char *varname);
|
|||
SWITCH_DECLARE(char *) switch_core_get_variable_dup(_In_z_ const char *varname);
|
||||
SWITCH_DECLARE(char *) switch_core_get_variable_pdup(_In_z_ const char *varname, switch_memory_pool_t *pool);
|
||||
SWITCH_DECLARE(const char *) switch_core_get_hostname(void);
|
||||
SWITCH_DECLARE(const char *) switch_core_get_switchname(void);
|
||||
|
||||
/*!
|
||||
\brief Add a global variable to the core
|
||||
|
|
|
@ -285,7 +285,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_free_subclass_detailed(const char *
|
|||
SWITCH_DECLARE(switch_status_t) switch_event_serialize(switch_event_t *event, char **str, switch_bool_t encode);
|
||||
SWITCH_DECLARE(switch_status_t) switch_event_serialize_json(switch_event_t *event, char **str);
|
||||
SWITCH_DECLARE(switch_status_t) switch_event_create_json(switch_event_t **event, const char *json);
|
||||
SWITCH_DECLARE(switch_status_t) switch_event_create_brackets(char *data, char a, char b, char c, switch_event_t **event, char **new_data);
|
||||
SWITCH_DECLARE(switch_status_t) switch_event_create_brackets(char *data, char a, char b, char c, switch_event_t **event, char **new_data, switch_bool_t dup);
|
||||
|
||||
#ifndef SWIG
|
||||
/*!
|
||||
|
|
|
@ -239,20 +239,23 @@ SWITCH_DECLARE(switch_size_t) switch_fd_read_line(int fd, char *buf, switch_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_free(switch_frame_t **frame);
|
||||
SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str);
|
||||
|
||||
/*!
|
||||
\brief Evaluate the truthfullness of a string expression
|
||||
\param expr a string expression
|
||||
\return true or false
|
||||
*/
|
||||
#define switch_true(expr)\
|
||||
((expr && ( !strcasecmp(expr, "yes") ||\
|
||||
!strcasecmp(expr, "on") ||\
|
||||
!strcasecmp(expr, "true") ||\
|
||||
!strcasecmp(expr, "enabled") ||\
|
||||
!strcasecmp(expr, "active") ||\
|
||||
!strcasecmp(expr, "allow") ||\
|
||||
(switch_is_number(expr) && atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE)
|
||||
static inline int switch_true(const char *expr)
|
||||
{
|
||||
return ((expr && ( !strcasecmp(expr, "yes") ||
|
||||
!strcasecmp(expr, "on") ||
|
||||
!strcasecmp(expr, "true") ||
|
||||
!strcasecmp(expr, "enabled") ||
|
||||
!strcasecmp(expr, "active") ||
|
||||
!strcasecmp(expr, "allow") ||
|
||||
(switch_is_number(expr) && atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE);
|
||||
}
|
||||
|
||||
#define switch_true_buf(expr)\
|
||||
((( !strcasecmp(expr, "yes") ||\
|
||||
|
@ -268,14 +271,16 @@ SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame);
|
|||
\param expr a string expression
|
||||
\return true or false
|
||||
*/
|
||||
#define switch_false(expr)\
|
||||
((expr && ( !strcasecmp(expr, "no") ||\
|
||||
!strcasecmp(expr, "off") ||\
|
||||
!strcasecmp(expr, "false") ||\
|
||||
!strcasecmp(expr, "disabled") ||\
|
||||
!strcasecmp(expr, "inactive") ||\
|
||||
!strcasecmp(expr, "disallow") ||\
|
||||
(switch_is_number(expr) && !atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE)
|
||||
static inline int switch_false(const char *expr)
|
||||
{
|
||||
return ((expr && ( !strcasecmp(expr, "no") ||
|
||||
!strcasecmp(expr, "off") ||
|
||||
!strcasecmp(expr, "false") ||
|
||||
!strcasecmp(expr, "disabled") ||
|
||||
!strcasecmp(expr, "inactive") ||
|
||||
!strcasecmp(expr, "disallow") ||
|
||||
(switch_is_number(expr) && !atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE);
|
||||
}
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_resolve_host(const char *host, char *buf, size_t buflen);
|
||||
|
@ -500,6 +505,23 @@ static inline char *switch_clean_string(char *s)
|
|||
}
|
||||
|
||||
|
||||
static inline char *switch_clean_name_string(char *s)
|
||||
{
|
||||
char *p;
|
||||
for (p = s; p && *p; p++) {
|
||||
uint8_t x = (uint8_t) * p;
|
||||
if ((x < 32) || x == '\'' || x == '"' || x == '<' || x == '>' || x == '\\' || x == ':' || x == '@' || x == '/') {
|
||||
*p = ' ';
|
||||
}
|
||||
if ( (p == s) && (*p == ' ') ) {
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Free a pointer and set it to NULL unless it already is NULL
|
||||
|
@ -653,7 +675,7 @@ SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in);
|
|||
SWITCH_DECLARE(unsigned int) switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen);
|
||||
SWITCH_DECLARE(unsigned int) switch_separate_string_string(char *buf, char *delim, _Post_count_(return) char **array, unsigned int arraylen);
|
||||
|
||||
SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str);
|
||||
|
||||
SWITCH_DECLARE(char *) switch_strip_spaces(char *str, switch_bool_t dup);
|
||||
SWITCH_DECLARE(char *) switch_strip_whitespace(const char *str);
|
||||
SWITCH_DECLARE(char *) switch_strip_commas(char *in, char *out, switch_size_t len);
|
||||
|
|
|
@ -417,6 +417,8 @@ SWITCH_DECLARE(switch_xml_section_t) switch_xml_parse_section_string(_In_opt_z_
|
|||
|
||||
SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_xml_locate_language(switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_xml_t *language, switch_xml_t *phrases, switch_xml_t *macros, const char *str_language);
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
///\}
|
||||
#endif // _SWITCH_XML_H
|
||||
|
|
|
@ -479,7 +479,7 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
|
|||
double success = 0.0;
|
||||
double amp = 0.0;
|
||||
double s_rate;
|
||||
double e_rate;
|
||||
// double e_rate;
|
||||
double avg_a;
|
||||
double sine_len;
|
||||
uint32_t sine_len_i;
|
||||
|
@ -523,7 +523,7 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
|
|||
/*! Every once in a while we evaluate the desa2 and amplitude results */
|
||||
if(((pos + 1) % sine_len_i) == 0){
|
||||
s_rate = success / (error + success);
|
||||
e_rate = error / (error + success);
|
||||
// e_rate = error / (error + success);
|
||||
avg_a = amp / sine_len;
|
||||
|
||||
/*! Results out of these ranges are considered invalid */
|
||||
|
|
|
@ -0,0 +1,287 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="mod_callcenter"
|
||||
ProjectGUID="{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}"
|
||||
RootNamespace="mod_callcenter"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath=".\mod_callcenter.c"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -0,0 +1,131 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>mod_callcenter</ProjectName>
|
||||
<ProjectGuid>{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}</ProjectGuid>
|
||||
<RootNamespace>mod_callcenter</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_release.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_debug.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_release.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_debug.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="mod_callcenter.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\w32\Library\FreeSwitchCore.2010.vcxproj">
|
||||
<Project>{202d7a4e-760d-4d0e-afa1-d7459ced30ff}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -37,10 +37,13 @@
|
|||
#define CC_AGENT_TYPE_UUID_STANDBY "uuid-standby"
|
||||
#define CC_SQLITE_DB_NAME "callcenter"
|
||||
|
||||
/* TODO
|
||||
drop caller if no agent login
|
||||
dont allow new caller
|
||||
*/
|
||||
#ifdef WIN32
|
||||
#define MSWITCH_TIME_T_FMT "lld"
|
||||
#else
|
||||
#define MSWITCH_TIME_T_FMT SWITCH_TIME_T_FMT
|
||||
#endif
|
||||
|
||||
|
||||
/* Prototypes */
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_callcenter_shutdown);
|
||||
SWITCH_MODULE_RUNTIME_FUNCTION(mod_callcenter_runtime);
|
||||
|
@ -249,6 +252,16 @@ static char tiers_sql[] =
|
|||
|
||||
static switch_xml_config_int_options_t config_int_0_86400 = { SWITCH_TRUE, 0, SWITCH_TRUE, 86400 };
|
||||
|
||||
/* TODO This is temporary until we either move it to the core, or use it differently in the module */
|
||||
switch_time_t local_epoch_time_now(switch_time_t *t)
|
||||
{
|
||||
switch_time_t now = switch_micro_time_now() / 1000000; /* APR_USEC_PER_SEC */
|
||||
if (t) {
|
||||
*t = now;
|
||||
}
|
||||
return now;
|
||||
}
|
||||
|
||||
const char * cc_tier_state2str(cc_tier_state_t state)
|
||||
{
|
||||
uint8_t x;
|
||||
|
@ -656,8 +669,6 @@ static cc_queue_t *load_queue(const char *queue_name)
|
|||
cc_queue_t *queue = NULL;
|
||||
switch_xml_t x_queues, x_queue, cfg, xml;
|
||||
switch_event_t *event = NULL;
|
||||
switch_cache_db_handle_t *dbh = NULL;
|
||||
char *sql = NULL;
|
||||
|
||||
if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf);
|
||||
|
@ -700,30 +711,10 @@ static cc_queue_t *load_queue(const char *queue_name)
|
|||
queue->last_agent_exist = 0;
|
||||
queue->last_agent_exist_check = 0;
|
||||
|
||||
if (!(dbh = cc_get_db_handle())) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot open DB!\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch_cache_db_test_reactive(dbh, "select count(session_uuid) from members", "drop table members", members_sql);
|
||||
switch_cache_db_test_reactive(dbh, "select count(ready_time) from agents", NULL, "alter table agents add ready_time integer not null default 0;"
|
||||
"alter table agents add reject_delay_time integer not null default 0;"
|
||||
"alter table agents add busy_delay_time integer not null default 0;");
|
||||
switch_cache_db_test_reactive(dbh, "select count(no_answer_delay_time) from agents", NULL, "alter table agents add no_answer_delay_time integer not null default 0;");
|
||||
switch_cache_db_test_reactive(dbh, "select count(ready_time) from agents", "drop table agents", agents_sql);
|
||||
switch_cache_db_test_reactive(dbh, "select count(queue) from tiers", "drop table tiers" , tiers_sql);
|
||||
switch_mutex_init(&queue->mutex, SWITCH_MUTEX_NESTED, queue->pool);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Added queue %s\n", queue->name);
|
||||
switch_core_hash_insert(globals.queue_hash, queue->name, queue);
|
||||
|
||||
/* Reset a unclean shutdown */
|
||||
sql = switch_mprintf("UPDATE agents SET state = 'Waiting', uuid = '' WHERE system = 'single_box';"
|
||||
"UPDATE tiers SET state = 'Ready' WHERE agent IN (SELECT name FROM agents WHERE system = 'single_box');"
|
||||
"UPDATE members SET state = '%q', session_uuid = '' WHERE system = 'single_box';",
|
||||
cc_member_state2str(CC_MEMBER_STATE_ABANDONED));
|
||||
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
}
|
||||
|
||||
end:
|
||||
|
@ -925,13 +916,13 @@ cc_status_t cc_agent_update(const char *key, const char *value, const char *agen
|
|||
if (cc_agent_str2status(value) != CC_AGENT_STATUS_UNKNOWN) {
|
||||
/* Reset values on available only */
|
||||
if (cc_agent_str2status(value) == CC_AGENT_STATUS_AVAILABLE) {
|
||||
sql = switch_mprintf("UPDATE agents SET status = '%q', last_status_change = '%ld', talk_time = 0, calls_answered = 0, no_answer_count = 0"
|
||||
sql = switch_mprintf("UPDATE agents SET status = '%q', last_status_change = '%" MSWITCH_TIME_T_FMT "', talk_time = 0, calls_answered = 0, no_answer_count = 0"
|
||||
" WHERE name = '%q' AND NOT status = '%q'",
|
||||
value, (long) switch_epoch_time_now(NULL),
|
||||
value, local_epoch_time_now(NULL),
|
||||
agent, value);
|
||||
} else {
|
||||
sql = switch_mprintf("UPDATE agents SET status = '%q', last_status_change = '%ld' WHERE name = '%q'",
|
||||
value, (long) switch_epoch_time_now(NULL), agent);
|
||||
sql = switch_mprintf("UPDATE agents SET status = '%q', last_status_change = '%" MSWITCH_TIME_T_FMT "' WHERE name = '%q'",
|
||||
value, local_epoch_time_now(NULL), agent);
|
||||
}
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
|
@ -943,7 +934,7 @@ cc_status_t cc_agent_update(const char *key, const char *value, const char *agen
|
|||
cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
|
||||
switch_safe_free(sql);
|
||||
if (!switch_strlen_zero(res)) {
|
||||
switch_core_session_hupall_matching_var("cc_member_uuid", res, SWITCH_CAUSE_ORIGINATOR_CANCEL);
|
||||
switch_core_session_hupall_matching_var("cc_member_pre_answer_uuid", res, SWITCH_CAUSE_ORIGINATOR_CANCEL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -966,8 +957,8 @@ cc_status_t cc_agent_update(const char *key, const char *value, const char *agen
|
|||
if (cc_agent_str2state(value) != CC_AGENT_STATE_RECEIVING) {
|
||||
sql = switch_mprintf("UPDATE agents SET state = '%q' WHERE name = '%q'", value, agent);
|
||||
} else {
|
||||
sql = switch_mprintf("UPDATE agents SET state = '%q', last_offered_call = '%ld' WHERE name = '%q'",
|
||||
value, (long) switch_epoch_time_now(NULL), agent);
|
||||
sql = switch_mprintf("UPDATE agents SET state = '%q', last_offered_call = '%" MSWITCH_TIME_T_FMT "' WHERE name = '%q'",
|
||||
value, local_epoch_time_now(NULL), agent);
|
||||
}
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
|
@ -1262,11 +1253,15 @@ end:
|
|||
|
||||
static switch_status_t load_config(void)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
switch_xml_t cfg, xml, settings, param, x_queues, x_queue, x_agents, x_agent, x_tiers, x_tier;
|
||||
switch_cache_db_handle_t *dbh = NULL;
|
||||
char *sql = NULL;
|
||||
|
||||
if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf);
|
||||
return SWITCH_STATUS_TERM;
|
||||
status = SWITCH_STATUS_TERM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch_mutex_lock(globals.mutex);
|
||||
|
@ -1297,6 +1292,30 @@ static switch_status_t load_config(void)
|
|||
globals.dbname = strdup(CC_SQLITE_DB_NAME);
|
||||
}
|
||||
|
||||
/* Initialize database */
|
||||
if (!(dbh = cc_get_db_handle())) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot open DB!\n");
|
||||
status = SWITCH_STATUS_TERM;
|
||||
goto end;
|
||||
}
|
||||
switch_cache_db_test_reactive(dbh, "select count(session_uuid) from members", "drop table members", members_sql);
|
||||
switch_cache_db_test_reactive(dbh, "select count(ready_time) from agents", NULL, "alter table agents add ready_time integer not null default 0;"
|
||||
"alter table agents add reject_delay_time integer not null default 0;"
|
||||
"alter table agents add busy_delay_time integer not null default 0;");
|
||||
switch_cache_db_test_reactive(dbh, "select count(no_answer_delay_time) from agents", NULL, "alter table agents add no_answer_delay_time integer not null default 0;");
|
||||
switch_cache_db_test_reactive(dbh, "select count(ready_time) from agents", "drop table agents", agents_sql);
|
||||
switch_cache_db_test_reactive(dbh, "select count(queue) from tiers", "drop table tiers" , tiers_sql);
|
||||
|
||||
switch_cache_db_release_db_handle(&dbh);
|
||||
|
||||
/* Reset a unclean shutdown */
|
||||
sql = switch_mprintf("update agents set state = 'Waiting', uuid = '' where system = 'single_box';"
|
||||
"update tiers set state = 'Ready' where agent IN (select name from agents where system = 'single_box');"
|
||||
"update members set state = '%q', session_uuid = '' where system = 'single_box';",
|
||||
cc_member_state2str(CC_MEMBER_STATE_ABANDONED));
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
|
||||
/* Loading queue into memory struct */
|
||||
if ((x_queues = switch_xml_child(cfg, "queues"))) {
|
||||
for (x_queue = switch_xml_child(x_queues, "queue"); x_queue; x_queue = x_queue->next) {
|
||||
|
@ -1342,11 +1361,14 @@ static switch_status_t load_config(void)
|
|||
}
|
||||
}
|
||||
|
||||
end:
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
|
||||
if (xml) {
|
||||
switch_xml_free(xml);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
return status;
|
||||
}
|
||||
|
||||
static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *thread, void *obj)
|
||||
|
@ -1371,8 +1393,11 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
|||
|
||||
/* member is gone before we could process it */
|
||||
if (!member_session) {
|
||||
sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%ld' WHERE system = 'single_box' AND uuid = '%q' AND state != '%q'",
|
||||
cc_member_state2str(CC_MEMBER_STATE_ABANDONED), (long) switch_epoch_time_now(NULL), h->member_uuid, cc_member_state2str(CC_MEMBER_STATE_ABANDONED));
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Member %s <%s> with uuid %s in queue %s is gone just before we assigned an agent\n", h->member_cid_name, h->member_cid_number, h->member_session_uuid, h->queue_name);
|
||||
|
||||
|
||||
sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%" MSWITCH_TIME_T_FMT "' WHERE system = 'single_box' AND uuid = '%q' AND state != '%q'",
|
||||
cc_member_state2str(CC_MEMBER_STATE_ABANDONED), local_epoch_time_now(NULL), h->member_uuid, cc_member_state2str(CC_MEMBER_STATE_ABANDONED));
|
||||
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
|
@ -1405,7 +1430,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
|||
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_side", "%s", "agent");
|
||||
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "ignore_early_media", "true");
|
||||
|
||||
t_agent_called = switch_epoch_time_now(NULL);
|
||||
t_agent_called = local_epoch_time_now(NULL);
|
||||
dialstr = switch_mprintf("%s", h->originate_string);
|
||||
status = switch_ivr_originate(NULL, &agent_session, &cause, dialstr, 60, NULL, h->member_cid_name, h->member_cid_number, NULL, ovars, SOF_NONE, NULL);
|
||||
switch_safe_free(dialstr);
|
||||
|
@ -1440,7 +1465,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
|||
cc_agent_update("uuid", "", h->agent_name);
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Invalid agent type '%s' for agent '%s', aborting member offering", h->agent_type, h->agent_name);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Invalid agent type '%s' for agent '%s', aborting member offering", h->agent_type, h->agent_name);
|
||||
status = SWITCH_CAUSE_USER_NOT_REGISTERED;
|
||||
}
|
||||
|
||||
|
@ -1507,7 +1532,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
|||
switch_core_session_hupall_matching_var("cc_member_pre_answer_uuid", h->member_uuid, SWITCH_CAUSE_ORIGINATOR_CANCEL);
|
||||
|
||||
}
|
||||
t_agent_answered = switch_epoch_time_now(NULL);
|
||||
t_agent_answered = local_epoch_time_now(NULL);
|
||||
|
||||
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_channel_event_set_data(agent_channel, event);
|
||||
|
@ -1516,9 +1541,9 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
|||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-System", h->agent_system);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-UUID", agent_uuid);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%ld", (long) t_agent_called);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%ld", (long) t_agent_answered);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%ld", (long) t_member_called);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%" SWITCH_TIME_T_FMT, t_agent_called);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%" SWITCH_TIME_T_FMT, t_agent_answered);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%" SWITCH_TIME_T_FMT, t_member_called);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", h->member_uuid);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", h->member_session_uuid);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", h->member_cid_name);
|
||||
|
@ -1527,12 +1552,12 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
|||
}
|
||||
/* for xml_cdr needs */
|
||||
switch_channel_set_variable(member_channel, "cc_agent", h->agent_name);
|
||||
switch_channel_set_variable_printf(member_channel, "cc_queue_answered_epoch", "%ld", (long) switch_epoch_time_now(NULL));
|
||||
switch_channel_set_variable_printf(member_channel, "cc_queue_answered_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
|
||||
|
||||
/* Set UUID of the Agent channel */
|
||||
sql = switch_mprintf("UPDATE agents SET uuid = '%q', last_bridge_start = '%ld', calls_answered = calls_answered + 1, no_answer_count = 0"
|
||||
sql = switch_mprintf("UPDATE agents SET uuid = '%q', last_bridge_start = '%" MSWITCH_TIME_T_FMT "', calls_answered = calls_answered + 1, no_answer_count = 0"
|
||||
" WHERE name = '%q' AND system = '%q'",
|
||||
agent_uuid, (long) switch_epoch_time_now(NULL),
|
||||
agent_uuid, local_epoch_time_now(NULL),
|
||||
h->agent_name, h->agent_system);
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
|
@ -1551,13 +1576,16 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
|||
}
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Agent %s answered \"%s\" <%s> from queue %s%s\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Agent %s answered \"%s\" <%s> from queue %s%s\n",
|
||||
h->agent_name, h->member_cid_name, h->member_cid_number, h->queue_name, (h->record_template?" (Recorded)":""));
|
||||
|
||||
switch_ivr_uuid_bridge(h->member_session_uuid, switch_core_session_get_uuid(agent_session));
|
||||
|
||||
/* This is used for the waiting caller to quit waiting for a agent */
|
||||
switch_channel_set_variable(member_channel, "cc_agent_uuid", agent_uuid);
|
||||
|
||||
/* This is used for the waiting caller to quit waiting for a agent */
|
||||
switch_channel_set_variable(member_channel, "cc_agent_found", "true");
|
||||
|
||||
/* Wait until the member hangup or the agent hangup. This will quit also if the agent transfer the call */
|
||||
while(switch_channel_up(member_channel) && switch_channel_up(agent_channel) && globals.running) {
|
||||
switch_yield(100000);
|
||||
|
@ -1572,10 +1600,10 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
|||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-System", h->agent_system);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-UUID", agent_uuid);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%ld", (long) t_agent_called);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%ld", (long) t_agent_answered);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%ld", (long) t_member_called);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Bridge-Terminated-Time", "%ld", (long) switch_epoch_time_now(NULL));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%" SWITCH_TIME_T_FMT, t_agent_called);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%" SWITCH_TIME_T_FMT, t_agent_answered);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%" SWITCH_TIME_T_FMT, t_member_called);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Bridge-Terminated-Time", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", h->member_uuid);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", h->member_session_uuid);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", h->member_cid_name);
|
||||
|
@ -1583,12 +1611,12 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
|||
switch_event_fire(&event);
|
||||
}
|
||||
/* for xml_cdr needs */
|
||||
switch_channel_set_variable_printf(member_channel, "cc_queue_terminated_epoch", "%ld", (long) switch_epoch_time_now(NULL));
|
||||
switch_channel_set_variable_printf(member_channel, "cc_queue_terminated_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
|
||||
|
||||
/* Update Agents Items */
|
||||
/* Do not remove uuid of the agent if we are a standby agent */
|
||||
sql = switch_mprintf("UPDATE agents SET %s last_bridge_end = %ld, talk_time = talk_time + (%ld-last_bridge_start) WHERE name = '%q' AND system = '%q';"
|
||||
, (strcasecmp(h->agent_type, CC_AGENT_TYPE_UUID_STANDBY)?"uuid = '',":""), (long) switch_epoch_time_now(NULL), (long) switch_epoch_time_now(NULL), h->agent_name, h->agent_system);
|
||||
sql = switch_mprintf("UPDATE agents SET %s last_bridge_end = %" MSWITCH_TIME_T_FMT ", talk_time = talk_time + (%" MSWITCH_TIME_T_FMT "-last_bridge_start) WHERE name = '%q' AND system = '%q';"
|
||||
, (strcasecmp(h->agent_type, CC_AGENT_TYPE_UUID_STANDBY)?"uuid = '',":""), local_epoch_time_now(NULL), local_epoch_time_now(NULL), h->agent_name, h->agent_system);
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
|
||||
|
@ -1607,10 +1635,10 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
|||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-System", h->agent_system);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-UUID", agent_uuid);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%ld", (long) t_agent_called);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%ld", (long) t_agent_answered);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Leaving-Time", "%ld", (long) switch_epoch_time_now(NULL));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%ld", (long) t_member_called);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%" SWITCH_TIME_T_FMT, t_agent_called);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%" SWITCH_TIME_T_FMT, t_agent_answered);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Leaving-Time", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%" SWITCH_TIME_T_FMT, t_member_called);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", h->member_uuid);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", h->member_session_uuid);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", h->member_cid_name);
|
||||
|
@ -1629,7 +1657,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
|||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Agent %s Origination Canceled : %s\n", h->agent_name, switch_channel_cause2str(cause));
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Agent %s Origination Canceled : %s\n", h->agent_name, switch_channel_cause2str(cause));
|
||||
|
||||
switch (cause) {
|
||||
/* When we hang-up agents that did not answer in ring-all strategy */
|
||||
|
@ -1658,7 +1686,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
|||
|
||||
/* Put Agent on break because he didn't answer often */
|
||||
if (h->max_no_answer > 0 && (h->no_answer_count + 1) >= h->max_no_answer) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Agent %s reach maximum no answer of %d, Putting agent on break\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Agent %s reach maximum no answer of %d, Putting agent on break\n",
|
||||
h->agent_name, h->max_no_answer);
|
||||
cc_agent_update("status", cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK), h->agent_name);
|
||||
}
|
||||
|
@ -1668,9 +1696,9 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
|||
/* Put agent to sleep for some time if necessary */
|
||||
if (delay_next_agent_call > 0) {
|
||||
char ready_epoch[64];
|
||||
switch_snprintf(ready_epoch, sizeof(ready_epoch), "%" SWITCH_TIME_T_FMT, switch_epoch_time_now(NULL) + delay_next_agent_call);
|
||||
switch_snprintf(ready_epoch, sizeof(ready_epoch), "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL) + delay_next_agent_call);
|
||||
cc_agent_update("ready_time", ready_epoch , h->agent_name);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Agent %s sleeping for %d seconds\n", h->agent_name, delay_next_agent_call);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Agent %s sleeping for %d seconds\n", h->agent_name, delay_next_agent_call);
|
||||
}
|
||||
|
||||
/* Fire up event when contact agent fails */
|
||||
|
@ -1763,9 +1791,10 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames
|
|||
const char *agent_wrap_up_time = argv[11];
|
||||
const char *agent_state = argv[12];
|
||||
const char *agent_ready_time = argv[13];
|
||||
const char *agent_tier_level = argv[14];
|
||||
const char *agent_type = argv[15];
|
||||
const char *agent_uuid = argv[16];
|
||||
const char *agent_tier_position = argv[14];
|
||||
const char *agent_tier_level = argv[15];
|
||||
const char *agent_type = argv[16];
|
||||
const char *agent_uuid = argv[17];
|
||||
|
||||
switch_bool_t contact_agent = SWITCH_TRUE;
|
||||
|
||||
|
@ -1778,11 +1807,11 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames
|
|||
if (cbt->tier_rule_no_agent_no_wait == SWITCH_TRUE && cbt->tier_agent_available == 0) {
|
||||
cbt->tier = atoi(agent_tier_level);
|
||||
/* Multiple the tier level by the tier wait time */
|
||||
} else if (cbt->tier_rule_wait_multiply_level == SWITCH_TRUE && (long) switch_epoch_time_now(NULL) - atol(cbt->member_joined_epoch) >= atoi(agent_tier_level) * cbt->tier_rule_wait_second) {
|
||||
} else if (cbt->tier_rule_wait_multiply_level == SWITCH_TRUE && (long) local_epoch_time_now(NULL) - atol(cbt->member_joined_epoch) >= atoi(agent_tier_level) * cbt->tier_rule_wait_second) {
|
||||
cbt->tier = atoi(agent_tier_level);
|
||||
cbt->tier_agent_available = 0;
|
||||
/* Just check if joined is bigger than next tier wait time */
|
||||
} else if (cbt->tier_rule_wait_multiply_level == SWITCH_FALSE && (long) switch_epoch_time_now(NULL) - atol(cbt->member_joined_epoch) >= cbt->tier_rule_wait_second) {
|
||||
} else if (cbt->tier_rule_wait_multiply_level == SWITCH_FALSE && (long) local_epoch_time_now(NULL) - atol(cbt->member_joined_epoch) >= cbt->tier_rule_wait_second) {
|
||||
cbt->tier = atoi(agent_tier_level);
|
||||
cbt->tier_agent_available = 0;
|
||||
} else {
|
||||
|
@ -1799,10 +1828,10 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames
|
|||
if (! (!strcasecmp(agent_state, cc_agent_state2str(CC_AGENT_STATE_WAITING)))) {
|
||||
contact_agent = SWITCH_FALSE;
|
||||
}
|
||||
if (! (atol(agent_last_bridge_end) < ((long) switch_epoch_time_now(NULL) - atol(agent_wrap_up_time)))) {
|
||||
if (! (atol(agent_last_bridge_end) < ((long) local_epoch_time_now(NULL) - atol(agent_wrap_up_time)))) {
|
||||
contact_agent = SWITCH_FALSE;
|
||||
}
|
||||
if (! (atol(agent_ready_time) <= (long) switch_epoch_time_now(NULL))) {
|
||||
if (! (atol(agent_ready_time) <= (long) local_epoch_time_now(NULL))) {
|
||||
contact_agent = SWITCH_FALSE;
|
||||
}
|
||||
if (! (strcasecmp(agent_status, cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK)))) {
|
||||
|
@ -1878,7 +1907,15 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames
|
|||
h->busy_delay_time = atoi(agent_busy_delay_time);
|
||||
h->no_answer_delay_time = atoi(agent_no_answer_delay_time);
|
||||
|
||||
|
||||
if (!strcasecmp(cbt->strategy, "top-down")) {
|
||||
switch_core_session_t *member_session = switch_core_session_locate(cbt->member_session_uuid);
|
||||
if (member_session) {
|
||||
switch_channel_t *member_channel = switch_core_session_get_channel(member_session);
|
||||
switch_channel_set_variable(member_channel, "cc_last_agent_tier_position", agent_tier_position);
|
||||
switch_channel_set_variable(member_channel, "cc_last_agent_tier_level", agent_tier_level);
|
||||
switch_core_session_rwunlock(member_session);
|
||||
}
|
||||
}
|
||||
cc_agent_update("state", cc_agent_state2str(CC_AGENT_STATE_RECEIVING), h->agent_name);
|
||||
|
||||
sql = switch_mprintf(
|
||||
|
@ -1918,7 +1955,6 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
|
|||
switch_bool_t tier_rule_wait_multiply_level;
|
||||
switch_bool_t tier_rule_no_agent_no_wait;
|
||||
uint32_t discard_abandoned_after;
|
||||
switch_bool_t abandoned_resume_allowed;
|
||||
agent_callback_t cbt;
|
||||
const char *member_state = NULL;
|
||||
const char *member_abandoned_epoch = NULL;
|
||||
|
@ -1945,7 +1981,7 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
|
|||
tier_rule_wait_multiply_level = queue->tier_rule_wait_multiply_level;
|
||||
tier_rule_no_agent_no_wait = queue->tier_rule_no_agent_no_wait;
|
||||
discard_abandoned_after = queue->discard_abandoned_after;
|
||||
abandoned_resume_allowed = queue->abandoned_resume_allowed;
|
||||
|
||||
if (queue->record_template) {
|
||||
queue_record_template = strdup(queue->record_template);
|
||||
}
|
||||
|
@ -1960,8 +1996,8 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
|
|||
abandoned_epoch = atol(cbt.member_joined_epoch);
|
||||
}
|
||||
/* Once we pass a certain point, we want to get rid of the abandoned call */
|
||||
if (abandoned_epoch + discard_abandoned_after < (long) switch_epoch_time_now(NULL)) {
|
||||
sql = switch_mprintf("DELETE FROM members WHERE system = 'single_box' AND uuid = '%q' AND (abandoned_epoch = '%ld' OR joined_epoch = '%q')", cbt.member_uuid, abandoned_epoch, cbt.member_joined_epoch);
|
||||
if (abandoned_epoch + discard_abandoned_after < (long) local_epoch_time_now(NULL)) {
|
||||
sql = switch_mprintf("DELETE FROM members WHERE system = 'single_box' AND uuid = '%q' AND (abandoned_epoch = '%" MSWITCH_TIME_T_FMT "' OR joined_epoch = '%q')", cbt.member_uuid, abandoned_epoch, cbt.member_joined_epoch);
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
}
|
||||
|
@ -1986,6 +2022,61 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
|
|||
cbt.record_template = queue_record_template;
|
||||
cbt.agent_found = SWITCH_FALSE;
|
||||
|
||||
if (!strcasecmp(queue->strategy, "top-down")) {
|
||||
/* WARNING this use channel variable to help dispatch... might need to be reviewed to save it in DB to make this multi server prooft in the future */
|
||||
switch_core_session_t *member_session = switch_core_session_locate(cbt.member_session_uuid);
|
||||
int position = 0, level = 0;
|
||||
const char *last_agent_tier_position, *last_agent_tier_level;
|
||||
if (member_session) {
|
||||
switch_channel_t *member_channel = switch_core_session_get_channel(member_session);
|
||||
|
||||
if ((last_agent_tier_position = switch_channel_get_variable(member_channel, "cc_last_agent_tier_position"))) {
|
||||
position = atoi(last_agent_tier_position);
|
||||
}
|
||||
if ((last_agent_tier_level = switch_channel_get_variable(member_channel, "cc_last_agent_tier_level"))) {
|
||||
level = atoi(last_agent_tier_level);
|
||||
}
|
||||
switch_core_session_rwunlock(member_session);
|
||||
}
|
||||
|
||||
sql = switch_mprintf("SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, agents.last_offered_call as agents_last_offered_call, 1 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
|
||||
" WHERE tiers.queue = '%q'"
|
||||
" AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')"
|
||||
" AND tiers.position > %d"
|
||||
" AND tiers.level = %d"
|
||||
" UNION "
|
||||
"SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, agents.last_offered_call as agents_last_offered_call, 2 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
|
||||
" WHERE tiers.queue = '%q'"
|
||||
" AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')"
|
||||
" ORDER BY dyn_order asc, tiers_level, tiers_position, agents_last_offered_call",
|
||||
queue_name,
|
||||
cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE), cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK), cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE_ON_DEMAND),
|
||||
position,
|
||||
level,
|
||||
queue_name,
|
||||
cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE), cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK), cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE_ON_DEMAND)
|
||||
);
|
||||
} else if (!strcasecmp(queue->strategy, "round-robin")) {
|
||||
sql = switch_mprintf("SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, agents.last_offered_call as agents_last_offered_call, 1 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
|
||||
" WHERE tiers.queue = '%q'"
|
||||
" AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')"
|
||||
" AND tiers.position > (SELECT tiers.position FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent) WHERE tiers.queue = '%q' AND agents.last_offered_call > 0 ORDER BY agents.last_offered_call DESC LIMIT 1)"
|
||||
" AND tiers.level = (SELECT tiers.level FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent) WHERE tiers.queue = '%q' AND agents.last_offered_call > 0 ORDER BY agents.last_offered_call DESC LIMIT 1)"
|
||||
" UNION "
|
||||
"SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, agents.last_offered_call as agents_last_offered_call, 2 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
|
||||
" WHERE tiers.queue = '%q'"
|
||||
" AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')"
|
||||
" ORDER BY dyn_order asc, tiers_level, tiers_position, agents_last_offered_call",
|
||||
queue_name,
|
||||
cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE), cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK), cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE_ON_DEMAND),
|
||||
queue_name,
|
||||
queue_name,
|
||||
queue_name,
|
||||
cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE), cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK), cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE_ON_DEMAND)
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
if (!strcasecmp(queue->strategy, "longest-idle-agent")) {
|
||||
sql_order_by = switch_mprintf("level, agents.last_offered_call, position");
|
||||
} else if (!strcasecmp(queue_strategy, "agent-with-least-talk-time")) {
|
||||
|
@ -1998,6 +2089,8 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
|
|||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
sql_order_by = switch_mprintf("level, position");
|
||||
} else if(!strcasecmp(queue_strategy, "random")) {
|
||||
sql_order_by = switch_mprintf("level, random()");
|
||||
} else if(!strcasecmp(queue_strategy, "sequentially-by-agent-order")) {
|
||||
sql_order_by = switch_mprintf("level, position, agents.last_offered_call"); /* Default to last_offered_call, let add new strategy if needing it differently */
|
||||
} else {
|
||||
|
@ -2005,25 +2098,27 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
|
|||
sql_order_by = switch_mprintf("level, position, agents.last_offered_call");
|
||||
}
|
||||
|
||||
sql = switch_mprintf("SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.level, agents.type, agents.uuid FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
|
||||
sql = switch_mprintf("SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position, tiers.level, agents.type, agents.uuid FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
|
||||
" WHERE tiers.queue = '%q'"
|
||||
" AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')"
|
||||
" ORDER BY %q",
|
||||
queue_name,
|
||||
cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE), cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK), cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE_ON_DEMAND),
|
||||
sql_order_by);
|
||||
switch_safe_free(sql_order_by);
|
||||
|
||||
}
|
||||
|
||||
cc_execute_sql_callback(NULL /* queue */, NULL /* mutex */, sql, agents_callback, &cbt /* Call back variables */);
|
||||
|
||||
switch_safe_free(sql);
|
||||
switch_safe_free(sql_order_by);
|
||||
|
||||
/* We update a field in the queue struct so we can kick caller out if waiting for too long with no agent */
|
||||
if (!cbt.queue_name || !(queue = get_queue(cbt.queue_name))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Queue %s not found locally, skip this member\n", cbt.queue_name);
|
||||
goto end;
|
||||
} else {
|
||||
queue->last_agent_exist_check = switch_epoch_time_now(NULL);
|
||||
queue->last_agent_exist_check = local_epoch_time_now(NULL);
|
||||
if (cbt.agent_found) {
|
||||
queue->last_agent_exist = queue->last_agent_exist_check;
|
||||
}
|
||||
|
@ -2062,9 +2157,9 @@ void *SWITCH_THREAD_FUNC cc_agent_dispatch_thread_run(switch_thread_t *thread, v
|
|||
|
||||
while (globals.running == 1) {
|
||||
char *sql = NULL;
|
||||
sql = switch_mprintf("SELECT queue,uuid,session_uuid,cid_number,cid_name,joined_epoch,(%ld-joined_epoch)+base_score+skill_score AS score, state, abandoned_epoch FROM members"
|
||||
sql = switch_mprintf("SELECT queue,uuid,session_uuid,cid_number,cid_name,joined_epoch,(%" MSWITCH_TIME_T_FMT "-joined_epoch)+base_score+skill_score AS score, state, abandoned_epoch FROM members"
|
||||
" WHERE state = '%q' OR state = '%q' OR (serving_agent = 'ring-all' AND state = '%q') ORDER BY score DESC",
|
||||
(long) switch_epoch_time_now(NULL),
|
||||
local_epoch_time_now(NULL),
|
||||
cc_member_state2str(CC_MEMBER_STATE_WAITING), cc_member_state2str(CC_MEMBER_STATE_ABANDONED), cc_member_state2str(CC_MEMBER_STATE_TRYING));
|
||||
|
||||
cc_execute_sql_callback(NULL /* queue */, NULL /* mutex */, sql, members_callback, NULL /* Call back variables */);
|
||||
|
@ -2113,6 +2208,8 @@ struct member_thread_helper {
|
|||
const char *queue_name;
|
||||
const char *member_uuid;
|
||||
const char *member_session_uuid;
|
||||
const char *member_cid_name;
|
||||
const char *member_cid_number;
|
||||
switch_time_t t_member_called;
|
||||
cc_member_cancel_reason_t member_cancel_reason;
|
||||
|
||||
|
@ -2126,10 +2223,6 @@ void *SWITCH_THREAD_FUNC cc_member_thread_run(switch_thread_t *thread, void *obj
|
|||
switch_core_session_t *member_session = switch_core_session_locate(m->member_session_uuid);
|
||||
switch_channel_t *member_channel = NULL;
|
||||
|
||||
switch_mutex_lock(globals.mutex);
|
||||
globals.threads++;
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
|
||||
if (member_session) {
|
||||
member_channel = switch_core_session_get_channel(member_session);
|
||||
} else {
|
||||
|
@ -2137,15 +2230,20 @@ void *SWITCH_THREAD_FUNC cc_member_thread_run(switch_thread_t *thread, void *obj
|
|||
return NULL;
|
||||
}
|
||||
|
||||
switch_mutex_lock(globals.mutex);
|
||||
globals.threads++;
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
|
||||
while(switch_channel_ready(member_channel) && m->running && globals.running) {
|
||||
cc_queue_t *queue = NULL;
|
||||
|
||||
if (!m->queue_name || !(queue = get_queue(m->queue_name))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Queue %s not found\n", m->queue_name);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_WARNING, "Queue %s not found\n", m->queue_name);
|
||||
break;
|
||||
}
|
||||
/* Make the Caller Leave if he went over his max wait time */
|
||||
if (queue->max_wait_time > 0 && queue->max_wait_time <= switch_epoch_time_now(NULL) - m->t_member_called) {
|
||||
if (queue->max_wait_time > 0 && queue->max_wait_time <= local_epoch_time_now(NULL) - m->t_member_called) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> in queue '%s' reached max wait time\n", m->member_cid_name, m->member_cid_number, m->queue_name);
|
||||
m->member_cancel_reason = CC_MEMBER_CANCEL_REASON_TIMEOUT;
|
||||
switch_channel_set_flag_value(member_channel, CF_BREAK, 2);
|
||||
}
|
||||
|
@ -2153,6 +2251,7 @@ void *SWITCH_THREAD_FUNC cc_member_thread_run(switch_thread_t *thread, void *obj
|
|||
/* Will drop the caller if no agent was found for more than X seconds */
|
||||
if (queue->max_wait_time_with_no_agent > 0 && m->t_member_called < queue->last_agent_exist_check - queue->max_wait_time_with_no_agent_time_reached &&
|
||||
queue->last_agent_exist_check - queue->last_agent_exist >= queue->max_wait_time_with_no_agent) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> in queue '%s' reached max wait with no agent time\n", m->member_cid_name, m->member_cid_number, m->queue_name);
|
||||
m->member_cancel_reason = CC_MEMBER_CANCEL_REASON_NO_AGENT_TIMEOUT;
|
||||
switch_channel_set_flag_value(member_channel, CF_BREAK, 2);
|
||||
}
|
||||
|
@ -2218,7 +2317,6 @@ static switch_status_t moh_on_dtmf(switch_core_session_t *session, void *input,
|
|||
|
||||
SWITCH_STANDARD_APP(callcenter_function)
|
||||
{
|
||||
int argc = 0;
|
||||
char *argv[6] = { 0 };
|
||||
char *mydata = NULL;
|
||||
cc_queue_t *queue = NULL;
|
||||
|
@ -2238,17 +2336,18 @@ SWITCH_STANDARD_APP(callcenter_function)
|
|||
const char *cur_moh = NULL;
|
||||
char start_epoch[64];
|
||||
switch_event_t *event;
|
||||
switch_time_t t_member_called = switch_epoch_time_now(NULL);
|
||||
switch_time_t t_member_called = local_epoch_time_now(NULL);
|
||||
long abandoned_epoch = 0;
|
||||
const char *agent_uuid = NULL;
|
||||
switch_uuid_t smember_uuid;
|
||||
char member_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = "";
|
||||
switch_bool_t agent_found = SWITCH_FALSE;
|
||||
switch_bool_t moh_valid = SWITCH_TRUE;
|
||||
|
||||
if (!zstr(data)) {
|
||||
mydata = switch_core_session_strdup(member_session, data);
|
||||
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No Queue name provided\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_WARNING, "No Queue name provided\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -2257,7 +2356,7 @@ SWITCH_STANDARD_APP(callcenter_function)
|
|||
}
|
||||
|
||||
if (!queue_name || !(queue = get_queue(queue_name))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Queue %s not found\n", queue_name);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_WARNING, "Queue %s not found\n", queue_name);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -2303,7 +2402,7 @@ SWITCH_STANDARD_APP(callcenter_function)
|
|||
|
||||
/* If system, will add the total time the session is up to the base score */
|
||||
if (!switch_strlen_zero(start_epoch) && !strcasecmp("system", queue->time_base_score)) {
|
||||
cc_base_score_int += ((long) switch_epoch_time_now(NULL) - atol(start_epoch));
|
||||
cc_base_score_int += ((long) local_epoch_time_now(NULL) - atol(start_epoch));
|
||||
}
|
||||
|
||||
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) {
|
||||
|
@ -2317,19 +2416,21 @@ SWITCH_STANDARD_APP(callcenter_function)
|
|||
switch_event_fire(&event);
|
||||
}
|
||||
/* for xml_cdr needs */
|
||||
switch_channel_set_variable_printf(member_channel, "cc_queue_joined_epoch", "%ld", (long) switch_epoch_time_now(NULL));
|
||||
switch_channel_set_variable_printf(member_channel, "cc_queue_joined_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
|
||||
switch_channel_set_variable(member_channel, "cc_queue", queue_name);
|
||||
|
||||
if (abandoned_epoch == 0) {
|
||||
/* Add the caller to the member queue */
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> joining queue %s\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name);
|
||||
|
||||
sql = switch_mprintf("INSERT INTO members"
|
||||
" (queue,system,uuid,session_uuid,system_epoch,joined_epoch,base_score,skill_score,cid_number,cid_name,serving_agent,serving_system,state)"
|
||||
" VALUES('%q','single_box','%q','%q','%q','%ld','%d','%d','%q','%q','%q','','%q')",
|
||||
" VALUES('%q','single_box','%q','%q','%q','%" MSWITCH_TIME_T_FMT "','%d','%d','%q','%q','%q','','%q')",
|
||||
queue_name,
|
||||
member_uuid,
|
||||
member_session_uuid,
|
||||
start_epoch,
|
||||
(long) switch_epoch_time_now(NULL),
|
||||
local_epoch_time_now(NULL),
|
||||
cc_base_score_int,
|
||||
0 /*TODO SKILL score*/,
|
||||
switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")),
|
||||
|
@ -2340,21 +2441,24 @@ SWITCH_STANDARD_APP(callcenter_function)
|
|||
switch_safe_free(sql);
|
||||
} else {
|
||||
char res[256];
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> restoring it previous position in queue %s\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name);
|
||||
|
||||
/* Update abandoned member */
|
||||
sql = switch_mprintf("UPDATE members SET session_uuid = '%q', state = '%q', rejoined_epoch = '%ld' WHERE uuid = '%q' AND state = '%q'",
|
||||
member_session_uuid, cc_member_state2str(CC_MEMBER_STATE_WAITING), (long) switch_epoch_time_now(NULL), member_uuid, cc_member_state2str(CC_MEMBER_STATE_ABANDONED));
|
||||
sql = switch_mprintf("UPDATE members SET session_uuid = '%q', state = '%q', rejoined_epoch = '%" MSWITCH_TIME_T_FMT "' WHERE uuid = '%q' AND state = '%q'",
|
||||
member_session_uuid, cc_member_state2str(CC_MEMBER_STATE_WAITING), local_epoch_time_now(NULL), member_uuid, cc_member_state2str(CC_MEMBER_STATE_ABANDONED));
|
||||
cc_execute_sql(queue, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
|
||||
/* Confirm we took that member in */
|
||||
sql = switch_mprintf("SELECT abandoned_epoch FROM members WHERE uuid = '%q' AND session_uuid = '%q' AND state = '%q' AND queue = '%q'", member_session, member_session_uuid, cc_member_state2str(CC_MEMBER_STATE_WAITING), queue_name);
|
||||
sql = switch_mprintf("SELECT abandoned_epoch FROM members WHERE uuid = '%q' AND session_uuid = '%q' AND state = '%q' AND queue = '%q'", member_uuid, member_session_uuid, cc_member_state2str(CC_MEMBER_STATE_WAITING), queue_name);
|
||||
cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
|
||||
switch_safe_free(sql);
|
||||
|
||||
if (atol(res) == 0) {
|
||||
/* Failed to get the member !!! */
|
||||
/* TODO Loop back to just create a uuid and add the member as a new member */
|
||||
/* TODO ERROR MSG */
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_ERROR, "Member %s <%s> restoring action failed in queue %s, exiting\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name);
|
||||
queue_rwunlock(queue);
|
||||
goto end;
|
||||
}
|
||||
|
@ -2371,6 +2475,8 @@ SWITCH_STANDARD_APP(callcenter_function)
|
|||
h->pool = pool;
|
||||
h->member_uuid = switch_core_strdup(h->pool, member_uuid);
|
||||
h->member_session_uuid = switch_core_strdup(h->pool, member_session_uuid);
|
||||
h->member_cid_name = switch_core_strdup(h->pool, switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")));
|
||||
h->member_cid_number = switch_core_strdup(h->pool, switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")));
|
||||
h->queue_name = switch_core_strdup(h->pool, queue_name);
|
||||
h->t_member_called = t_member_called;
|
||||
h->member_cancel_reason = CC_MEMBER_CANCEL_REASON_NONE;
|
||||
|
@ -2392,6 +2498,7 @@ SWITCH_STANDARD_APP(callcenter_function)
|
|||
while (switch_channel_ready(member_channel)) {
|
||||
switch_input_args_t args = { 0 };
|
||||
struct moh_dtmf_helper ht;
|
||||
const char *p;
|
||||
|
||||
ht.dtmf = '\0';
|
||||
args.input_callback = moh_on_dtmf;
|
||||
|
@ -2399,7 +2506,7 @@ SWITCH_STANDARD_APP(callcenter_function)
|
|||
args.buflen = sizeof(h);
|
||||
|
||||
/* An agent was found, time to exit and let the bridge do it job */
|
||||
if ((agent_uuid = switch_channel_get_variable(member_channel, "cc_agent_uuid"))) {
|
||||
if ((p = switch_channel_get_variable(member_channel, "cc_agent_found")) && (agent_found = switch_true(p))) {
|
||||
break;
|
||||
}
|
||||
/* If the member thread set a different reason, we monitor it so we can quit the wait */
|
||||
|
@ -2409,10 +2516,14 @@ SWITCH_STANDARD_APP(callcenter_function)
|
|||
|
||||
switch_core_session_flush_private_events(member_session);
|
||||
|
||||
if (cur_moh) {
|
||||
if (moh_valid && cur_moh) {
|
||||
switch_status_t status = switch_ivr_play_file(member_session, NULL, cur_moh, &args);
|
||||
|
||||
if (!SWITCH_READ_ACCEPTABLE(status)) {
|
||||
if (status == SWITCH_STATUS_FALSE /* Invalid Recording */) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_WARNING, "Couldn't play file '%s', continuing wait with no audio\n", cur_moh);
|
||||
moh_valid = SWITCH_FALSE;
|
||||
|
||||
} else if (!SWITCH_READ_ACCEPTABLE(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2430,28 +2541,31 @@ SWITCH_STANDARD_APP(callcenter_function)
|
|||
}
|
||||
|
||||
/* Check if we were removed be cause FS Core(BREAK) asked us too */
|
||||
if (h->member_cancel_reason == CC_MEMBER_CANCEL_REASON_NONE && !switch_channel_get_variable(member_channel, "cc_agent_uuid")) {
|
||||
if (h->member_cancel_reason == CC_MEMBER_CANCEL_REASON_NONE && !agent_found) {
|
||||
h->member_cancel_reason = CC_MEMBER_CANCEL_REASON_BREAK_OUT;
|
||||
}
|
||||
|
||||
switch_channel_set_variable(member_channel, "cc_agent_found", NULL);
|
||||
/* Canceled for some reason */
|
||||
if (!switch_channel_up(member_channel) || h->member_cancel_reason != CC_MEMBER_CANCEL_REASON_NONE) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> abandoned waiting in queue %s\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name);
|
||||
|
||||
/* Update member state */
|
||||
sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%ld' WHERE system = 'single_box' AND uuid = '%q'",
|
||||
cc_member_state2str(CC_MEMBER_STATE_ABANDONED), (long) switch_epoch_time_now(NULL), member_uuid);
|
||||
sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%" MSWITCH_TIME_T_FMT "' WHERE system = 'single_box' AND uuid = '%q'",
|
||||
cc_member_state2str(CC_MEMBER_STATE_ABANDONED), local_epoch_time_now(NULL), member_uuid);
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
|
||||
/* Hangup any callback agents */
|
||||
switch_core_session_hupall_matching_var("cc_member_uuid", member_uuid, SWITCH_CAUSE_ORIGINATOR_CANCEL);
|
||||
switch_core_session_hupall_matching_var("cc_member_pre_answer_uuid", member_uuid, SWITCH_CAUSE_ORIGINATOR_CANCEL);
|
||||
|
||||
/* Generate an event */
|
||||
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_channel_event_set_data(member_channel, event);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Queue", queue_name);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Action", "member-queue-end");
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Leaving-Time", "%ld", (long) switch_epoch_time_now(NULL));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%ld", (long) t_member_called);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Leaving-Time", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%" SWITCH_TIME_T_FMT, t_member_called);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Cause", "Cancel");
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Cancel-Reason", cc_member_cancel_reason2str(h->member_cancel_reason));
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", member_uuid);
|
||||
|
@ -2462,20 +2576,22 @@ SWITCH_STANDARD_APP(callcenter_function)
|
|||
}
|
||||
|
||||
/* Update some channel variables for xml_cdr needs */
|
||||
switch_channel_set_variable_printf(member_channel, "cc_queue_canceled_epoch", "%ld", (long) switch_epoch_time_now(NULL));
|
||||
switch_channel_set_variable_printf(member_channel, "cc_queue_canceled_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
|
||||
switch_channel_set_variable_printf(member_channel, "cc_cause", "%s", "cancel");
|
||||
switch_channel_set_variable_printf(member_channel, "cc_cancel_reason", "%s", cc_member_cancel_reason2str(h->member_cancel_reason));
|
||||
|
||||
/* Print some debug log information */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Member \"%s\" <%s> exit queue %s due to %s\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member \"%s\" <%s> exit queue %s due to %s\n",
|
||||
switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")),
|
||||
switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")),
|
||||
queue_name, cc_member_cancel_reason2str(h->member_cancel_reason));
|
||||
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> is answered by an agent in queue %s\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name);
|
||||
|
||||
/* Update member state */
|
||||
sql = switch_mprintf("UPDATE members SET state = '%q', bridge_epoch = '%ld' WHERE system = 'single_box' AND uuid = '%q'",
|
||||
cc_member_state2str(CC_MEMBER_STATE_ANSWERED), (long) switch_epoch_time_now(NULL), member_uuid);
|
||||
sql = switch_mprintf("UPDATE members SET state = '%q', bridge_epoch = '%" MSWITCH_TIME_T_FMT "' WHERE system = 'single_box' AND uuid = '%q'",
|
||||
cc_member_state2str(CC_MEMBER_STATE_ANSWERED), local_epoch_time_now(NULL), member_uuid);
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
|
||||
|
|
|
@ -366,7 +366,6 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha
|
|||
switch_time_t time_diff = 0;
|
||||
CURL *curl_handle = NULL;
|
||||
long httpRes = 0;
|
||||
char hostname[256] = "";
|
||||
|
||||
struct http_data http_data;
|
||||
|
||||
|
@ -375,8 +374,6 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha
|
|||
http_data.max_bytes = 10240;
|
||||
SWITCH_STANDARD_STREAM(http_data.stream);
|
||||
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "url: %s\n", query);
|
||||
curl_handle = curl_easy_init();
|
||||
|
||||
|
@ -729,6 +726,9 @@ SWITCH_STANDARD_APP(cidlookup_app_function)
|
|||
if (!session && pool) {
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
}
|
||||
/* This is so compile doesn't failed because status is never used */
|
||||
if (status) {
|
||||
}
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(cidlookup_function)
|
||||
|
|
|
@ -217,7 +217,7 @@ int go(int i)
|
|||
int vgo(int i, switch_core_session_t *session)
|
||||
{
|
||||
int x;
|
||||
int sleep_len = 40000;
|
||||
//int sleep_len = 40000;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_frame_t *read_frame;
|
||||
switch_status_t status;
|
||||
|
@ -233,9 +233,9 @@ int vgo(int i, switch_core_session_t *session)
|
|||
|
||||
printf("%s", SWITCH_SEQ_CLEARSCR);
|
||||
|
||||
if (i > 0) {
|
||||
sleep_len = i;
|
||||
}
|
||||
//if (i > 0) {
|
||||
//sleep_len = i;
|
||||
//}
|
||||
|
||||
initscr();
|
||||
signal(SIGINT, SIG_IGN);
|
||||
|
|
|
@ -249,9 +249,13 @@ SWITCH_STANDARD_API(banner_function)
|
|||
|
||||
SWITCH_STANDARD_API(hostname_api_function)
|
||||
{
|
||||
char hostname[256] = "";
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
stream->write_function(stream, "%s", hostname);
|
||||
stream->write_function(stream, "%s", switch_core_get_hostname());
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(switchname_api_function)
|
||||
{
|
||||
stream->write_function(stream, "%s", switch_core_get_switchname());
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2601,7 +2605,6 @@ SWITCH_STANDARD_API(uuid_broadcast_function)
|
|||
{
|
||||
char *mycmd = NULL, *argv[4] = { 0 };
|
||||
int argc = 0;
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
if (!zstr(cmd) && (mycmd = strdup(cmd))) {
|
||||
argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
|
@ -2635,7 +2638,7 @@ SWITCH_STANDARD_API(uuid_broadcast_function)
|
|||
flags = SMF_ECHO_ALEG | SMF_HOLD_BLEG;
|
||||
}
|
||||
|
||||
status = switch_ivr_broadcast(argv[0], argv[1], flags);
|
||||
switch_ivr_broadcast(argv[0], argv[1], flags);
|
||||
stream->write_function(stream, "+OK Message Sent\n");
|
||||
}
|
||||
|
||||
|
@ -2648,7 +2651,6 @@ SWITCH_STANDARD_API(sched_broadcast_function)
|
|||
{
|
||||
char *mycmd = NULL, *argv[4] = { 0 };
|
||||
int argc = 0;
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
if (!zstr(cmd) && (mycmd = strdup(cmd))) {
|
||||
argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
|
@ -2678,7 +2680,7 @@ SWITCH_STANDARD_API(sched_broadcast_function)
|
|||
flags |= SMF_ECHO_ALEG;
|
||||
}
|
||||
|
||||
status = switch_ivr_schedule_broadcast(when, argv[1], argv[2], flags);
|
||||
switch_ivr_schedule_broadcast(when, argv[1], argv[2], flags);
|
||||
stream->write_function(stream, "+OK Message Scheduled\n");
|
||||
}
|
||||
|
||||
|
@ -2763,8 +2765,6 @@ SWITCH_STANDARD_API(uuid_buglist_function)
|
|||
char *mydata = NULL, *argv[2] = { 0 };
|
||||
int argc = 0;
|
||||
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
if (zstr(cmd)) {
|
||||
goto error;
|
||||
}
|
||||
|
@ -2781,7 +2781,7 @@ SWITCH_STANDARD_API(uuid_buglist_function)
|
|||
switch_core_session_t *lsession = NULL;
|
||||
|
||||
if ((lsession = switch_core_session_locate(argv[0]))) {
|
||||
status = switch_core_media_bug_enumerate(lsession, stream);
|
||||
switch_core_media_bug_enumerate(lsession, stream);
|
||||
switch_core_session_rwunlock(lsession);
|
||||
}
|
||||
goto ok;
|
||||
|
@ -3863,13 +3863,10 @@ SWITCH_STANDARD_API(show_function)
|
|||
struct holder holder = { 0 };
|
||||
int help = 0;
|
||||
char *mydata = NULL, *argv[6] = { 0 };
|
||||
int argc;
|
||||
char *command = NULL, *as = NULL;
|
||||
switch_core_flag_t cflags = switch_core_flags();
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
char hostname[256] = "";
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
|
||||
const char *hostname = switch_core_get_switchname();
|
||||
|
||||
if (!(cflags & SCF_USE_SQL)) {
|
||||
stream->write_function(stream, "-ERR SQL DISABLED NO DATA AVAILABLE!\n");
|
||||
|
@ -3884,7 +3881,7 @@ SWITCH_STANDARD_API(show_function)
|
|||
holder.justcount = 0;
|
||||
|
||||
if (cmd && (mydata = strdup(cmd))) {
|
||||
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
command = argv[0];
|
||||
if (argv[2] && !strcasecmp(argv[1], "as")) {
|
||||
as = argv[2];
|
||||
|
@ -4378,10 +4375,10 @@ SWITCH_STANDARD_API(uuid_fileman_function)
|
|||
char *cmd = argv[1];
|
||||
|
||||
if ((psession = switch_core_session_locate(uuid))) {
|
||||
switch_channel_t *channel;
|
||||
//switch_channel_t *channel;
|
||||
switch_file_handle_t *fh = NULL;
|
||||
|
||||
channel = switch_core_session_get_channel(psession);
|
||||
//channel = switch_core_session_get_channel(psession);
|
||||
|
||||
if (switch_ivr_get_file_handle(psession, &fh) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_ivr_process_fh(psession, cmd, fh);
|
||||
|
@ -4689,13 +4686,12 @@ SWITCH_STANDARD_API(strftime_tz_api_function)
|
|||
SWITCH_STANDARD_API(hupall_api_function)
|
||||
{
|
||||
char *mycmd = NULL, *argv[3] = { 0 };
|
||||
int argc = 0;
|
||||
char *var = NULL;
|
||||
char *val = NULL;
|
||||
switch_call_cause_t cause = SWITCH_CAUSE_MANAGER_REQUEST;
|
||||
|
||||
if (!zstr(cmd) && (mycmd = strdup(cmd))) {
|
||||
argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
switch_assert(argv[0]);
|
||||
if ((cause = switch_channel_str2cause(argv[0])) == SWITCH_CAUSE_NONE) {
|
||||
cause = SWITCH_CAUSE_MANAGER_REQUEST;
|
||||
|
@ -5156,6 +5152,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
|||
SWITCH_ADD_API(commands_api_interface, "help", "Show help for all the api commands", help_function, "");
|
||||
SWITCH_ADD_API(commands_api_interface, "host_lookup", "host_lookup", host_lookup_function, "<hostname>");
|
||||
SWITCH_ADD_API(commands_api_interface, "hostname", "Returns the system hostname", hostname_api_function, "");
|
||||
SWITCH_ADD_API(commands_api_interface, "switchname", "Returns the switch name", switchname_api_function, "");
|
||||
SWITCH_ADD_API(commands_api_interface, "hupall", "hupall", hupall_api_function, "<cause> [<var> <value>]");
|
||||
SWITCH_ADD_API(commands_api_interface, "in_group", "determine if a user is in a group", in_group_function, "<user>[@<domain>] <group_name>");
|
||||
SWITCH_ADD_API(commands_api_interface, "is_lan_addr", "see if an ip is a lan addr", lan_addr_function, "<ip>");
|
||||
|
|
|
@ -778,7 +778,7 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe
|
|||
}
|
||||
|
||||
switch_channel_clear_app_flag_key("conf_silent", channel, CONF_SILENT_REQ);
|
||||
|
||||
switch_channel_set_app_flag_key("conf_silent", channel, CONF_SILENT_DONE);
|
||||
|
||||
switch_ivr_dmachine_create(&member->dmachine, "mod_conference", NULL, 500, 0, NULL, NULL, NULL);
|
||||
|
||||
|
@ -948,7 +948,7 @@ static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thr
|
|||
conference_member_t *imember;
|
||||
switch_frame_t *vid_frame;
|
||||
switch_status_t status;
|
||||
int has_vid = 1, req_iframe = 0;
|
||||
int has_vid = 1;// req_iframe = 0;
|
||||
int yield = 0;
|
||||
uint32_t last_member = 0;
|
||||
switch_core_session_t *session;
|
||||
|
@ -983,7 +983,7 @@ static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thr
|
|||
|
||||
if (!SWITCH_READ_ACCEPTABLE(status) || !conference->floor_holder || switch_test_flag(vid_frame, SFF_CNG)) {
|
||||
conference->floor_holder = NULL;
|
||||
req_iframe = 0;
|
||||
//req_iframe = 0;
|
||||
goto do_continue;
|
||||
}
|
||||
|
||||
|
@ -1018,7 +1018,7 @@ static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thr
|
|||
goto do_continue;
|
||||
}
|
||||
|
||||
req_iframe = 0;
|
||||
//req_iframe = 0;
|
||||
}
|
||||
|
||||
last_member = conference->floor_holder->id;
|
||||
|
@ -1623,7 +1623,7 @@ static void conference_loop_fn_energy_up(conference_member_t *member, caller_con
|
|||
if (member == NULL)
|
||||
return;
|
||||
|
||||
lock_member(member);
|
||||
|
||||
member->energy_level += 200;
|
||||
if (member->energy_level > 1800) {
|
||||
member->energy_level = 1800;
|
||||
|
@ -1636,7 +1636,6 @@ static void conference_loop_fn_energy_up(conference_member_t *member, caller_con
|
|||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
unlock_member(member);
|
||||
|
||||
//switch_snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level);
|
||||
//conference_member_say(member, msg, 0);
|
||||
|
@ -1660,7 +1659,6 @@ static void conference_loop_fn_energy_equ_conf(conference_member_t *member, call
|
|||
if (member == NULL)
|
||||
return;
|
||||
|
||||
lock_member(member);
|
||||
member->energy_level = member->conference->energy_level;
|
||||
|
||||
if (test_eflag(member->conference, EFLAG_ENERGY_LEVEL) &&
|
||||
|
@ -1670,7 +1668,6 @@ static void conference_loop_fn_energy_equ_conf(conference_member_t *member, call
|
|||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
unlock_member(member);
|
||||
|
||||
//switch_snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level);
|
||||
//conference_member_say(member, msg, 0);
|
||||
|
@ -1691,7 +1688,6 @@ static void conference_loop_fn_energy_dn(conference_member_t *member, caller_con
|
|||
if (member == NULL)
|
||||
return;
|
||||
|
||||
lock_member(member);
|
||||
member->energy_level -= 200;
|
||||
if (member->energy_level < 0) {
|
||||
member->energy_level = 0;
|
||||
|
@ -1704,7 +1700,6 @@ static void conference_loop_fn_energy_dn(conference_member_t *member, caller_con
|
|||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
unlock_member(member);
|
||||
|
||||
//switch_snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level);
|
||||
//conference_member_say(member, msg, 0);
|
||||
|
@ -1725,7 +1720,6 @@ static void conference_loop_fn_volume_talk_up(conference_member_t *member, calle
|
|||
if (member == NULL)
|
||||
return;
|
||||
|
||||
lock_member(member);
|
||||
member->volume_out_level++;
|
||||
switch_normalize_volume(member->volume_out_level);
|
||||
|
||||
|
@ -1736,7 +1730,6 @@ static void conference_loop_fn_volume_talk_up(conference_member_t *member, calle
|
|||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
unlock_member(member);
|
||||
|
||||
//switch_snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level);
|
||||
//conference_member_say(member, msg, 0);
|
||||
|
@ -1759,7 +1752,6 @@ static void conference_loop_fn_volume_talk_zero(conference_member_t *member, cal
|
|||
if (member == NULL)
|
||||
return;
|
||||
|
||||
lock_member(member);
|
||||
member->volume_out_level = 0;
|
||||
|
||||
if (test_eflag(member->conference, EFLAG_VOLUME_LEVEL) &&
|
||||
|
@ -1769,7 +1761,6 @@ static void conference_loop_fn_volume_talk_zero(conference_member_t *member, cal
|
|||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
unlock_member(member);
|
||||
|
||||
//switch_snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level);
|
||||
//conference_member_say(member, msg, 0);
|
||||
|
@ -1792,7 +1783,6 @@ static void conference_loop_fn_volume_talk_dn(conference_member_t *member, calle
|
|||
if (member == NULL)
|
||||
return;
|
||||
|
||||
lock_member(member);
|
||||
member->volume_out_level--;
|
||||
switch_normalize_volume(member->volume_out_level);
|
||||
|
||||
|
@ -1803,7 +1793,6 @@ static void conference_loop_fn_volume_talk_dn(conference_member_t *member, calle
|
|||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
unlock_member(member);
|
||||
|
||||
//switch_snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level);
|
||||
//conference_member_say(member, msg, 0);
|
||||
|
@ -1825,7 +1814,6 @@ static void conference_loop_fn_volume_listen_up(conference_member_t *member, cal
|
|||
if (member == NULL)
|
||||
return;
|
||||
|
||||
lock_member(member);
|
||||
member->volume_in_level++;
|
||||
switch_normalize_volume(member->volume_in_level);
|
||||
|
||||
|
@ -1836,7 +1824,6 @@ static void conference_loop_fn_volume_listen_up(conference_member_t *member, cal
|
|||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
unlock_member(member);
|
||||
|
||||
//switch_snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level);
|
||||
//conference_member_say(member, msg, 0);
|
||||
|
@ -1859,7 +1846,6 @@ static void conference_loop_fn_volume_listen_zero(conference_member_t *member, c
|
|||
if (member == NULL)
|
||||
return;
|
||||
|
||||
lock_member(member);
|
||||
member->volume_in_level = 0;
|
||||
|
||||
if (test_eflag(member->conference, EFLAG_GAIN_LEVEL) &&
|
||||
|
@ -1869,7 +1855,6 @@ static void conference_loop_fn_volume_listen_zero(conference_member_t *member, c
|
|||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
unlock_member(member);
|
||||
|
||||
//switch_snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level);
|
||||
//conference_member_say(member, msg, 0);
|
||||
|
@ -1892,7 +1877,6 @@ static void conference_loop_fn_volume_listen_dn(conference_member_t *member, cal
|
|||
if (member == NULL)
|
||||
return;
|
||||
|
||||
lock_member(member);
|
||||
member->volume_in_level--;
|
||||
switch_normalize_volume(member->volume_in_level);
|
||||
|
||||
|
@ -1903,7 +1887,6 @@ static void conference_loop_fn_volume_listen_dn(conference_member_t *member, cal
|
|||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
unlock_member(member);
|
||||
|
||||
//switch_snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level);
|
||||
//conference_member_say(member, msg, 0);
|
||||
|
@ -2512,30 +2495,20 @@ static void conference_loop_output(conference_member_t *member)
|
|||
switch_timer_t timer = { 0 };
|
||||
uint32_t interval;
|
||||
uint32_t samples;
|
||||
uint32_t csamples;
|
||||
//uint32_t csamples;
|
||||
uint32_t tsamples;
|
||||
uint32_t flush_len;
|
||||
uint32_t low_count, bytes;
|
||||
call_list_t *call_list, *cp;
|
||||
int restarting = -1;
|
||||
switch_codec_implementation_t read_impl = { 0 };
|
||||
|
||||
top:
|
||||
|
||||
switch_core_session_get_read_impl(member->session, &read_impl);
|
||||
|
||||
restarting++;
|
||||
|
||||
if (switch_test_flag(member, MFLAG_RESTART)) {
|
||||
switch_clear_flag(member, MFLAG_RESTART);
|
||||
switch_set_flag_locked(member, MFLAG_FLUSH_BUFFER);
|
||||
switch_core_timer_destroy(&timer);
|
||||
}
|
||||
|
||||
channel = switch_core_session_get_channel(member->session);
|
||||
interval = read_impl.microseconds_per_packet / 1000;
|
||||
samples = switch_samples_per_packet(member->conference->rate, interval);
|
||||
csamples = samples;
|
||||
//csamples = samples;
|
||||
tsamples = member->orig_read_impl.samples_per_packet;
|
||||
flush_len = 0;
|
||||
low_count = 0;
|
||||
|
@ -2557,14 +2530,13 @@ static void conference_loop_output(conference_member_t *member)
|
|||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, "Setup timer %s success interval: %u samples: %u\n",
|
||||
member->conference->timer_name, interval, tsamples);
|
||||
|
||||
if (!restarting) {
|
||||
|
||||
write_frame.data = data = switch_core_session_alloc(member->session, SWITCH_RECOMMENDED_BUFFER_SIZE);
|
||||
write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
|
||||
write_frame.codec = &member->write_codec;
|
||||
|
||||
if (!restarting) {
|
||||
/* Start the input thread */
|
||||
launch_conference_loop_input(member, switch_core_session_get_pool(member->session));
|
||||
|
||||
|
@ -2611,9 +2583,11 @@ static void conference_loop_output(conference_member_t *member)
|
|||
switch_safe_free(cpstr);
|
||||
}
|
||||
|
||||
switch_channel_set_app_flag(channel, CF_APP_TAGGED);
|
||||
do {
|
||||
switch_ivr_sleep(member->session, 500, SWITCH_TRUE, NULL);
|
||||
} while(switch_channel_up(channel) && member->conference->originating);
|
||||
switch_channel_clear_app_flag(channel, CF_APP_TAGGED);
|
||||
|
||||
if (!switch_channel_ready(channel)) {
|
||||
member->conference->cancel_cause = SWITCH_CAUSE_ORIGINATOR_CANCEL;
|
||||
|
@ -2621,18 +2595,12 @@ static void conference_loop_output(conference_member_t *member)
|
|||
}
|
||||
|
||||
conference_member_play_file(member, "tone_stream://%(500,0,640)", 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!switch_test_flag(member->conference, CFLAG_ANSWERED)) {
|
||||
switch_channel_answer(channel);
|
||||
}
|
||||
|
||||
if (restarting) {
|
||||
switch_channel_clear_app_flag(channel, CF_APP_TAGGED);
|
||||
}
|
||||
|
||||
/* Fair WARNING, If you expect the caller to hear anything or for digit handling to be processed, */
|
||||
/* you better not block this thread loop for more than the duration of member->conference->timer_name! */
|
||||
while (switch_test_flag(member, MFLAG_RUNNING) && switch_test_flag(member, MFLAG_ITHREAD)
|
||||
|
@ -2645,11 +2613,6 @@ static void conference_loop_output(conference_member_t *member)
|
|||
|
||||
switch_mutex_lock(member->write_mutex);
|
||||
|
||||
if (switch_test_flag(member, MFLAG_RESTART)) {
|
||||
switch_mutex_unlock(member->write_mutex);
|
||||
goto top;
|
||||
}
|
||||
|
||||
if (switch_core_session_dequeue_event(member->session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
|
||||
if (event->event_id == SWITCH_EVENT_MESSAGE) {
|
||||
char *from = switch_event_get_header(event, "from");
|
||||
|
@ -2835,7 +2798,7 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th
|
|||
conference_record_t *rec = (conference_record_t *) obj;
|
||||
conference_obj_t *conference = rec->conference;
|
||||
uint32_t samples = switch_samples_per_packet(conference->rate, conference->interval);
|
||||
uint32_t low_count = 0, mux_used;
|
||||
uint32_t mux_used;
|
||||
char *vval;
|
||||
switch_timer_t timer = { 0 };
|
||||
uint32_t rlen;
|
||||
|
@ -2962,7 +2925,7 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th
|
|||
if (mux_used >= data_buf_len) {
|
||||
/* Flush the output buffer and write all the data (presumably muxed) to the file */
|
||||
switch_mutex_lock(member->audio_out_mutex);
|
||||
low_count = 0;
|
||||
//low_count = 0;
|
||||
|
||||
if ((rlen = (uint32_t) switch_buffer_read(member->mux_buffer, data_buf, data_buf_len))) {
|
||||
len = (switch_size_t) rlen / sizeof(int16_t);
|
||||
|
@ -3785,18 +3748,18 @@ static switch_status_t conf_api_sub_kick(conference_member_t *member, switch_str
|
|||
{
|
||||
switch_event_t *event;
|
||||
|
||||
if (member == NULL)
|
||||
if (member == NULL) {
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
lock_member(member);
|
||||
switch_clear_flag(member, MFLAG_RUNNING);
|
||||
switch_set_flag_locked(member, MFLAG_KICKED);
|
||||
|
||||
switch_core_session_kill_channel(member->session, SWITCH_SIG_BREAK);
|
||||
unlock_member(member);
|
||||
|
||||
if (stream != NULL) {
|
||||
stream->write_function(stream, "OK kicked %u\n", member->id);
|
||||
}
|
||||
|
||||
if (member->conference && test_eflag(member->conference, EFLAG_KICK_MEMBER)) {
|
||||
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
|
||||
conference_add_event_member_data(member, event);
|
||||
|
@ -3804,6 +3767,7 @@ static switch_status_t conf_api_sub_kick(conference_member_t *member, switch_str
|
|||
switch_event_fire(&event);
|
||||
}
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -4091,7 +4055,7 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer
|
|||
switch_channel_t *channel;
|
||||
switch_caller_profile_t *profile;
|
||||
char *uuid;
|
||||
char *name;
|
||||
//char *name;
|
||||
uint32_t count = 0;
|
||||
switch_xml_t x_tag;
|
||||
int toff = 0;
|
||||
|
@ -4104,7 +4068,7 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer
|
|||
uuid = switch_core_session_get_uuid(member->session);
|
||||
channel = switch_core_session_get_channel(member->session);
|
||||
profile = switch_channel_get_caller_profile(channel);
|
||||
name = switch_channel_get_name(channel);
|
||||
//name = switch_channel_get_name(channel);
|
||||
|
||||
|
||||
x_member = switch_xml_add_child_d(x_members, "member", moff++);
|
||||
|
@ -5661,7 +5625,7 @@ static int setup_media(conference_member_t *member, conference_obj_t *conference
|
|||
SWITCH_STANDARD_APP(conference_function)
|
||||
{
|
||||
switch_codec_t *read_codec = NULL;
|
||||
uint32_t flags = 0;
|
||||
//uint32_t flags = 0;
|
||||
conference_member_t member = { 0 };
|
||||
conference_obj_t *conference = NULL;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
@ -6049,7 +6013,7 @@ SWITCH_STANDARD_APP(conference_function)
|
|||
member.pool = switch_core_session_get_pool(session);
|
||||
|
||||
if (setup_media(&member, conference)) {
|
||||
flags = 0;
|
||||
//flags = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -6338,7 +6302,6 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c
|
|||
uint32_t announce_count = 0;
|
||||
char *maxmember_sound = NULL;
|
||||
uint32_t rate = 8000, interval = 20;
|
||||
switch_status_t status;
|
||||
int comfort_noise_level = 0;
|
||||
char *suppress_events = NULL;
|
||||
char *verbose_events = NULL;
|
||||
|
@ -6552,7 +6515,6 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c
|
|||
/* Setup a memory pool to use. */
|
||||
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n");
|
||||
status = SWITCH_STATUS_TERM;
|
||||
conference = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
@ -6561,7 +6523,6 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c
|
|||
/* Create the conference object. */
|
||||
if (!(conference = switch_core_alloc(pool, sizeof(*conference)))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
|
||||
status = SWITCH_STATUS_TERM;
|
||||
conference = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
|
|
@ -104,7 +104,6 @@ static http_data_t *do_lookup_url(switch_memory_pool_t *pool, const char *url, c
|
|||
|
||||
CURL *curl_handle = NULL;
|
||||
long httpRes = 0;
|
||||
char hostname[256] = "";
|
||||
|
||||
http_data_t *http_data = NULL;
|
||||
|
||||
|
@ -115,8 +114,6 @@ static http_data_t *do_lookup_url(switch_memory_pool_t *pool, const char *url, c
|
|||
http_data->max_bytes = 64000;
|
||||
SWITCH_STANDARD_STREAM(http_data->stream);
|
||||
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
|
||||
if (!method) {
|
||||
method = "get";
|
||||
}
|
||||
|
|
|
@ -598,7 +598,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_db_load)
|
|||
switch_limit_interface_t *limit_interface;
|
||||
|
||||
memset(&globals, 0, sizeof(&globals));
|
||||
gethostname(globals.hostname, sizeof(globals.hostname));
|
||||
strncpy(globals.hostname, switch_core_get_switchname(), sizeof(globals.hostname));
|
||||
globals.pool = pool;
|
||||
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ static switch_xml_config_int_options_t config_int_ht_0 = { SWITCH_TRUE, 0 };
|
|||
|
||||
static struct {
|
||||
switch_hash_t *profile_hash;
|
||||
char hostname[256];
|
||||
const char *hostname;
|
||||
int integer;
|
||||
int debug;
|
||||
char *dbname;
|
||||
|
@ -949,7 +949,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_directory_load)
|
|||
/* connect my internal structure to the blank pointer passed to me */
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
|
||||
gethostname(globals.hostname, sizeof(globals.hostname));
|
||||
globals.hostname = switch_core_get_switchname();
|
||||
|
||||
globals.dbname = switch_core_sprintf(pool, "directory");
|
||||
|
||||
|
|
|
@ -2298,14 +2298,14 @@ SWITCH_STANDARD_APP(record_function)
|
|||
char *path;
|
||||
switch_input_args_t args = { 0 };
|
||||
switch_file_handle_t fh = { 0 };
|
||||
int argc;
|
||||
//int argc;
|
||||
char *mydata, *argv[4] = { 0 };
|
||||
char *l = NULL;
|
||||
const char *tmp;
|
||||
int rate;
|
||||
|
||||
if (!zstr(data) && (mydata = switch_core_session_strdup(session, data))) {
|
||||
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No file specified.\n");
|
||||
return;
|
||||
|
@ -2490,7 +2490,7 @@ SWITCH_STANDARD_APP(audio_bridge_function)
|
|||
const char *transfer_on_fail = NULL;
|
||||
char *tof_data = NULL;
|
||||
char *tof_array[4] = { 0 };
|
||||
int tof_arrayc = 0;
|
||||
//int tof_arrayc = 0;
|
||||
const char *continue_on_fail = NULL, *failure_causes = NULL,
|
||||
*v_campon = NULL, *v_campon_retries, *v_campon_sleep, *v_campon_timeout, *v_campon_fallback_exten = NULL;
|
||||
switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
|
||||
|
@ -2510,7 +2510,7 @@ SWITCH_STANDARD_APP(audio_bridge_function)
|
|||
|
||||
transfer_on_fail = switch_channel_get_variable(caller_channel, "transfer_on_fail");
|
||||
tof_data = switch_core_session_strdup(session, transfer_on_fail);
|
||||
tof_arrayc = switch_split(tof_data, ' ', tof_array);
|
||||
switch_split(tof_data, ' ', tof_array);
|
||||
transfer_on_fail = tof_array[0];
|
||||
|
||||
failure_causes = switch_channel_get_variable(caller_channel, "failure_causes");
|
||||
|
|
|
@ -71,7 +71,7 @@ SWITCH_STANDARD_APP(bcast_function)
|
|||
switch_port_t rtp_port;
|
||||
char guess_ip[25];
|
||||
ls_how_t ready = SEND_TYPE_UNKNOWN;
|
||||
int argc;
|
||||
//int argc;
|
||||
char *mydata, *argv[5];
|
||||
char *mcast_ip = "224.168.168.168";
|
||||
switch_port_t mcast_port = 34567;
|
||||
|
@ -87,7 +87,7 @@ SWITCH_STANDARD_APP(bcast_function)
|
|||
mydata = switch_core_session_strdup(session, data);
|
||||
assert(mydata != NULL);
|
||||
|
||||
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
|
||||
if ((var = switch_channel_get_variable(channel, "esf_multicast_ip"))) {
|
||||
mcast_ip = switch_core_session_strdup(session, var);
|
||||
|
|
|
@ -1167,7 +1167,7 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void
|
|||
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
|
||||
switch_call_cause_t cancel_cause = 0;
|
||||
char *uuid_list = NULL;
|
||||
int connected = 0, total = 0;
|
||||
int total = 0;
|
||||
const char *codec;
|
||||
struct call_helper *rows[MAX_ROWS] = { 0 };
|
||||
int rowcount = 0;
|
||||
|
@ -1238,7 +1238,7 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void
|
|||
struct call_helper *h = cbh->rows[i];
|
||||
char *parsed = NULL;
|
||||
|
||||
switch_event_create_brackets(h->originate_string, '{', '}', ',', &ovars, &parsed);
|
||||
switch_event_create_brackets(h->originate_string, '{', '}', ',', &ovars, &parsed, SWITCH_TRUE);
|
||||
switch_event_del_header(ovars, "fifo_outbound_uuid");
|
||||
|
||||
if (!h->timeout) h->timeout = node->ring_timeout;
|
||||
|
@ -1417,8 +1417,6 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void
|
|||
goto end;
|
||||
}
|
||||
|
||||
connected = 1;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
|
||||
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
|
||||
|
@ -1513,7 +1511,6 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj)
|
|||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
switch_event_t *event = NULL;
|
||||
char *sql = NULL;
|
||||
int connected = 0;
|
||||
|
||||
if (!globals.running) return NULL;
|
||||
|
||||
|
@ -1592,8 +1589,6 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj)
|
|||
goto end;
|
||||
}
|
||||
|
||||
connected = 1;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
|
||||
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
|
||||
|
@ -3870,7 +3865,7 @@ static void extract_fifo_outbound_uuid(char *string, char *uuid, switch_size_t l
|
|||
|
||||
switch_event_create(&ovars, SWITCH_EVENT_REQUEST_PARAMS);
|
||||
|
||||
switch_event_create_brackets(string, '{', '}', ',', &ovars, &parsed);
|
||||
switch_event_create_brackets(string, '{', '}', ',', &ovars, &parsed, SWITCH_TRUE);
|
||||
|
||||
if ((fifo_outbound_uuid = switch_event_get_header(ovars, "fifo_outbound_uuid"))) {
|
||||
switch_snprintf(uuid, len, "%s", fifo_outbound_uuid);
|
||||
|
@ -3890,7 +3885,7 @@ static switch_status_t load_config(int reload, int del_all)
|
|||
switch_cache_db_handle_t *dbh = NULL;
|
||||
fifo_node_t *node;
|
||||
|
||||
gethostname(globals.hostname, sizeof(globals.hostname));
|
||||
strncpy(globals.hostname, switch_core_get_switchname(), sizeof(globals.hostname));
|
||||
|
||||
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
|
||||
|
|
|
@ -531,17 +531,34 @@ SWITCH_STANDARD_API(hash_api_function)
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define HASH_DUMP_SYNTAX "all|limit|db"
|
||||
#define HASH_DUMP_SYNTAX "all|limit|db [<realm>]"
|
||||
SWITCH_STANDARD_API(hash_dump_function)
|
||||
{
|
||||
int mode;
|
||||
switch_hash_index_t *hi;
|
||||
int argc = 0;
|
||||
char *argv[4] = { 0 };
|
||||
char *mydata = NULL;
|
||||
int realm = 0;
|
||||
char *realmvalue = NULL;
|
||||
|
||||
if (zstr(cmd)) {
|
||||
if (!zstr(cmd)) {
|
||||
mydata = strdup(cmd);
|
||||
switch_assert(mydata);
|
||||
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
} else {
|
||||
realmvalue = "test";
|
||||
realm = 0;
|
||||
stream->write_function(stream, "Usage: "HASH_DUMP_SYNTAX"\n");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cmd = strdup(argv[0]);
|
||||
if (argc == 2) {
|
||||
realm = 1;
|
||||
realmvalue = switch_mprintf("%s_", argv[1]);
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "all")) {
|
||||
mode = 3;
|
||||
} else if (!strcmp(cmd, "limit")) {
|
||||
|
@ -553,7 +570,6 @@ SWITCH_STANDARD_API(hash_dump_function)
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
if (mode & 1) {
|
||||
switch_thread_rwlock_rdlock(globals.limit_hash_rwlock);
|
||||
for (hi = switch_hash_first(NULL, globals.limit_hash); hi; hi = switch_hash_next(hi)) {
|
||||
|
@ -577,9 +593,14 @@ SWITCH_STANDARD_API(hash_dump_function)
|
|||
const void *key;
|
||||
switch_ssize_t keylen;
|
||||
switch_hash_this(hi, &key, &keylen, &val);
|
||||
|
||||
if (realm) {
|
||||
if (strstr(key, realmvalue)) {
|
||||
stream->write_function(stream, "D/%s/%s\n", key, (char*)val);
|
||||
}
|
||||
} else {
|
||||
stream->write_function(stream, "D/%s/%s\n", key, (char*)val);
|
||||
}
|
||||
}
|
||||
switch_thread_rwlock_unlock(globals.db_hash_rwlock);
|
||||
}
|
||||
|
||||
|
@ -590,7 +611,7 @@ SWITCH_STANDARD_API(hash_dump_function)
|
|||
#define HASH_REMOTE_SYNTAX "list|kill [name]|rescan"
|
||||
SWITCH_STANDARD_API(hash_remote_function)
|
||||
{
|
||||
int argc;
|
||||
//int argc;
|
||||
char *argv[10];
|
||||
char *dup = NULL;
|
||||
|
||||
|
@ -601,7 +622,7 @@ SWITCH_STANDARD_API(hash_remote_function)
|
|||
|
||||
dup = strdup(cmd);
|
||||
|
||||
argc = switch_split(dup, ' ', argv);
|
||||
switch_split(dup, ' ', argv);
|
||||
if (argv[0] && !strcmp(argv[0], "list")) {
|
||||
switch_hash_index_t *hi;
|
||||
stream->write_function(stream, "Remote connections:\nName\t\t\tState\n");
|
||||
|
|
|
@ -565,12 +565,11 @@ switch_status_t ladspa_session(switch_core_session_t *session, const char *flags
|
|||
static void ladspa_parse(switch_core_session_t *session, const char *data)
|
||||
{
|
||||
char *argv[5] = { 0 };
|
||||
int argc;
|
||||
char *lbuf;
|
||||
|
||||
if (data) {
|
||||
lbuf = strdup(data);
|
||||
argc = switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
ladspa_session(session, argv[0], argv[1], argv[2], argv[3]);
|
||||
free(lbuf);
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ struct callback_obj {
|
|||
profile_t *profile;
|
||||
switch_core_session_t *session;
|
||||
switch_event_t *event;
|
||||
float sell_rate;
|
||||
float max_rate;
|
||||
};
|
||||
typedef struct callback_obj callback_t;
|
||||
|
||||
|
@ -248,14 +248,13 @@ static char *get_bridge_data(switch_memory_pool_t *pool, char *dialed_number, ch
|
|||
size_t tstrip;
|
||||
char *data = NULL;
|
||||
char *destination_number = NULL;
|
||||
char *orig_destination_number = NULL;
|
||||
char *codec = NULL;
|
||||
char *cid = NULL;
|
||||
char *header = NULL;
|
||||
char *user_rate = NULL;
|
||||
char *export_fields = NULL;
|
||||
|
||||
orig_destination_number = destination_number = switch_core_strdup(pool, dialed_number);
|
||||
destination_number = switch_core_strdup(pool, dialed_number);
|
||||
|
||||
tstrip = ((cur_route->digit_len - cur_route->tstrip) + 1);
|
||||
lstrip = cur_route->lstrip;
|
||||
|
@ -622,6 +621,9 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
|
|||
} else if (CF("lcr_carrier_name")) {
|
||||
additional->carrier_name = switch_core_strdup(pool, switch_str_nil(argv[i]));
|
||||
} else if (CF("lcr_rate_field")) {
|
||||
if (!argv[i] || zstr(argv[i])) {
|
||||
goto end;
|
||||
}
|
||||
additional->rate = (float)atof(switch_str_nil(argv[i]));
|
||||
additional->rate_str = switch_core_sprintf(pool, "%0.5f", additional->rate);
|
||||
} else if (CF("lcr_gw_prefix")) {
|
||||
|
@ -669,8 +671,10 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
|
|||
|
||||
|
||||
for (current = cbt->head; current; current = current->next) {
|
||||
if (cbt->sell_rate && cbt->sell_rate > current->rate) {
|
||||
continue;
|
||||
if (cbt->max_rate && (cbt->max_rate < additional->rate)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Skipping [%s] because [%f] is higher than the max_rate of [%f]\n",
|
||||
additional->carrier_name, additional->rate, cbt->max_rate);
|
||||
break;
|
||||
}
|
||||
|
||||
key = switch_core_sprintf(pool, "%s:%s", additional->gw_prefix, additional->gw_suffix);
|
||||
|
@ -852,9 +856,9 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct)
|
|||
if (cb_struct->session) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "we have a session\n");
|
||||
if ((channel = switch_core_session_get_channel(cb_struct->session))) {
|
||||
const char *sell_rate = switch_channel_get_variable(channel, "sell_rate");
|
||||
if (!zstr(sell_rate)) {
|
||||
cb_struct->sell_rate = atof(sell_rate);
|
||||
const char *max_rate = switch_channel_get_variable(channel, "max_rate");
|
||||
if (!zstr(max_rate)) {
|
||||
cb_struct->max_rate = atof(max_rate);
|
||||
}
|
||||
switch_channel_set_variable_var_check(channel, "lcr_rate_field", rate_field, SWITCH_FALSE);
|
||||
switch_channel_set_variable_var_check(channel, "lcr_user_rate_field", user_rate_field, SWITCH_FALSE);
|
||||
|
@ -1258,7 +1262,6 @@ static switch_call_cause_t lcr_outgoing_channel(switch_core_session_t *session,
|
|||
const char *intralata = NULL;
|
||||
switch_core_session_t *mysession = NULL;
|
||||
switch_channel_t *channel = NULL;
|
||||
switch_caller_profile_t *caller_profile = NULL;
|
||||
|
||||
dest = strdup(outbound_profile->destination_number);
|
||||
|
||||
|
@ -1285,7 +1288,6 @@ static switch_call_cause_t lcr_outgoing_channel(switch_core_session_t *session,
|
|||
timelimit = atoi(var);
|
||||
}
|
||||
routes.session = session;
|
||||
caller_profile = switch_channel_get_caller_profile(channel);
|
||||
intrastate = switch_channel_get_variable(channel, "intrastate");
|
||||
intralata = switch_channel_get_variable(channel, "intralata");
|
||||
cid_name_override = switch_channel_get_variable(channel, "origination_caller_id_name");
|
||||
|
@ -1665,7 +1667,7 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
|
|||
char *argv[4] = { 0 };
|
||||
int argc;
|
||||
char *mydata = NULL;
|
||||
char *dialstring = NULL;
|
||||
//char *dialstring = NULL;
|
||||
char *lcr_profile = NULL;
|
||||
lcr_route current = NULL;
|
||||
max_obj_t maximum_lengths = { 0 };
|
||||
|
@ -1787,7 +1789,8 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
|
|||
current = cb_struct.head;
|
||||
while (current) {
|
||||
|
||||
dialstring = get_bridge_data(pool, cb_struct.lookup_number, cb_struct.cid, current, cb_struct.profile, cb_struct.session);
|
||||
//dialstring =
|
||||
get_bridge_data(pool, cb_struct.lookup_number, cb_struct.cid, current, cb_struct.profile, cb_struct.session);
|
||||
rowcount++;
|
||||
|
||||
if (as_xml) {
|
||||
|
|
|
@ -399,7 +399,7 @@ static switch_status_t do_billing(switch_core_session_t *session)
|
|||
const char *billrate;
|
||||
const char *billaccount;
|
||||
float nobal_amt = globals.nobal_amt;
|
||||
float lowbal_amt = globals.lowbal_amt;
|
||||
//float lowbal_amt = globals.lowbal_amt;
|
||||
float balance;
|
||||
|
||||
if (!session) {
|
||||
|
@ -421,10 +421,11 @@ static switch_status_t do_billing(switch_core_session_t *session)
|
|||
if (!zstr(switch_channel_get_variable(channel, "nobal_amt"))) {
|
||||
nobal_amt = (float)atof(switch_channel_get_variable(channel, "nobal_amt"));
|
||||
}
|
||||
/*
|
||||
if (!zstr(switch_channel_get_variable(channel, "lowbal_amt"))) {
|
||||
lowbal_amt = (float)atof(switch_channel_get_variable(channel, "lowbal_amt"));
|
||||
}
|
||||
|
||||
*/
|
||||
/* Return if there's no billing information on this session */
|
||||
if (!billrate || !billaccount) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
@ -802,9 +803,6 @@ SWITCH_STANDARD_API(nibblebill_api_function)
|
|||
if ((argc == 2 || argc == 3) && !zstr(argv[0])) {
|
||||
char *uuid = argv[0];
|
||||
if ((psession = switch_core_session_locate(uuid))) {
|
||||
switch_channel_t *channel;
|
||||
channel = switch_core_session_get_channel(psession);
|
||||
|
||||
if (!strcasecmp(argv[1], "adjust") && argc == 3) {
|
||||
nibblebill_adjust(psession, (float) atof(argv[2]));
|
||||
} else if (!strcasecmp(argv[1], "flush")) {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
BASE=../../../..
|
||||
LOCAL_OBJS=ivr.o util.o config.o menu.o
|
||||
include $(BASE)/build/modmake.rules
|
|
@ -0,0 +1,130 @@
|
|||
/* Copy paste from FS mod_voicemail */
|
||||
#include <switch.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
const char *global_cf = "protovm.conf";
|
||||
|
||||
void populate_profile_menu_event(vmivr_profile_t *profile, vmivr_menu_profile_t *menu) {
|
||||
switch_xml_t cfg, xml, x_profiles, x_profile, x_keys, x_phrases, x_menus, x_menu;
|
||||
|
||||
free_profile_menu_event(menu);
|
||||
|
||||
if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf);
|
||||
goto end;
|
||||
}
|
||||
if (!(x_profiles = switch_xml_child(cfg, "profiles"))) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((x_profile = switch_xml_find_child(x_profiles, "profile", "name", profile->name))) {
|
||||
if ((x_menus = switch_xml_child(x_profile, "menus"))) {
|
||||
if ((x_menu = switch_xml_find_child(x_menus, "menu", "name", menu->name))) {
|
||||
if ((x_keys = switch_xml_child(x_menu, "keys"))) {
|
||||
switch_event_import_xml(switch_xml_child(x_keys, "key"), "dtmf", "action", &menu->event_keys_dtmf);
|
||||
switch_event_import_xml(switch_xml_child(x_keys, "key"), "action", "dtmf", &menu->event_keys_action);
|
||||
switch_event_import_xml(switch_xml_child(x_keys, "key"), "action", "variable", &menu->event_keys_varname);
|
||||
}
|
||||
if ((x_phrases = switch_xml_child(x_menu, "phrases"))) {
|
||||
switch_event_import_xml(switch_xml_child(x_phrases, "phrase"), "name", "value", &menu->event_phrases);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end:
|
||||
if (xml)
|
||||
switch_xml_free(xml);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
void free_profile_menu_event(vmivr_menu_profile_t *menu) {
|
||||
if (menu->event_keys_dtmf) {
|
||||
switch_event_destroy(&menu->event_keys_dtmf);
|
||||
}
|
||||
if (menu->event_keys_action) {
|
||||
switch_event_destroy(&menu->event_keys_action);
|
||||
}
|
||||
if (menu->event_keys_varname) {
|
||||
switch_event_destroy(&menu->event_keys_varname);
|
||||
}
|
||||
|
||||
if (menu->event_phrases) {
|
||||
switch_event_destroy(&menu->event_phrases);
|
||||
}
|
||||
}
|
||||
|
||||
vmivr_profile_t *get_profile(switch_core_session_t *session, const char *profile_name)
|
||||
{
|
||||
vmivr_profile_t *profile = NULL;
|
||||
switch_xml_t cfg, xml, x_profiles, x_profile, x_apis, param;
|
||||
|
||||
if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf);
|
||||
return profile;
|
||||
}
|
||||
if (!(x_profiles = switch_xml_child(cfg, "profiles"))) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((x_profile = switch_xml_find_child(x_profiles, "profile", "name", profile_name))) {
|
||||
if (!(profile = switch_core_session_alloc(session, sizeof(vmivr_profile_t)))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Alloc Failure\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
profile->name = profile_name;
|
||||
|
||||
/* TODO Make the following configurable */
|
||||
profile->api_profile = profile->name;
|
||||
profile->menu_check_auth = "std_authenticate";
|
||||
profile->menu_check_main = "std_navigator";
|
||||
profile->menu_check_terminate = "std_purge";
|
||||
|
||||
if ((x_apis = switch_xml_child(x_profile, "apis"))) {
|
||||
int total_options = 0;
|
||||
int total_invalid_options = 0;
|
||||
for (param = switch_xml_child(x_apis, "api"); param; param = param->next) {
|
||||
char *var, *val;
|
||||
if ((var = (char *) switch_xml_attr_soft(param, "name")) && (val = (char *) switch_xml_attr_soft(param, "value"))) {
|
||||
if (!strcasecmp(var, "msg_undelete") && !profile->api_msg_undelete)
|
||||
profile->api_msg_undelete = switch_core_session_strdup(session, val);
|
||||
else if (!strcasecmp(var, "msg_delete") && !profile->api_msg_delete)
|
||||
profile->api_msg_delete = switch_core_session_strdup(session, val);
|
||||
else if (!strcasecmp(var, "msg_list") && !profile->api_msg_list)
|
||||
profile->api_msg_list = switch_core_session_strdup(session, val);
|
||||
else if (!strcasecmp(var, "msg_count") && !profile->api_msg_count)
|
||||
profile->api_msg_count = switch_core_session_strdup(session, val);
|
||||
else if (!strcasecmp(var, "msg_save") && !profile->api_msg_save)
|
||||
profile->api_msg_save = switch_core_session_strdup(session, val);
|
||||
else if (!strcasecmp(var, "msg_purge") && !profile->api_msg_purge)
|
||||
profile->api_msg_purge = switch_core_session_strdup(session, val);
|
||||
else if (!strcasecmp(var, "msg_get") && !profile->api_msg_get)
|
||||
profile->api_msg_get = switch_core_session_strdup(session, val);
|
||||
else if (!strcasecmp(var, "pref_greeting_set") && !profile->api_pref_greeting_set)
|
||||
profile->api_pref_greeting_set = switch_core_session_strdup(session, val);
|
||||
else if (!strcasecmp(var, "pref_recname_set") && !profile->api_pref_recname_set)
|
||||
profile->api_pref_recname_set = switch_core_session_strdup(session, val);
|
||||
else if (!strcasecmp(var, "pref_password_set") && !profile->api_pref_password_set)
|
||||
profile->api_pref_password_set = switch_core_session_strdup(session, val);
|
||||
else if (!strcasecmp(var, "auth_login") && !profile->api_auth_login)
|
||||
profile->api_auth_login = switch_core_session_strdup(session, val);
|
||||
else
|
||||
total_invalid_options++;
|
||||
total_options++;
|
||||
}
|
||||
}
|
||||
if (total_options - total_invalid_options != 11) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing api definition for profile '%s'\n", profile_name);
|
||||
profile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
end:
|
||||
switch_xml_free(xml);
|
||||
return profile;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
extern const char *global_cf;
|
||||
|
||||
struct vmivr_profile {
|
||||
const char *name;
|
||||
|
||||
const char *domain;
|
||||
const char *id;
|
||||
|
||||
const char *menu_check_auth;
|
||||
const char *menu_check_main;
|
||||
const char *menu_check_terminate;
|
||||
|
||||
switch_bool_t authorized;
|
||||
|
||||
const char *api_profile;
|
||||
const char *api_auth_login;
|
||||
const char *api_msg_delete;
|
||||
const char *api_msg_undelete;
|
||||
const char *api_msg_list;
|
||||
const char *api_msg_count;
|
||||
const char *api_msg_save;
|
||||
const char *api_msg_purge;
|
||||
const char *api_msg_get;
|
||||
const char *api_pref_greeting_set;
|
||||
const char *api_pref_recname_set;
|
||||
const char *api_pref_password_set;
|
||||
|
||||
};
|
||||
typedef struct vmivr_profile vmivr_profile_t;
|
||||
|
||||
struct vmivr_menu_profile {
|
||||
const char *name;
|
||||
|
||||
switch_event_t *event_keys_action;
|
||||
switch_event_t *event_keys_dtmf;
|
||||
switch_event_t *event_keys_varname;
|
||||
switch_event_t *event_phrases;
|
||||
};
|
||||
typedef struct vmivr_menu_profile vmivr_menu_profile_t;
|
||||
|
||||
vmivr_profile_t *get_profile(switch_core_session_t *session, const char *profile_name);
|
||||
|
||||
void free_profile_menu_event(vmivr_menu_profile_t *menu);
|
||||
void populate_profile_menu_event(vmivr_profile_t *profile, vmivr_menu_profile_t *menu);
|
||||
|
||||
#endif /* _CONFIG_H_ */
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2011, 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):
|
||||
*
|
||||
* Marc Olivier Chouinard <mochouinard@moctel.com>
|
||||
*
|
||||
*
|
||||
* ivr.c -- MT IVR System Interface
|
||||
*
|
||||
*/
|
||||
|
||||
#include <switch.h>
|
||||
|
||||
#include "ivr.h"
|
||||
|
||||
int match_dtmf(switch_core_session_t *session, dtmf_ss_t *loc) {
|
||||
switch_bool_t is_invalid[128] = { SWITCH_FALSE };
|
||||
int i;
|
||||
loc->potentialMatch = NULL;
|
||||
loc->completeMatch = NULL;
|
||||
loc->potentialMatchCount = 0;
|
||||
|
||||
for (i = 0; i < loc->dtmf_received; i++) {
|
||||
int j;
|
||||
loc->potentialMatchCount = 0;
|
||||
for (j = 0; !zstr(loc->dtmf_accepted[j]) && j < 128; j++) {
|
||||
switch_bool_t cMatch = SWITCH_FALSE;
|
||||
char test[2] = { 0 };
|
||||
|
||||
if (is_invalid[j])
|
||||
continue;
|
||||
|
||||
test[0] = loc->dtmf_stored[i];
|
||||
if (loc->dtmf_accepted[j][i] == 'N' && atoi(test) >= 2 && atoi(test) <= 9)
|
||||
cMatch = SWITCH_TRUE;
|
||||
if (loc->dtmf_accepted[j][i] == 'X' && atoi(test) >= 0 && atoi(test) <= 9) {
|
||||
cMatch = SWITCH_TRUE;
|
||||
}
|
||||
if (i >= strlen(loc->dtmf_accepted[j]) - 1 && loc->dtmf_accepted[j][strlen(loc->dtmf_accepted[j])-1] == '.')
|
||||
cMatch = SWITCH_TRUE;
|
||||
if (loc->dtmf_accepted[j][i] == loc->dtmf_stored[i])
|
||||
cMatch = SWITCH_TRUE;
|
||||
|
||||
if (cMatch == SWITCH_FALSE) {
|
||||
is_invalid[j] = SWITCH_TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i == strlen(loc->dtmf_accepted[j]) - 1 && loc->dtmf_accepted[j][strlen(loc->dtmf_accepted[j])-1] == '.') {
|
||||
loc->completeMatch = loc->dtmf_accepted[j];
|
||||
}
|
||||
if (i == loc->dtmf_received - 1 && loc->dtmf_received == strlen(loc->dtmf_accepted[j]) && loc->dtmf_accepted[j][strlen(loc->dtmf_accepted[j])-1] != '.') {
|
||||
loc->completeMatch = loc->dtmf_accepted[j];
|
||||
continue;
|
||||
}
|
||||
loc->potentialMatchCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static switch_status_t cb_on_dtmf_ignore(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
|
||||
{
|
||||
switch (itype) {
|
||||
case SWITCH_INPUT_TYPE_DTMF:
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
|
||||
switch_channel_queue_dtmf(channel, dtmf);
|
||||
return SWITCH_STATUS_BREAK;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t cb_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
|
||||
{
|
||||
dtmf_ss_t *loc = (dtmf_ss_t*) buf;
|
||||
|
||||
switch (itype) {
|
||||
case SWITCH_INPUT_TYPE_DTMF:
|
||||
{
|
||||
switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
|
||||
switch_bool_t audio_was_stopped = loc->audio_stopped;
|
||||
loc->audio_stopped = SWITCH_TRUE;
|
||||
|
||||
if (loc->dtmf_received >= sizeof(loc->dtmf_stored)) {
|
||||
loc->result = RES_BUFFER_OVERFLOW;
|
||||
break;
|
||||
}
|
||||
if (!loc->terminate_key || dtmf->digit != loc->terminate_key)
|
||||
loc->dtmf_stored[loc->dtmf_received++] = dtmf->digit;
|
||||
|
||||
match_dtmf(session, loc);
|
||||
|
||||
if (loc->terminate_key && dtmf->digit == loc->terminate_key && loc->result == RES_WAITFORMORE) {
|
||||
if (loc->potentialMatchCount == 1 && loc->completeMatch != NULL) {
|
||||
loc->result = RES_FOUND;
|
||||
} else {
|
||||
loc->result = RES_INVALID;
|
||||
}
|
||||
return SWITCH_STATUS_BREAK;
|
||||
} else {
|
||||
if (loc->potentialMatchCount == 0 && loc->completeMatch != NULL) {
|
||||
loc->result = RES_FOUND;
|
||||
return SWITCH_STATUS_BREAK;
|
||||
} else if (loc->potentialMatchCount > 0) {
|
||||
loc->result = RES_WAITFORMORE;
|
||||
if (!audio_was_stopped)
|
||||
return SWITCH_STATUS_BREAK;
|
||||
} else {
|
||||
loc->result = RES_INVALID;
|
||||
return SWITCH_STATUS_BREAK;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t captureMenuInitialize(dtmf_ss_t *loc, char **dtmf_accepted) {
|
||||
int i;
|
||||
|
||||
memset(loc, 0, sizeof(*loc));
|
||||
|
||||
for (i = 0; dtmf_accepted[i] && i < 16; i++) {
|
||||
strncpy(loc->dtmf_accepted[i], dtmf_accepted[i], 128);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t playbackBufferDTMF(switch_core_session_t *session, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout) {
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
if (switch_channel_ready(channel)) {
|
||||
switch_input_args_t args = { 0 };
|
||||
|
||||
args.input_callback = cb_on_dtmf_ignore;
|
||||
|
||||
if (macro_name) {
|
||||
status = switch_ivr_phrase_macro_event(session, macro_name, data, event, lang, &args);
|
||||
}
|
||||
} else {
|
||||
status = SWITCH_STATUS_BREAK;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
switch_status_t captureMenu(switch_core_session_t *session, dtmf_ss_t *loc, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout) {
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
if (switch_channel_ready(channel)) {
|
||||
switch_input_args_t args = { 0 };
|
||||
|
||||
args.input_callback = cb_on_dtmf;
|
||||
args.buf = loc;
|
||||
|
||||
if (macro_name && loc->audio_stopped == SWITCH_FALSE && loc->result == RES_WAITFORMORE) {
|
||||
status = switch_ivr_phrase_macro_event(session, macro_name, data, event, lang, &args);
|
||||
}
|
||||
|
||||
if (switch_channel_ready(channel) && (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK) && timeout && loc->result == RES_WAITFORMORE) {
|
||||
loc->audio_stopped = SWITCH_TRUE;
|
||||
switch_ivr_collect_digits_callback(session, &args, timeout, 0);
|
||||
if (loc->result == RES_WAITFORMORE) {
|
||||
if (loc->potentialMatchCount == 1 && loc->completeMatch != NULL) {
|
||||
loc->result = RES_FOUND;
|
||||
} else {
|
||||
loc->result = RES_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status = SWITCH_STATUS_BREAK;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
switch_status_t captureMenuRecord(switch_core_session_t *session, dtmf_ss_t *loc, switch_event_t *event, const char *file_path, switch_file_handle_t *fh, int max_record_len) {
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
if (switch_channel_ready(channel)) {
|
||||
switch_input_args_t args = { 0 };
|
||||
|
||||
args.input_callback = cb_on_dtmf;
|
||||
args.buf = loc;
|
||||
|
||||
if (loc->audio_stopped == SWITCH_FALSE && loc->result == RES_WAITFORMORE) {
|
||||
loc->recorded_audio = SWITCH_TRUE;
|
||||
status = switch_ivr_record_file(session, fh, file_path, &args, max_record_len);
|
||||
|
||||
}
|
||||
if (loc->result == RES_WAITFORMORE) {
|
||||
loc->result = RES_TIMEOUT;
|
||||
}
|
||||
|
||||
} else {
|
||||
status = SWITCH_STATUS_BREAK;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
*/
|
|
@ -0,0 +1,30 @@
|
|||
struct dtmf_ss {
|
||||
char dtmf_stored[128];
|
||||
int dtmf_received;
|
||||
char dtmf_accepted[16][128];
|
||||
int result;
|
||||
switch_bool_t audio_stopped;
|
||||
switch_bool_t recorded_audio;
|
||||
const char *potentialMatch;
|
||||
int potentialMatchCount;
|
||||
const char *completeMatch;
|
||||
char terminate_key;
|
||||
};
|
||||
typedef struct dtmf_ss dtmf_ss_t;
|
||||
|
||||
#define RES_WAITFORMORE 0
|
||||
#define RES_FOUND 1
|
||||
#define RES_INVALID 3
|
||||
#define RES_TIMEOUT 4
|
||||
#define RES_BREAK 5
|
||||
#define RES_RECORD 6
|
||||
#define RES_BUFFER_OVERFLOW 99
|
||||
|
||||
#define MAX_DTMF_SIZE_OPTION 32
|
||||
|
||||
switch_status_t captureMenu(switch_core_session_t *session, dtmf_ss_t *loc, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout);
|
||||
switch_status_t captureMenuRecord(switch_core_session_t *session, dtmf_ss_t *loc, switch_event_t *event, const char *file_path, switch_file_handle_t *fh, int max_record_len);
|
||||
switch_status_t captureMenuInitialize(dtmf_ss_t *loc, char **dtmf_accepted);
|
||||
|
||||
switch_status_t playbackBufferDTMF(switch_core_session_t *session, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout);
|
||||
|
|
@ -0,0 +1,599 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2011, 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):
|
||||
*
|
||||
* Marc Olivier Chouinard <mochouinard@moctel.com>
|
||||
*
|
||||
*
|
||||
* menu.c -- VoiceMail Menu
|
||||
*
|
||||
*/
|
||||
#include <switch.h>
|
||||
|
||||
#include "ivr.h"
|
||||
#include "menu.h"
|
||||
#include "util.h"
|
||||
#include "config.h"
|
||||
|
||||
/* List of available menu */
|
||||
vmivr_menu_function_t menu_list[] = {
|
||||
{"std_authenticate", mtvm_menu_authenticate},
|
||||
{"std_navigator", mtvm_menu_main},
|
||||
{"std_record_name", mtvm_menu_record_name},
|
||||
{"std_set_password", mtvm_menu_set_password},
|
||||
{"std_select_greeting_slot", mtvm_menu_select_greeting_slot},
|
||||
{"std_record_greeting_with_slot", mtvm_menu_record_greeting_with_slot},
|
||||
{"std_preference", mtvm_menu_preference},
|
||||
{"std_purge", mtvm_menu_purge},
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#define MAX_ATTEMPT 3 /* TODO Make these fields configurable */
|
||||
#define DEFAULT_IVR_TIMEOUT 3000
|
||||
|
||||
void mtvm_menu_purge(switch_core_session_t *session, vmivr_profile_t *profile) {
|
||||
if (profile->id && profile->authorized) {
|
||||
if (1==1 /* TODO make Purge email on exit optional ??? */) {
|
||||
const char *cmd = switch_core_session_sprintf(session, "%s %s %s", profile->api_profile, profile->domain, profile->id);
|
||||
mt_api_execute(session, profile->api_msg_purge, cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
void mtvm_menu_main(switch_core_session_t *session, vmivr_profile_t *profile) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_event_t *msg_list_params = NULL;
|
||||
size_t msg_count = 0;
|
||||
size_t current_msg = 1;
|
||||
size_t next_msg = current_msg;
|
||||
size_t previous_msg = current_msg;
|
||||
char *cmd = NULL;
|
||||
int retry;
|
||||
|
||||
/* Different switch to control playback of phrases */
|
||||
switch_bool_t initial_count_played = SWITCH_FALSE;
|
||||
switch_bool_t skip_header = SWITCH_FALSE;
|
||||
switch_bool_t msg_deleted = SWITCH_FALSE;
|
||||
switch_bool_t msg_undeleted = SWITCH_FALSE;
|
||||
switch_bool_t msg_saved = SWITCH_FALSE;
|
||||
|
||||
vmivr_menu_profile_t menu = { "std_navigator" };
|
||||
|
||||
/* Initialize Menu Configs */
|
||||
populate_profile_menu_event(profile, &menu);
|
||||
|
||||
if (!menu.event_keys_dtmf || !menu.event_phrases) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get VoiceMail List And update msg count */
|
||||
cmd = switch_core_session_sprintf(session, "json %s %s %s", profile->api_profile, profile->domain, profile->id);
|
||||
msg_list_params = jsonapi2event(session, NULL, profile->api_msg_list, cmd);
|
||||
msg_count = atol(switch_event_get_header(msg_list_params,"VM-List-Count"));
|
||||
|
||||
/* TODO Add Detection of new message and notify the user */
|
||||
|
||||
for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
|
||||
dtmf_ss_t loc;
|
||||
char *dtmfa[16] = { 0 };
|
||||
switch_event_t *phrase_params = NULL;
|
||||
|
||||
switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS);
|
||||
|
||||
append_event_profile(phrase_params, profile, menu);
|
||||
|
||||
populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa);
|
||||
|
||||
previous_msg = current_msg;
|
||||
|
||||
/* Simple Protection to not go out of msg list scope */
|
||||
/* TODO: Add Prompt to notify they reached the begining or the end */
|
||||
if (next_msg == 0) {
|
||||
next_msg = 1;
|
||||
} else if (next_msg > msg_count) {
|
||||
next_msg = msg_count;
|
||||
}
|
||||
|
||||
current_msg = next_msg;
|
||||
|
||||
captureMenuInitialize(&loc, dtmfa);
|
||||
|
||||
/* Prompt related to previous Message here */
|
||||
append_event_message(session, profile, phrase_params, msg_list_params, previous_msg);
|
||||
if (msg_deleted) {
|
||||
msg_deleted = SWITCH_FALSE;
|
||||
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "deleted", phrase_params, NULL, 0);
|
||||
}
|
||||
if (msg_undeleted) {
|
||||
msg_undeleted = SWITCH_FALSE;
|
||||
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "undeleted", phrase_params, NULL, 0);
|
||||
}
|
||||
if (msg_saved) {
|
||||
msg_saved = SWITCH_FALSE;
|
||||
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "saved", phrase_params, NULL, 0);
|
||||
}
|
||||
|
||||
/* Prompt related the current message */
|
||||
append_event_message(session, profile, phrase_params, msg_list_params, current_msg);
|
||||
|
||||
/* TODO check if msg is gone (purged by another session, notify user and auto jump to next message or something) */
|
||||
if (!skip_header) {
|
||||
if (!initial_count_played) {
|
||||
cmd = switch_core_session_sprintf(session, "json %s %s %s", profile->api_profile, profile->domain, profile->id);
|
||||
jsonapi2event(session, phrase_params, profile->api_msg_count, cmd);
|
||||
initial_count_played = SWITCH_TRUE;
|
||||
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "msg_count"), NULL, phrase_params, NULL, 0);
|
||||
}
|
||||
if (msg_count > 0) {
|
||||
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "say_msg_number"), NULL, phrase_params, NULL, 0);
|
||||
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "say_date"), NULL, phrase_params, NULL, 0);
|
||||
}
|
||||
}
|
||||
if (msg_count > 0) {
|
||||
/* TODO Update the Read date of a message (When msg start, or when it listen compleatly ??? To be determined */
|
||||
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "play_message"), NULL, phrase_params, NULL, 0);
|
||||
}
|
||||
skip_header = SWITCH_FALSE;
|
||||
|
||||
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
|
||||
|
||||
if (loc.result == RES_TIMEOUT) {
|
||||
/* TODO Ask for the prompt Again IF retry != 0 */
|
||||
} else if (loc.result == RES_INVALID) {
|
||||
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
|
||||
} else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */
|
||||
const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored);
|
||||
|
||||
/* Reset the try count */
|
||||
retry = MAX_ATTEMPT;
|
||||
|
||||
if (action) {
|
||||
if (!strcasecmp(action, "skip_intro")) { /* Skip Header / Play the recording again */
|
||||
skip_header = SWITCH_TRUE;
|
||||
} else if (!strcasecmp(action, "next_msg")) { /* Next Message */
|
||||
next_msg++;
|
||||
} else if (!strcasecmp(action, "prev_msg")) { /* Previous Message */
|
||||
next_msg--;
|
||||
} else if (!strcasecmp(action, "delete_msg")) { /* Delete / Undelete Message */
|
||||
if (strncasecmp(switch_event_get_header(phrase_params, "VM-Message-Flags"), "delete", 6)) {
|
||||
cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID"));
|
||||
mt_api_execute(session, profile->api_msg_delete, cmd);
|
||||
|
||||
msg_deleted = SWITCH_TRUE;
|
||||
/* TODO Option for auto going to next message or just return to the menu (So user used to do 76 to delete and next message wont be confused) */
|
||||
next_msg++;
|
||||
} else {
|
||||
cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID"));
|
||||
mt_api_execute(session, profile->api_msg_undelete, cmd);
|
||||
|
||||
msg_undeleted = SWITCH_TRUE;
|
||||
}
|
||||
} else if (!strcasecmp(action, "save_msg")) { /* Save Message */
|
||||
cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID"));
|
||||
mt_api_execute(session, profile->api_msg_save, cmd);
|
||||
|
||||
msg_saved = SWITCH_TRUE;
|
||||
} else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */
|
||||
void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(action+5);
|
||||
if (fPtr) {
|
||||
fPtr(session, profile);
|
||||
}
|
||||
} else if (!strcasecmp(action, "return")) { /* Return */
|
||||
retry = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* IF the API to get the message returned us a COPY of the file locally (temp file create from a DB or from a web server), delete it */
|
||||
if (switch_true(switch_event_get_header(phrase_params, "VM-Message-Private-Local-Copy"))) {
|
||||
const char *file_path = switch_event_get_header(phrase_params, "VM-Message-File-Path");
|
||||
if (file_path && unlink(file_path) != 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to delete temp file [%s]\n", file_path);
|
||||
}
|
||||
}
|
||||
switch_event_destroy(&phrase_params);
|
||||
}
|
||||
|
||||
switch_event_destroy(&msg_list_params);
|
||||
|
||||
free_profile_menu_event(&menu);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void mtvm_menu_record_name(switch_core_session_t *session, vmivr_profile_t *profile) {
|
||||
switch_status_t status;
|
||||
vmivr_menu_profile_t menu = { "std_record_name" };
|
||||
|
||||
char *tmp_filepath = generate_random_file_name(session, "protovm", "wav" /* TODO make it configurable */);
|
||||
|
||||
/* Initialize Menu Configs */
|
||||
populate_profile_menu_event(profile, &menu);
|
||||
|
||||
status = mtvm_menu_record(session, profile, menu, tmp_filepath);
|
||||
|
||||
if (status == SWITCH_STATUS_SUCCESS) {
|
||||
char *cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, tmp_filepath);
|
||||
mt_api_execute(session, profile->api_pref_recname_set, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void mtvm_menu_set_password(switch_core_session_t *session, vmivr_profile_t *profile) {
|
||||
char *password;
|
||||
vmivr_menu_profile_t menu = { "std_set_password" };
|
||||
|
||||
password = mtvm_menu_get_input_set(session, profile, menu, "XXX." /* TODO Conf Min 3 Digit */, "#" /* TODO Conf terminate input key */);
|
||||
|
||||
/* TODO Add Prompts to tell if password was set and if it was not */
|
||||
if (password) {
|
||||
char *cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, password);
|
||||
mt_api_execute(session, profile->api_pref_password_set, cmd);
|
||||
}
|
||||
|
||||
free_profile_menu_event(&menu);
|
||||
}
|
||||
|
||||
void mtvm_menu_authenticate(switch_core_session_t *session, vmivr_profile_t *profile) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
vmivr_menu_profile_t menu = { "std_authenticate" };
|
||||
int retry;
|
||||
const char *auth_var = NULL;
|
||||
/* Initialize Menu Configs */
|
||||
populate_profile_menu_event(profile, &menu);
|
||||
|
||||
if (profile->id && (auth_var = switch_channel_get_variable(channel, "voicemail_authorized")) && switch_true(auth_var)) {
|
||||
profile->authorized = SWITCH_TRUE;
|
||||
}
|
||||
|
||||
for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0 && profile->authorized == SWITCH_FALSE; retry--) {
|
||||
const char *id = profile->id, *password = NULL;
|
||||
char *cmd = NULL;
|
||||
|
||||
if (!id) {
|
||||
vmivr_menu_profile_t sub_menu = { "std_authenticate_ask_user" };
|
||||
/* Initialize Menu Configs */
|
||||
populate_profile_menu_event(profile, &sub_menu);
|
||||
|
||||
id = mtvm_menu_get_input_set(session, profile, sub_menu, "X." /* TODO Conf Min 3 Digit */, "#" /* TODO Conf terminate input key */);
|
||||
free_profile_menu_event(&sub_menu);
|
||||
}
|
||||
if (!password) {
|
||||
vmivr_menu_profile_t sub_menu = { "std_authenticate_ask_password" };
|
||||
/* Initialize Menu Configs */
|
||||
populate_profile_menu_event(profile, &sub_menu);
|
||||
|
||||
password = mtvm_menu_get_input_set(session, profile, sub_menu, "X." /* TODO Conf Min 3 Digit */, "#" /* TODO Conf terminate input key */);
|
||||
free_profile_menu_event(&sub_menu);
|
||||
}
|
||||
cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, id, password);
|
||||
|
||||
if (mt_api_execute(session, profile->api_auth_login, cmd) == SWITCH_STATUS_SUCCESS) {
|
||||
profile->id = id;
|
||||
profile->authorized = SWITCH_TRUE;
|
||||
} else {
|
||||
playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "fail_auth"), NULL, NULL, NULL, 0);
|
||||
}
|
||||
}
|
||||
free_profile_menu_event(&menu);
|
||||
}
|
||||
|
||||
|
||||
void mtvm_menu_select_greeting_slot(switch_core_session_t *session, vmivr_profile_t *profile) {
|
||||
vmivr_menu_profile_t menu = { "std_select_greeting_slot" };
|
||||
|
||||
const char *result;
|
||||
int gnum = -1;
|
||||
|
||||
/* Initialize Menu Configs */
|
||||
populate_profile_menu_event(profile, &menu);
|
||||
|
||||
result = mtvm_menu_get_input_set(session, profile, menu, "X", NULL);
|
||||
|
||||
if (result)
|
||||
gnum = atoi(result);
|
||||
if (gnum != -1) {
|
||||
char * cmd = switch_core_session_sprintf(session, "%s %s %s %d", profile->api_profile, profile->domain, profile->id, gnum);
|
||||
if (mt_api_execute(session, profile->api_pref_greeting_set, cmd) == SWITCH_STATUS_SUCCESS) {
|
||||
char *str_num = switch_core_session_sprintf(session, "%d", gnum);
|
||||
playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0);
|
||||
} else {
|
||||
playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "invalid_slot"), NULL, NULL, NULL, 0);
|
||||
}
|
||||
}
|
||||
free_profile_menu_event(&menu);
|
||||
}
|
||||
|
||||
void mtvm_menu_record_greeting_with_slot(switch_core_session_t *session, vmivr_profile_t *profile) {
|
||||
|
||||
vmivr_menu_profile_t menu = { "std_record_greeting_with_slot" };
|
||||
|
||||
const char *result;
|
||||
int gnum = -1;
|
||||
|
||||
/* Initialize Menu Configs */
|
||||
populate_profile_menu_event(profile, &menu);
|
||||
|
||||
result = mtvm_menu_get_input_set(session, profile, menu, "X", NULL);
|
||||
|
||||
if (result)
|
||||
gnum = atoi(result);
|
||||
|
||||
/* If user entered 0, we don't accept it */
|
||||
if (gnum > 0) {
|
||||
vmivr_menu_profile_t sub_menu = { "std_record_greeting" };
|
||||
char *tmp_filepath = generate_random_file_name(session, "protovm", "wav" /* TODO make it configurable */);
|
||||
switch_status_t status;
|
||||
|
||||
/* Initialize Menu Configs */
|
||||
populate_profile_menu_event(profile, &sub_menu);
|
||||
|
||||
status = mtvm_menu_record(session, profile, sub_menu, tmp_filepath);
|
||||
|
||||
if (status == SWITCH_STATUS_SUCCESS) {
|
||||
char *cmd = switch_core_session_sprintf(session, "%s %s %s %d %s", profile->api_profile, profile->domain, profile->id, gnum, tmp_filepath);
|
||||
char *str_num = switch_core_session_sprintf(session, "%d", gnum);
|
||||
mt_api_execute(session, profile->api_pref_greeting_set, cmd);
|
||||
playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0);
|
||||
}
|
||||
free_profile_menu_event(&sub_menu);
|
||||
|
||||
}
|
||||
|
||||
free_profile_menu_event(&menu);
|
||||
|
||||
}
|
||||
|
||||
void mtvm_menu_preference(switch_core_session_t *session, vmivr_profile_t *profile) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
int retry;
|
||||
|
||||
vmivr_menu_profile_t menu = { "std_preference" };
|
||||
|
||||
/* Initialize Menu Configs */
|
||||
populate_profile_menu_event(profile, &menu);
|
||||
|
||||
if (!menu.event_keys_dtmf || !menu.event_phrases) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
|
||||
dtmf_ss_t loc;
|
||||
char *dtmfa[16] = { 0 };
|
||||
switch_event_t *phrase_params = NULL;
|
||||
|
||||
switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS);
|
||||
append_event_profile(phrase_params, profile, menu);
|
||||
|
||||
populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa);
|
||||
|
||||
captureMenuInitialize(&loc, dtmfa);
|
||||
|
||||
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
|
||||
|
||||
if (loc.result == RES_TIMEOUT) {
|
||||
/* TODO Ask for the prompt Again IF retry != 0 */
|
||||
} else if (loc.result == RES_INVALID) {
|
||||
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
|
||||
} else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */
|
||||
const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored);
|
||||
|
||||
/* Reset the try count */
|
||||
retry = MAX_ATTEMPT;
|
||||
|
||||
if (action) {
|
||||
if (!strcasecmp(action, "return")) { /* Return to the previous menu */
|
||||
retry = -1;
|
||||
} else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */
|
||||
void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(action+5);
|
||||
if (fPtr) {
|
||||
fPtr(session, profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
switch_event_destroy(&phrase_params);
|
||||
}
|
||||
|
||||
free_profile_menu_event(&menu);
|
||||
}
|
||||
|
||||
char *mtvm_menu_get_input_set(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *input_mask, const char *terminate_key) {
|
||||
char *result = NULL;
|
||||
int retry;
|
||||
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
if (!menu.event_keys_dtmf || !menu.event_phrases) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys : %s\n", menu.name);
|
||||
return result;
|
||||
}
|
||||
|
||||
for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
|
||||
dtmf_ss_t loc;
|
||||
char *dtmfa[16] = { 0 };
|
||||
int i;
|
||||
switch_event_t *phrase_params = NULL;
|
||||
|
||||
switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS);
|
||||
append_event_profile(phrase_params, profile, menu);
|
||||
|
||||
populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa);
|
||||
|
||||
/* Find the last entry and append this one to it */
|
||||
for (i=0; dtmfa[i] && i < 16; i++){
|
||||
}
|
||||
dtmfa[i] = (char *) input_mask;
|
||||
|
||||
captureMenuInitialize(&loc, dtmfa);
|
||||
if (terminate_key)
|
||||
loc.terminate_key = terminate_key[0]; /* TODO Make this load from the configuration */
|
||||
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "instructions"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
|
||||
|
||||
if (loc.result == RES_TIMEOUT) {
|
||||
/* TODO Ask for the prompt Again IF retry != 0 */
|
||||
} else if (loc.result == RES_INVALID) {
|
||||
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
|
||||
} else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */
|
||||
|
||||
/* Reset the try count */
|
||||
retry = MAX_ATTEMPT;
|
||||
|
||||
if (!strncasecmp(loc.completeMatch, input_mask, 1)) {
|
||||
result = switch_core_session_strdup(session, loc.dtmf_stored);
|
||||
retry = -1;
|
||||
|
||||
}
|
||||
}
|
||||
switch_event_destroy(&phrase_params);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
switch_status_t mtvm_menu_record(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *file_name) {
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
int retry;
|
||||
|
||||
switch_bool_t record_prompt = SWITCH_TRUE;
|
||||
switch_bool_t listen_recording = SWITCH_FALSE;
|
||||
switch_bool_t play_instruction = SWITCH_TRUE;
|
||||
|
||||
if (!menu.event_keys_dtmf || !menu.event_phrases) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) {
|
||||
dtmf_ss_t loc;
|
||||
|
||||
char *dtmfa[16] = { 0 };
|
||||
switch_event_t *phrase_params = NULL;
|
||||
switch_file_handle_t fh = { 0 };
|
||||
|
||||
/* TODO Make the following configurable */
|
||||
fh.thresh = 200;
|
||||
fh.silence_hits = 4;
|
||||
//fh.samplerate = 8000;
|
||||
|
||||
|
||||
switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS);
|
||||
append_event_profile(phrase_params, profile, menu);
|
||||
|
||||
populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa);
|
||||
|
||||
captureMenuInitialize(&loc, dtmfa);
|
||||
if (record_prompt) {
|
||||
if (play_instruction) {
|
||||
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "instructions"), NULL, phrase_params, NULL, 0);
|
||||
}
|
||||
play_instruction = SWITCH_TRUE;
|
||||
|
||||
captureMenuRecord(session, &loc, phrase_params, file_name, &fh, 30 /* TODO Make max recording configurable */);
|
||||
} else {
|
||||
if (listen_recording) {
|
||||
switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Record-File-Path", "%s", file_name);
|
||||
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "play_recording"), NULL, phrase_params, NULL, 0);
|
||||
listen_recording = SWITCH_FALSE;
|
||||
|
||||
}
|
||||
captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT);
|
||||
}
|
||||
|
||||
if (loc.recorded_audio) {
|
||||
/* Reset the try count */
|
||||
retry = MAX_ATTEMPT;
|
||||
|
||||
/* TODO Check if message is too short */
|
||||
|
||||
record_prompt = SWITCH_FALSE;
|
||||
|
||||
} else if (loc.result == RES_TIMEOUT) {
|
||||
/* TODO Ask for the prompt Again IF retry != 0 */
|
||||
} else if (loc.result == RES_INVALID) {
|
||||
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
|
||||
} else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */
|
||||
const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored);
|
||||
|
||||
/* Reset the try count */
|
||||
retry = MAX_ATTEMPT;
|
||||
|
||||
if (action) {
|
||||
if (!strcasecmp(action, "listen")) { /* Listen */
|
||||
listen_recording = SWITCH_TRUE;
|
||||
|
||||
} else if (!strcasecmp(action, "save")) {
|
||||
retry = -1;
|
||||
/* TODO ALLOW SAVE ONLY IF FILE IS RECORDED AND HIGHER THAN MIN SIZE */
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
} else if (!strcasecmp(action, "rerecord")) {
|
||||
record_prompt = SWITCH_TRUE;
|
||||
|
||||
} else if (!strcasecmp(action, "skip_instruction")) { /* Skip Recording Greeting */
|
||||
play_instruction = SWITCH_FALSE;
|
||||
|
||||
} else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */
|
||||
void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(action+5);
|
||||
if (fPtr) {
|
||||
fPtr(session, profile);
|
||||
}
|
||||
} else if (!strcasecmp(action, "return")) { /* Return */
|
||||
retry = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch_event_destroy(&phrase_params);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void (*mtvm_get_menu_function(const char *menu_name))(switch_core_session_t *session, vmivr_profile_t *profile) {
|
||||
int i = 0;
|
||||
|
||||
if (menu_name) {
|
||||
for (i=0; menu_list[i].name ; i++) {
|
||||
if (!strcasecmp(menu_list[i].name, menu_name)) {
|
||||
return menu_list[i].pt2Func;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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
|
||||
*/
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef _MENU_H_
|
||||
#define _MENU_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
void mtvm_menu_purge(switch_core_session_t *session, vmivr_profile_t *profile);
|
||||
void mtvm_menu_authenticate(switch_core_session_t *session, vmivr_profile_t *profile);
|
||||
void mtvm_menu_main(switch_core_session_t *session, vmivr_profile_t *profile);
|
||||
void mtvm_menu_record_name(switch_core_session_t *session, vmivr_profile_t *profile);
|
||||
void mtvm_menu_set_password(switch_core_session_t *session, vmivr_profile_t *profile);
|
||||
void mtvm_menu_select_greeting_slot(switch_core_session_t *session, vmivr_profile_t *profile);
|
||||
void mtvm_menu_record_greeting_with_slot(switch_core_session_t *session, vmivr_profile_t *profile);
|
||||
void mtvm_menu_preference(switch_core_session_t *session, vmivr_profile_t *profile);
|
||||
|
||||
switch_status_t mtvm_menu_record(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *file_name);
|
||||
char *mtvm_menu_get_input_set(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *input_mask, const char *terminate_key);
|
||||
|
||||
|
||||
struct vmivr_menu_function {
|
||||
const char *name;
|
||||
void (*pt2Func)(switch_core_session_t *session, vmivr_profile_t *profile);
|
||||
|
||||
};
|
||||
typedef struct vmivr_menu_function vmivr_menu_function_t;
|
||||
|
||||
extern vmivr_menu_function_t menu_list[];
|
||||
|
||||
void (*mtvm_get_menu_function(const char *menu_name))(switch_core_session_t *session, vmivr_profile_t *profile);
|
||||
|
||||
#endif /* _MENU_H_ */
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2011, 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):
|
||||
*
|
||||
* Marc Olivier Chouinard <mochouinard@moctel.com>
|
||||
*
|
||||
*
|
||||
* mod_protovm.c -- MT VoiceMail System
|
||||
*
|
||||
*/
|
||||
#include <switch.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "menu.h"
|
||||
|
||||
/* Prototypes */
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_protovm_shutdown);
|
||||
SWITCH_MODULE_RUNTIME_FUNCTION(mod_protovm_runtime);
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_protovm_load);
|
||||
|
||||
/* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime)
|
||||
* Defines a switch_loadable_module_function_table_t and a static const char[] modname
|
||||
*/
|
||||
SWITCH_MODULE_DEFINITION(mod_protovm, mod_protovm_load, mod_protovm_shutdown, NULL);
|
||||
|
||||
|
||||
#define MTVM_DESC "protovm"
|
||||
#define MTVM_USAGE "<check> profile domain [id]"
|
||||
|
||||
SWITCH_STANDARD_APP(protovm_function)
|
||||
{
|
||||
const char *id = NULL;
|
||||
const char *domain = NULL;
|
||||
const char *profile_name = NULL;
|
||||
vmivr_profile_t *profile = NULL;
|
||||
int argc = 0;
|
||||
char *argv[6] = { 0 };
|
||||
char *mydata = NULL;
|
||||
|
||||
if (!zstr(data)) {
|
||||
mydata = switch_core_session_strdup(session, data);
|
||||
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
}
|
||||
|
||||
if (argv[1])
|
||||
profile_name = argv[1];
|
||||
|
||||
if (argv[2])
|
||||
domain = argv[2];
|
||||
|
||||
if (!strcasecmp(argv[0], "check")) {
|
||||
if (argv[3])
|
||||
id = argv[3];
|
||||
|
||||
if (domain && profile_name) {
|
||||
profile = get_profile(session, profile_name);
|
||||
|
||||
if (profile) {
|
||||
void (*fPtrAuth)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(profile->menu_check_auth);
|
||||
void (*fPtrMain)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(profile->menu_check_main);
|
||||
void (*fPtrTerminate)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(profile->menu_check_terminate);
|
||||
|
||||
profile->domain = domain;
|
||||
profile->id = id;
|
||||
|
||||
if (fPtrAuth && !profile->authorized) {
|
||||
fPtrAuth(session, profile);
|
||||
}
|
||||
|
||||
if (fPtrMain && profile->authorized) {
|
||||
fPtrMain(session, profile);
|
||||
}
|
||||
if (fPtrTerminate) {
|
||||
fPtrTerminate(session, profile);
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile '%s' not found\n", profile_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Macro expands to: switch_status_t mod_protovm_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_protovm_load)
|
||||
{
|
||||
switch_application_interface_t *app_interface;
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
/* connect my internal structure to the blank pointer passed to me */
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "protovm", "protovm", MTVM_DESC, protovm_function, MTVM_USAGE, SAF_NONE);
|
||||
|
||||
/* indicate that the module should continue to be loaded */
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
Called when the system shuts down
|
||||
Macro expands to: switch_status_t mod_protovm_shutdown() */
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_protovm_shutdown)
|
||||
{
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4
|
||||
*/
|
|
@ -0,0 +1,137 @@
|
|||
<configuration name="protovm.conf" description="ProtoVoicemailIVR">
|
||||
<profiles>
|
||||
<profile name="default">
|
||||
<apis>
|
||||
<api name="auth_login" value="vm_fsdb_auth_login" />
|
||||
<api name="msg_list" value="vm_fsdb_msg_list" />
|
||||
<api name="msg_count" value="vm_fsdb_msg_count" />
|
||||
<api name="msg_delete" value="vm_fsdb_msg_delete" />
|
||||
<api name="msg_undelete" value="vm_fsdb_msg_undelete" />
|
||||
<api name="msg_save" value="vm_fsdb_msg_save" />
|
||||
<api name="msg_purge" value="vm_fsdb_msg_purge" />
|
||||
<api name="msg_get" value="vm_fsdb_msg_get" />
|
||||
<api name="pref_greeting_set" value="vm_fsdb_pref_greeting_set" />
|
||||
<api name="pref_recname_set" value="vm_fsdb_pref_recname_set" />
|
||||
<api name="pref_password_set" value="vm_fsdb_pref_password_set" />
|
||||
</apis>
|
||||
<menus>
|
||||
<menu name="std_authenticate">
|
||||
<phrases>
|
||||
<phrase name="fail_auth" value="fail_auth@protovm" />
|
||||
</phrases>
|
||||
<keys>
|
||||
</keys>
|
||||
</menu>
|
||||
|
||||
<menu name="std_authenticate_ask_user">
|
||||
<phrases>
|
||||
<phrase name="instructions" value="enter_id@protovm" />
|
||||
</phrases>
|
||||
<keys>
|
||||
<key dtmf="#" action="ivrengine:terminate_entry" variable="VM-Key-Terminator" /> <!-- TODO Make the ivrengine: parsed and the key configurable -->
|
||||
</keys>
|
||||
</menu>
|
||||
|
||||
<menu name="std_authenticate_ask_password">
|
||||
<phrases>
|
||||
<phrase name="instructions" value="enter_pass@protovm" />
|
||||
</phrases>
|
||||
<keys>
|
||||
<key dtmf="#" action="ivrengine:terminate_entry" variable="VM-Key-Terminator" /> <!-- TODO Make the ivrengine: parsed and the key configurable -->
|
||||
</keys>
|
||||
</menu>
|
||||
|
||||
<menu name="std_navigator">
|
||||
<phrases>
|
||||
<phrase name="msg_count" value="message_count@protovm" />
|
||||
<phrase name="say_date" value="say_date_event@protovm" />
|
||||
<phrase name="say_msg_number" value="say_message_number@protovm" />
|
||||
<phrase name="menu_options" value="listen_file_check@protovm" />
|
||||
<phrase name="ack" value="ack@protovm" />
|
||||
<phrase name="play_message" value="play_message@protovm" />
|
||||
</phrases>
|
||||
<keys>
|
||||
<key dtmf="1" action="skip_intro" variable="VM-Key-Main-Listen-File" />
|
||||
<key dtmf="6" action="next_msg" variable="VM-Key-Main-Next-Msg" />
|
||||
<key dtmf="4" action="prev_msg" />
|
||||
<key dtmf="7" action="delete_msg" variable="VM-Key-Main-Delete-File" /> <!-- Same key for undelete if it already deleted -->
|
||||
<key dtmf="3" action="save_msg" variable="VM-Key-Main-Save-File" />
|
||||
<key dtmf="5" action="menu:std_preference" />
|
||||
</keys>
|
||||
</menu>
|
||||
|
||||
<menu name="std_preference">
|
||||
<phrases>
|
||||
<phrase name="menu_options" value="config_menu@protovm" />
|
||||
</phrases>
|
||||
<keys>
|
||||
<key dtmf="1" action="menu:std_record_greeting_with_slot" variable="VM-Key-Record-Greeting" />
|
||||
<key dtmf="2" action="menu:std_select_greeting_slot" variable="VM-Key-Choose-Greeting" />
|
||||
<key dtmf="3" action="menu:std_record_name" variable="VM-Key-Record-Name" />
|
||||
<key dtmf="6" action="menu:std_set_password" variable="VM-Key-Change-Password" />
|
||||
<key dtmf="0" action="return" variable="VM-Key-Main-Menu" />
|
||||
</keys>
|
||||
</menu>
|
||||
|
||||
<menu name="std_record_greeting">
|
||||
<phrases>
|
||||
<phrase name="instructions" value="record_greeting@protovm" />
|
||||
<phrase name="play_recording" value="play_recording@protovm" />
|
||||
<phrase name="menu_options" value="record_file_check@protovm" />
|
||||
</phrases>
|
||||
<keys>
|
||||
<key dtmf="1" action="listen" variable="VM-Key-Listen-File" />
|
||||
<key dtmf="3" action="save" variable="VM-Key-Save-File" />
|
||||
<key dtmf="4" action="rerecord" variable="VM-Key-ReRecord-File" />
|
||||
<key dtmf="#" action="skip_instruction" />
|
||||
</keys>
|
||||
</menu>
|
||||
|
||||
|
||||
<menu name="std_record_name">
|
||||
<phrases>
|
||||
<phrase name="instructions" value="record_name@protovm" />
|
||||
<phrase name="play_recording" value="play_recording@protovm" />
|
||||
<phrase name="menu_options" value="record_file_check@protovm" />
|
||||
</phrases>
|
||||
<keys>
|
||||
<key dtmf="1" action="listen" variable="VM-Key-Listen-File" />
|
||||
<key dtmf="3" action="save" variable="VM-Key-Save-File" />
|
||||
<key dtmf="4" action="rerecord" variable="VM-Key-ReRecord-File" />
|
||||
<key dtmf="#" action="skip_instruction" />
|
||||
</keys>
|
||||
</menu>
|
||||
|
||||
|
||||
|
||||
<menu name="std_select_greeting_slot">
|
||||
<phrases>
|
||||
<phrase name="instructions" value="choose_greeting@protovm" />
|
||||
<phrase name="invalid_slot" value="choose_greeting_fail@protovm" />
|
||||
<phrase name="selected_slot" value="greeting_selected@protovm" />
|
||||
</phrases>
|
||||
<keys>
|
||||
</keys>
|
||||
</menu>
|
||||
|
||||
<menu name="std_record_greeting_with_slot">
|
||||
<phrases>
|
||||
<phrase name="instructions" value="choose_greeting@protovm" />
|
||||
</phrases>
|
||||
<keys>
|
||||
</keys>
|
||||
</menu>
|
||||
|
||||
<menu name="std_set_password">
|
||||
<phrases>
|
||||
<phrase name="instructions" value="enter_pass@protovm" />
|
||||
</phrases>
|
||||
<keys>
|
||||
</keys>
|
||||
</menu>
|
||||
</menus>
|
||||
</profile>
|
||||
</profiles>
|
||||
</configuration>
|
||||
|
||||
|
|
@ -0,0 +1,376 @@
|
|||
<include><!--This line will be ignored it's here to validate the xml and is optional -->
|
||||
<macros name="protovm" sound-prefix="$${sounds_dir}/fr/ca/june">
|
||||
<macro name="press_key">
|
||||
<input pattern="^(.*):(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="$2"/>
|
||||
<action function="play-file" data="voicemail/vm-press.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="plurial_msg">
|
||||
<input pattern="^[01]:(.*):(.*)$" break_on_match="true">
|
||||
<match>
|
||||
<action function="play-file" data="$1"/>
|
||||
</match>
|
||||
</input>
|
||||
<input pattern="^.*:(.*):(.*)$" break_on_match="true">
|
||||
<match>
|
||||
<action function="play-file" data="$2"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="enter_id">
|
||||
<input pattern="(.+)">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-enter_id.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
<nomatch>
|
||||
<action function="play-file" data="voicemail/vm-enter_id.wav"/>
|
||||
<action function="say" data="${VM-Key-Terminator}" method="pronounced" type="name_spelled"/>
|
||||
</nomatch>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
|
||||
<macro name="enter_pass">
|
||||
<input pattern="(.+)">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-enter_pass.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
<nomatch>
|
||||
<action function="play-file" data="voicemail/vm-enter_pass.wav"/>
|
||||
<action function="say" data="${VM-Key-Terminator}" method="pronounced" type="name_spelled"/>
|
||||
</nomatch>
|
||||
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="fail_auth">
|
||||
<input>
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-fail_auth.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="hello">
|
||||
<input>
|
||||
<match>
|
||||
<!--<action function="play-file" data="voicemail/vm-hello.wav"/> -->
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="goodbye">
|
||||
<input>
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-goodbye.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="abort">
|
||||
<input>
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-abort.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="message_count">
|
||||
<input field="${VM-Total-New-Urgent-Messages}" pattern="^(0)$">
|
||||
<nomatch>
|
||||
<action function="play-file" data="voicemail/vm-you_have.wav"/>
|
||||
<action function="say" data="${VM-Total-New-Urgent-Messages}" method="pronounced" type="items"/>
|
||||
<action function="play-file" data="voicemail/vm-urgent-new.wav"/>
|
||||
<action function="phrase" phrase="plurial_msg@protovm" data="${VM-Total-New-Urgent-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
|
||||
</nomatch>
|
||||
</input>
|
||||
<input field="${VM-Total-New-Messages}" pattern="^(\d+)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-you_have.wav"/>
|
||||
<action function="say" data="${VM-Total-New-Messages}" method="pronounced" type="items"/>
|
||||
<action function="play-file" data="voicemail/vm-new.wav"/>
|
||||
<action function="phrase" phrase="plurial_msg@protovm" data="${VM-Total-New-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
<input field="${VM-Total-Saved-Messages}" pattern="^(0)$">
|
||||
<nomatch>
|
||||
<action function="play-file" data="currency/and.wav"/>
|
||||
<action function="say" data="${VM-Total-Saved-Messages}" method="pronounced" type="items"/>
|
||||
<action function="play-file" data="voicemail/vm-saved.wav"/>
|
||||
<action function="phrase" phrase="plurial_msg@protovm" data="${VM-Total-Saved-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
|
||||
</nomatch>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="menu">
|
||||
<input>
|
||||
<match>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Play-New-Messages}:voicemail/vm-listen_new.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Play-Saved-Messages}:voicemail/vm-listen_saved.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Config-Menu}:voicemail/vm-advanced.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Terminator}:voicemail/vm-to_exit.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="config_menu">
|
||||
<input>
|
||||
<match>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Record-Greeting}:voicemail/vm-to_record_greeting.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Choose-Greeting}:voicemail/vm-choose_greeting.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Record-Name}:voicemail/vm-record_name2.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Change-Password}:voicemail/vm-change_password.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Menu}:voicemail/vm-main_menu.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="record_name">
|
||||
<input>
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-record_name1.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="record_file_check">
|
||||
<input>
|
||||
<match>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Listen-File}:voicemail/vm-listen_to_recording.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Save-File}:voicemail/vm-save_recording.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Record-File}:voicemail/vm-rerecord.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="record_urgent_check">
|
||||
<input>
|
||||
<match>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Urgent}:voicemail/vm-mark-urgent.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Terminator}:voicemail/vm-continue.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="forward_prepend">
|
||||
<input>
|
||||
<match>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Prepend}:voicemail/vm-forward_add_intro.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Forward}:voicemail/vm-send_message_now.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="forward_message_enter_extension">
|
||||
<input pattern="^([0-9#*])$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-forward_enter_ext.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-followed_by.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="invalid_extension">
|
||||
<input>
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-that_was_an_invalid_ext.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="listen_file_check">
|
||||
<input>
|
||||
<match>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Next-Msg}:voicemail/vm-for_next_msg.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Listen-File}:voicemail/vm-listen_to_recording.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Save-File}:voicemail/vm-save_recording.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Delete-File}:voicemail/vm-delete_recording.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
<input field="${VM-Message-Email}" pattern="^$">
|
||||
<nomatch>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Email}:voicemail/vm-forward_to_email.wav"/>
|
||||
</nomatch>
|
||||
</input>
|
||||
<input>
|
||||
<match>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Callback}:voicemail/vm-return_call.wav"/>
|
||||
<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Forward}:voicemail/vm-to_forward.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="choose_greeting">
|
||||
<input>
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-choose_greeting_choose.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="choose_greeting_fail">
|
||||
<input>
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-choose_greeting_fail.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="record_greeting">
|
||||
<input>
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-record_greeting.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="record_message">
|
||||
<input>
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-record_message.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="greeting_selected">
|
||||
<input pattern="^(\d+)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-greeting.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="items"/>
|
||||
<action function="play-file" data="voicemail/vm-selected.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="play_greeting">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-person.wav"/>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
<action function="play-file" data="voicemail/vm-not_available.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="say_number">
|
||||
<input pattern="^(\d+)$">
|
||||
<match>
|
||||
<action function="say" data="$1" method="pronounced" type="items"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="say_message_number">
|
||||
<input>
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-${VM-Message-Type}.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-message_number.wav"/>
|
||||
<action function="say" data="${VM-Message-Number}" method="pronounced" type="items"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="say_phone_number">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="say_name">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="say" data="$1" method="pronounced" type="name_spelled"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
<!-- Note: Update this to marked-urgent,emailed and saved once new sound files are recorded -->
|
||||
<macro name="ack">
|
||||
<input pattern="^(too-small)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-too-small.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
<input pattern="^(undeleted)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-message.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-$1.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
<input pattern="^(deleted)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-message.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-$1.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
<input pattern="^(saved)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-message.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-$1.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
<input pattern="^(emailed)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-message.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-$1.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
<input pattern="^(marked-urgent)$">
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-message.wav"/>
|
||||
<action function="play-file" data="voicemail/vm-$1.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="say_date">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
<action function="say" data="$1" method="pronounced" type="short_date_time"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="say_date_event">
|
||||
<input>
|
||||
<match>
|
||||
<action function="say" data="${VM-Message-Received-Epoch}" method="pronounced" type="short_date_time"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="play_message">
|
||||
<input>
|
||||
<match>
|
||||
<action function="play-file" data="${VM-Message-File-Path}"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="play_recording">
|
||||
<input>
|
||||
<match>
|
||||
<action function="play-file" data="${VM-Record-File-Path}"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="disk_quota_exceeded">
|
||||
<input>
|
||||
<match>
|
||||
<action function="play-file" data="voicemail/vm-mailbox_full.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
</macros>
|
||||
</include><!--This line will be ignored it's here to validate the xml and is optional -->
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2011, 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):
|
||||
*
|
||||
* Marc Olivier Chouinard <mochouinard@moctel.com>
|
||||
*
|
||||
*
|
||||
* utils.c -- MT VoiceMail / Different utility that might need to go into the core (after cleanup)
|
||||
*
|
||||
*/
|
||||
#include <switch.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
switch_status_t mt_merge_media_files(const char** inputs, const char *output) {
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
switch_file_handle_t fh_output = { 0 };
|
||||
int channels = 1;
|
||||
int rate = 8000; /* TODO Make this configurable */
|
||||
int j = 0;
|
||||
|
||||
if (switch_core_file_open(&fh_output, output, channels, rate, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open %s\n", output);
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (j = 0; inputs[j] != NULL && j < 128 && status == SWITCH_STATUS_SUCCESS; j++) {
|
||||
switch_file_handle_t fh_input = { 0 };
|
||||
char buf[2048];
|
||||
switch_size_t len = sizeof(buf) / 2;
|
||||
|
||||
if (switch_core_file_open(&fh_input, inputs[j], channels, rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open %s\n", inputs[j]);
|
||||
status = SWITCH_STATUS_GENERR;
|
||||
break;
|
||||
}
|
||||
|
||||
while (switch_core_file_read(&fh_input, buf, &len) == SWITCH_STATUS_SUCCESS) {
|
||||
if (switch_core_file_write(&fh_output, buf, &len) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write error\n");
|
||||
status = SWITCH_STATUS_GENERR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fh_input.file_interface) {
|
||||
switch_core_file_close(&fh_input);
|
||||
}
|
||||
}
|
||||
|
||||
if (fh_output.file_interface) {
|
||||
switch_core_file_close(&fh_output);
|
||||
}
|
||||
end:
|
||||
return status;
|
||||
}
|
||||
|
||||
switch_event_t *jsonapi2event(switch_core_session_t *session, switch_event_t *apply_event, const char *api, const char *data) {
|
||||
switch_event_t *phrases_event = NULL;
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
switch_api_execute(api, data, session, &stream);
|
||||
switch_event_create_json(&phrases_event, (char *) stream.data);
|
||||
switch_safe_free(stream.data);
|
||||
|
||||
if (apply_event) {
|
||||
switch_event_header_t *hp;
|
||||
for (hp = phrases_event->headers; hp; hp = hp->next) {
|
||||
if (!strncasecmp(hp->name, "VM-", 3)) {
|
||||
switch_event_add_header(apply_event, SWITCH_STACK_BOTTOM, hp->name, "%s", hp->value);
|
||||
}
|
||||
}
|
||||
switch_event_destroy(&phrases_event);
|
||||
phrases_event = apply_event;
|
||||
|
||||
}
|
||||
|
||||
return phrases_event;
|
||||
}
|
||||
|
||||
char *generate_random_file_name(switch_core_session_t *session, const char *mod_name, char *file_extension) {
|
||||
char rand_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = "";
|
||||
switch_uuid_t srand_uuid;
|
||||
|
||||
switch_uuid_get(&srand_uuid);
|
||||
switch_uuid_format(rand_uuid, &srand_uuid);
|
||||
|
||||
return switch_core_session_sprintf(session, "%s%s%s_%s.%s", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, mod_name, rand_uuid, file_extension);
|
||||
|
||||
}
|
||||
|
||||
switch_status_t mt_api_execute(switch_core_session_t *session, const char *apiname, const char *arguments) {
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
switch_api_execute(apiname, arguments, session, &stream);
|
||||
if (!strncasecmp(stream.data, "-ERR", 4)) {
|
||||
status = SWITCH_STATUS_GENERR;
|
||||
}
|
||||
switch_safe_free(stream.data);
|
||||
return status;
|
||||
}
|
||||
|
||||
void append_event_profile(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu) {
|
||||
/* Used for some appending function */
|
||||
if (profile->name && profile->id && profile->domain) {
|
||||
switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Profile", "%s", profile->name);
|
||||
switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Account-ID", "%s", profile->id);
|
||||
switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Account-Domain", "%s", profile->domain);
|
||||
}
|
||||
}
|
||||
|
||||
void populate_dtmfa_from_event(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu, char **dtmfa) {
|
||||
int i = 0;
|
||||
if (menu.event_keys_dtmf) {
|
||||
switch_event_header_t *hp;
|
||||
|
||||
for (hp = menu.event_keys_dtmf->headers; hp; hp = hp->next) {
|
||||
if (strlen(hp->name) < 3 && hp->value) { /* TODO This is a hack to discard default FS Events ! */
|
||||
const char *varphrasename = switch_event_get_header(menu.event_keys_varname, hp->value);
|
||||
dtmfa[i++] = hp->name;
|
||||
|
||||
if (varphrasename && !zstr(varphrasename)) {
|
||||
switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, varphrasename, "%s", hp->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void append_event_message(switch_core_session_t *session, vmivr_profile_t *profile, switch_event_t *phrase_params, switch_event_t *msg_list_event, size_t current_msg) {
|
||||
|
||||
char *varname;
|
||||
char *apicmd;
|
||||
|
||||
varname = switch_mprintf("VM-List-Message-%" SWITCH_SIZE_T_FMT "-UUID", current_msg);
|
||||
apicmd = switch_mprintf("json %s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(msg_list_event, varname));
|
||||
|
||||
switch_safe_free(varname);
|
||||
|
||||
jsonapi2event(session, phrase_params, profile->api_msg_get, apicmd);
|
||||
|
||||
/* TODO Set these 2 header correctly */
|
||||
switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Message-Type", "%s", "new");
|
||||
switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Message-Number", "%"SWITCH_SIZE_T_FMT, current_msg);
|
||||
|
||||
switch_event_add_header_string(phrase_params, SWITCH_STACK_BOTTOM, "VM-Message-Private-Local-Copy", "False");
|
||||
|
||||
switch_safe_free(apicmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
switch_status_t mt_merge_files(const char** inputs, const char *output);
|
||||
|
||||
void append_event_message(switch_core_session_t *session, vmivr_profile_t *profile, switch_event_t *phrase_params, switch_event_t *msg_list_event, size_t current_msg);
|
||||
void append_event_profile(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu);
|
||||
char *generate_random_file_name(switch_core_session_t *session, const char *mod_name, char *file_extension);
|
||||
switch_event_t *jsonapi2event(switch_core_session_t *session, switch_event_t *apply_event, const char *api, const char *data);
|
||||
switch_status_t mt_merge_media_files(const char** inputs, const char *output);
|
||||
switch_status_t mt_api_execute(switch_core_session_t *session, const char *apiname, const char *arguments);
|
||||
void populate_dtmfa_from_event(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu, char **dtmfa);
|
||||
#endif /* _UTIL_H_ */
|
||||
|
|
@ -89,7 +89,7 @@ SWITCH_LIMIT_INCR(limit_incr_redis)
|
|||
}
|
||||
|
||||
/* Get the keys for redis server */
|
||||
uuid_rediskey = switch_core_session_sprintf(session,"%s_%s_%s", switch_core_get_hostname(), realm, resource);
|
||||
uuid_rediskey = switch_core_session_sprintf(session,"%s_%s_%s", switch_core_get_switchname(), realm, resource);
|
||||
rediskey = switch_core_session_sprintf(session, "%s_%s", realm, resource);
|
||||
|
||||
if ((pvt = switch_channel_get_private(channel, "limit_redis"))) {
|
||||
|
@ -179,7 +179,7 @@ SWITCH_LIMIT_RELEASE(limit_release_redis)
|
|||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Couldn't decrement value corresponding to %s\n", (char *)p_key);
|
||||
switch_goto_status(SWITCH_STATUS_FALSE, end);
|
||||
}
|
||||
p_uuid_key = switch_core_session_sprintf(session, "%s_%s", switch_core_get_hostname(), (char *)p_key);
|
||||
p_uuid_key = switch_core_session_sprintf(session, "%s_%s", switch_core_get_switchname(), (char *)p_key);
|
||||
if (credis_decr(redis,p_uuid_key,&uuid_val) != 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Couldn't decrement value corresponding to %s\n", p_uuid_key);
|
||||
switch_goto_status(SWITCH_STATUS_FALSE, end);
|
||||
|
@ -193,7 +193,7 @@ SWITCH_LIMIT_RELEASE(limit_release_redis)
|
|||
|
||||
} else {
|
||||
rediskey = switch_core_session_sprintf(session, "%s_%s", realm, resource);
|
||||
uuid_rediskey = switch_core_session_sprintf(session, "%s_%s_%s", switch_core_get_hostname(), realm, resource);
|
||||
uuid_rediskey = switch_core_session_sprintf(session, "%s_%s_%s", switch_core_get_switchname(), realm, resource);
|
||||
switch_core_hash_delete(pvt->hash, (const char *) rediskey);
|
||||
|
||||
if (credis_decr(redis, rediskey, &val) != 0) {
|
||||
|
@ -249,13 +249,13 @@ SWITCH_LIMIT_RESET(limit_reset_redis)
|
|||
{
|
||||
REDIS redis;
|
||||
if (redis_factory(&redis) == SWITCH_STATUS_SUCCESS) {
|
||||
char *rediskey = switch_mprintf("%s_*", switch_core_get_hostname());
|
||||
char *rediskey = switch_mprintf("%s_*", switch_core_get_switchname());
|
||||
int dec = 0, val = 0, keyc;
|
||||
char *uuids[2000];
|
||||
|
||||
if ((keyc = credis_keys(redis, rediskey, uuids, switch_arraylen(uuids))) > 0) {
|
||||
int i = 0;
|
||||
int hostnamelen = strlen(switch_core_get_hostname())+1;
|
||||
int hostnamelen = strlen(switch_core_get_switchname())+1;
|
||||
|
||||
for (i = 0; i < keyc && uuids[i]; i++){
|
||||
const char *key = uuids[i] + hostnamelen;
|
||||
|
|
|
@ -175,7 +175,7 @@ SWITCH_STANDARD_APP(rss_function)
|
|||
char *filename = NULL;
|
||||
char *argv[3], *feed_list[TTS_MAX_ENTRIES] = { 0 }, *feed_names[TTS_MAX_ENTRIES] = {
|
||||
0};
|
||||
int argc, feed_index = 0;
|
||||
int feed_index = 0;
|
||||
const char *cf = "rss.conf";
|
||||
switch_xml_t cfg, cxml, feeds, feed;
|
||||
char buf[1024] = "";
|
||||
|
@ -236,7 +236,7 @@ SWITCH_STANDARD_APP(rss_function)
|
|||
|
||||
if (!zstr(data)) {
|
||||
if ((mydata = switch_core_session_strdup(session, data))) {
|
||||
argc = switch_separate_string(mydata, ' ', argv, sizeof(argv) / sizeof(argv[0]));
|
||||
switch_separate_string(mydata, ' ', argv, sizeof(argv) / sizeof(argv[0]));
|
||||
|
||||
if (argv[0]) {
|
||||
engine = argv[0];
|
||||
|
|
|
@ -70,23 +70,77 @@ SWITCH_STANDARD_APP(stop_dtmf_session_function)
|
|||
spandsp_stop_inband_dtmf_session(session);
|
||||
}
|
||||
|
||||
|
||||
SWITCH_STANDARD_APP(spandsp_fax_detect_session_function)
|
||||
{
|
||||
int argc = 0;
|
||||
char *argv[3] = { 0 };
|
||||
char *dupdata;
|
||||
const char *app = NULL, *arg = NULL;
|
||||
int timeout = 0;
|
||||
|
||||
if (!zstr(data) && (dupdata = switch_core_session_strdup(session, data))) {
|
||||
if ((argc = switch_split(dupdata, ' ', argv)) == 3) {
|
||||
app = argv[0];
|
||||
arg = argv[1];
|
||||
timeout = atoi(argv[2]);
|
||||
if (timeout < 0) {
|
||||
timeout = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (app) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Enabling fax detection '%s' '%s'\n", argv[0], argv[1]);
|
||||
spandsp_fax_detect_session(session, "rw", timeout, 1, app, arg, NULL);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot Enable fax detection '%s' '%s'\n", argv[0], argv[1]);
|
||||
}
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_APP(spandsp_stop_fax_detect_session_function)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Disabling fax detection\n");
|
||||
spandsp_fax_stop_detect_session(session);
|
||||
}
|
||||
|
||||
static void event_handler(switch_event_t *event)
|
||||
{
|
||||
mod_spandsp_fax_event_handler(event);
|
||||
}
|
||||
|
||||
|
||||
SWITCH_STANDARD_APP(t38_gateway_function)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
time_t timeout = switch_epoch_time_now(NULL) + 20;
|
||||
const char *var;
|
||||
int argc = 0;
|
||||
char *argv[2] = { 0 };
|
||||
char *dupdata;
|
||||
const char *direction = NULL, *flags = NULL;
|
||||
|
||||
if (zstr(data) || strcasecmp(data, "self")) {
|
||||
data = "peer";
|
||||
if (!zstr(data) && (dupdata = switch_core_session_strdup(session, data))) {
|
||||
if ((argc = switch_split(dupdata, ' ', argv))) {
|
||||
if (argc > 0) {
|
||||
direction = argv[0];
|
||||
}
|
||||
|
||||
switch_channel_set_variable(channel, "t38_leg", data);
|
||||
if (argc > 1) {
|
||||
flags = argv[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (zstr(direction) || strcasecmp(direction, "self")) {
|
||||
direction = "peer";
|
||||
}
|
||||
|
||||
switch_channel_set_variable(channel, "t38_leg", direction);
|
||||
|
||||
if (!zstr(flags) && !strcasecmp(flags, "nocng")) {
|
||||
t38_gateway_start(session, direction, NULL);
|
||||
} else {
|
||||
if ((var = switch_channel_get_variable(channel, "t38_gateway_detect_timeout"))) {
|
||||
long to = atol(var);
|
||||
if (to > -1) {
|
||||
|
@ -96,7 +150,9 @@ SWITCH_STANDARD_APP(t38_gateway_function)
|
|||
}
|
||||
}
|
||||
|
||||
switch_ivr_tone_detect_session(session, "t38", "1100.0", "rw", timeout, 1, data, NULL, t38_gateway_start);
|
||||
//switch_ivr_tone_detect_session(session, "t38", "1100.0", "rw", timeout, 1, direction, NULL, t38_gateway_start);
|
||||
spandsp_fax_detect_session(session, "rw", timeout, 1, direction, NULL, t38_gateway_start);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,6 +254,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_spandsp_init)
|
|||
SWITCH_ADD_APP(app_interface, "spandsp_stop_dtmf", "stop inband dtmf", "Stop detecting inband dtmf.", stop_dtmf_session_function, "", SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "spandsp_start_dtmf", "Detect dtmf", "Detect inband dtmf on the session", dtmf_session_function, "", SAF_MEDIA_TAP);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "spandsp_start_fax_detect", "start fax detect", "start fax detect", spandsp_fax_detect_session_function,
|
||||
"<app>[ <arg>][ <timeout>]", SAF_NONE);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "spandsp_stop_fax_detect", "stop fax detect", "stop fax detect", spandsp_stop_fax_detect_session_function, "", SAF_NONE);
|
||||
|
||||
|
||||
mod_spandsp_fax_load(pool);
|
||||
mod_spandsp_codecs_load(module_interface, pool);
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue