diff --git a/Freeswitch.2010.sln b/Freeswitch.2010.sln index 63b3ad12f2..cfb4770b6f 100644 --- a/Freeswitch.2010.sln +++ b/Freeswitch.2010.sln @@ -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} diff --git a/conf/autoload_configs/cepstral.conf.xml b/conf/autoload_configs/cepstral.conf.xml new file mode 100644 index 0000000000..cf4aa92f41 --- /dev/null +++ b/conf/autoload_configs/cepstral.conf.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/conf/autoload_configs/switch.conf.xml b/conf/autoload_configs/switch.conf.xml index d2500a6463..b0f0c53fef 100644 --- a/conf/autoload_configs/switch.conf.xml +++ b/conf/autoload_configs/switch.conf.xml @@ -24,6 +24,17 @@ + + + + + + diff --git a/conf/dialplan/default/01_Talking_Clock.xml b/conf/dialplan/default/01_Talking_Clock.xml new file mode 100644 index 0000000000..4e37962001 --- /dev/null +++ b/conf/dialplan/default/01_Talking_Clock.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml index 65f6e1812d..42eede31ee 100644 --- a/conf/freeswitch.xml +++ b/conf/freeswitch.xml @@ -52,14 +52,12 @@ - - - - - - - - - + + + + + + + diff --git a/conf/lang/de/de.xml b/conf/lang/de/de.xml index 5239489f75..1b44c9a1dd 100644 --- a/conf/lang/de/de.xml +++ b/conf/lang/de/de.xml @@ -1,7 +1,11 @@ - - - - + + + + + + + + diff --git a/conf/lang/de/vm/sounds.xml b/conf/lang/de/vm/sounds.xml new file mode 100644 index 0000000000..ad9dc2e136 --- /dev/null +++ b/conf/lang/de/vm/sounds.xml @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/lang/en/dir/sounds.xml b/conf/lang/en/dir/sounds.xml index e7a2e8f925..15ecec304a 100644 --- a/conf/lang/en/dir/sounds.xml +++ b/conf/lang/en/dir/sounds.xml @@ -99,7 +99,7 @@ - + diff --git a/conf/lang/en/en.xml b/conf/lang/en/en.xml index 6bd5a7d5fb..1e23dc5d7b 100644 --- a/conf/lang/en/en.xml +++ b/conf/lang/en/en.xml @@ -1,8 +1,12 @@ - - - - - + + + + + + + + + diff --git a/conf/lang/en/ivr/sounds.xml b/conf/lang/en/ivr/sounds.xml new file mode 100644 index 0000000000..58db0a6c15 --- /dev/null +++ b/conf/lang/en/ivr/sounds.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/conf/lang/fr/fr.xml b/conf/lang/fr/fr.xml index 12bec06f20..eaf00f247e 100644 --- a/conf/lang/fr/fr.xml +++ b/conf/lang/fr/fr.xml @@ -1,8 +1,12 @@ - - - - - + + + + + + + + + diff --git a/conf/lang/he/he.xml b/conf/lang/he/he.xml index 006195bf9a..fe7c5d8a01 100644 --- a/conf/lang/he/he.xml +++ b/conf/lang/he/he.xml @@ -1,7 +1,11 @@ - - - - + + + + + + + + diff --git a/conf/lang/ru/ru.xml b/conf/lang/ru/ru.xml index 25d63b6110..686e840860 100644 --- a/conf/lang/ru/ru.xml +++ b/conf/lang/ru/ru.xml @@ -1,9 +1,13 @@ - - - - + + + + + + + + diff --git a/configure.in b/configure.in index 4ae6dc7b59..356e4c4705 100644 --- a/configure.in +++ b/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 diff --git a/debian/freeswitch-lang-de.conffiles b/debian/freeswitch-lang-de.conffiles index 34d88b70ea..5c1dded24e 100644 --- a/debian/freeswitch-lang-de.conffiles +++ b/debian/freeswitch-lang-de.conffiles @@ -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 diff --git a/debian/freeswitch-lang-de.install b/debian/freeswitch-lang-de.install index a7e326a6ad..1b33ebec72 100644 --- a/debian/freeswitch-lang-de.install +++ b/debian/freeswitch-lang-de.install @@ -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* diff --git a/docs/ChangeLog b/docs/ChangeLog index 4d0760a982..b4e93ab05c 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -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 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 (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) diff --git a/docs/phrase/phrase_en.xml b/docs/phrase/phrase_en.xml index 34901054e9..ab4f61bb46 100644 --- a/docs/phrase/phrase_en.xml +++ b/docs/phrase/phrase_en.xml @@ -436,9 +436,24 @@ + - + + + + + + + + + + + + + + + diff --git a/freeswitch.spec b/freeswitch.spec index 8fcbd07772..4397430d7f 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -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 diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index 2985bca2af..96cd81d349 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -839,9 +839,9 @@ static const char *basic_gets(int *cnt) } Sleep(20); } +#endif return command_buf; -#endif } #endif diff --git a/libs/esl/lua/esl_lua.2010.sln b/libs/esl/lua/esl_lua.2010.sln new file mode 100644 index 0000000000..5cdab36b1c --- /dev/null +++ b/libs/esl/lua/esl_lua.2010.sln @@ -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 diff --git a/libs/esl/lua/esl_lua.2010.vcxproj b/libs/esl/lua/esl_lua.2010.vcxproj new file mode 100644 index 0000000000..99a355f95a --- /dev/null +++ b/libs/esl/lua/esl_lua.2010.vcxproj @@ -0,0 +1,178 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + ESL + {86B6AB99-A261-455A-9CD6-9142A5A1652E} + esl_lua.2010 + Win32Proj + + + + DynamicLibrary + + + DynamicLibrary + + + DynamicLibrary + + + DynamicLibrary + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + $(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\;$(ProjectDir)..\src\include;%(AdditionalIncludeDirectories) + ESL_DECLARE_STATIC;WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + EditAndContinue + + + esl.lib;lua51.lib;ws2_32.lib;%(AdditionalDependencies) + $(ProjectDir)..\..\..\$(Platform)\$(Configuration)\;$(ProjectDir)..\..\..\libs\esl\src\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + + + $(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\;$(ProjectDir)..\src\include;%(AdditionalIncludeDirectories) + ESL_DECLARE_STATIC;WIN32;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + esl.lib;lua51.lib;ws2_32.lib;%(AdditionalDependencies) + $(ProjectDir)..\..\..\$(Platform)\$(Configuration)\;$(ProjectDir)..\..\..\libs\esl\src\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + + + X64 + + + Disabled + $(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\;$(ProjectDir)..\src\include;%(AdditionalIncludeDirectories) + ESL_DECLARE_STATIC;WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + esl.lib;lua51.lib;ws2_32.lib;%(AdditionalDependencies) + $(ProjectDir)..\..\..\$(Platform)\$(Configuration);$(ProjectDir)..\..\..\libs\esl\src\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) + true + Windows + MachineX64 + + + + + X64 + + + $(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\;$(ProjectDir)..\src\include;%(AdditionalIncludeDirectories) + ESL_DECLARE_STATIC;WIN32;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + esl.lib;lua51.lib;ws2_32.lib;%(AdditionalDependencies) + $(ProjectDir)..\..\..\$(Platform)\$(Configuration);$(ProjectDir)..\..\..\libs\esl\src\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX64 + + + + + + + + + + \ No newline at end of file diff --git a/libs/esl/lua/esl_lua.2010.vcxproj.filters b/libs/esl/lua/esl_lua.2010.vcxproj.filters new file mode 100644 index 0000000000..51644e4cdf --- /dev/null +++ b/libs/esl/lua/esl_lua.2010.vcxproj.filters @@ -0,0 +1,25 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index 95e9615107..bfdf58a625 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -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); } diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 4db6854bb7..68728668bd 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -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)) { @@ -1568,7 +1587,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS", "%s", channel_caller_data->rdnis.digits); switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-TON", "%d", channel_caller_data->rdnis.type); switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Plan", "%d", channel_caller_data->rdnis.plan); - + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Screen", "%d", channel_caller_data->screen); switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Presentation", "%d", channel_caller_data->pres); } @@ -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 \n" \ -"ftdm restart \n" \ +"ftdm restart []\n" \ "ftdm dump []\n" \ "ftdm sigstatus get|set [] [] []\n" \ "ftdm trace []\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 \n"); + if (argc < 2) { + stream->write_function(stream, "-ERR Usage: ftdm restart []\n"); goto end; } ftdm_span_find_by_name(argv[1], &span); @@ -4152,15 +4172,32 @@ SWITCH_STANDARD_API(ft_function) stream->write_function(stream, "-ERR invalid span\n"); goto end; } - - chan_id = atoi(argv[2]); - chan = ftdm_span_get_channel(span, chan_id); - if (!chan) { - stream->write_function(stream, "-ERR Could not find chan\n"); - 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; + } } - stream->write_function(stream, "Resetting channel %s:%s\n", argv[2], argv[3]); - ftdm_channel_reset(chan); + 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[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); diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 96fd235ad2..1c10171202 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -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) { diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index 6653a923aa..949ea154e3 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -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; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index d119ff4fd2..75379eef64 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -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); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index 43d6ad555e..112e7cf27d 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -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; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index ee0cdbe1ef..49b07fff33 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -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")) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c index b7eaa37639..34d79837f0 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c @@ -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,21 +397,25 @@ 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); - return 1; - } else { - SS7_INFO("ISUP CKT %d configuration DONE!\n", x); - } + if (ftmod_ss7_isup_ckt_config(x)) { + SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x); + return 1; + } else { + SS7_INFO("ISUP CKT %d configuration DONE!\n", x); + } - /* set the SNGSS7_CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.isupCkt[x].flags |= SNGSS7_CONFIGURED; + /* 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) */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c index 2cd3a13e30..1dd9717c9f 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c @@ -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; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c index 8a7b095675..b0a2163fdd 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c @@ -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; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c index 3981cd6597..40a712f8e2 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c @@ -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); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c index 2a395c9ad1..4b5787c0cb 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c @@ -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,24 +149,19 @@ 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", - buf, - DECODE_LSD_EVENT(sta->t.usta.alarm.event)); - break; - /******************************************************************/ - default: - ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s (***unknown cause***)\n", - buf, - DECODE_LSD_EVENT(sta->t.usta.alarm.event)); - break; + case (LCM_CAUSE_MGMT_INITIATED): + 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_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; /******************************************************************/ } /* switch (sta->t.usta.alarm.cause) */ 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)); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 8e57473202..4f8c069b71 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -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,7 +636,10 @@ 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 */ - ft_to_sngss7_acm(ftdmchan); + 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", ""); - /* bring the sig status down */ - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); + 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(); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index df8b086c49..ea31a89c5b 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -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); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c index 96446b4215..9fe279d7c5 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c @@ -182,8 +182,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) /* copy down the called number information */ copy_cdPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cdPtyNum); - /* copy down the calling number information */ - + /* 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 */ @@ -195,7 +194,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) iam.cgPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].clg_nadi; SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLG, using \"%d\"\n", iam.cgPtyNum.natAddrInd.val); } - + cld_nadi = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_cld_nadi"); if ((cld_nadi != NULL) && (*cld_nadi)) { SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called NADI value \"%s\"\n", cld_nadi); @@ -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)) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c index 2b915b1053..22b522409f 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c @@ -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); @@ -134,11 +127,12 @@ uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum) cgPtyNum->niInd.val = 0x00; /**************************************************************************/ cgPtyNum->addrSig.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'; 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; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c index 49da10cdf1..815377b476 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c @@ -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; diff --git a/libs/libteletone/src/libteletone_generate.c b/libs/libteletone/src/libteletone_generate.c index ebf62822a4..a5cefac98d 100644 --- a/libs/libteletone/src/libteletone_generate.c +++ b/libs/libteletone/src/libteletone_generate.c @@ -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); diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index ecc88483f6..fafef50c36 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Tue Mar 22 15:01:49 CDT 2011 +Wed Apr 27 11:49:37 CDT 2011 diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/msg_date.c b/libs/sofia-sip/libsofia-sip-ua/msg/msg_date.c index a665e9d495..5a8f354fa5 100644 --- a/libs/sofia-sip/libsofia-sip-ua/msg/msg_date.c +++ b/libs/sofia-sip/libsofia-sip-ua/msg/msg_date.c @@ -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)) { diff --git a/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c b/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c index a6c7d49ac6..bd1e63b478 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c +++ b/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c @@ -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; diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c index 543f0e135a..b96ec2ba5b 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c +++ b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c @@ -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) { diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c index fd826e0e19..a0dcbb1c4e 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c @@ -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; diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c index 032c0a04f2..a35669dd3b 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c @@ -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) diff --git a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c index b6e0c01385..6455f4b5c8 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c +++ b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c @@ -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; diff --git a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_print.c b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_print.c index e2852b446b..e94c6b6758 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_print.c +++ b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_print.c @@ -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); } diff --git a/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c b/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c index e00d3912d8..4152669bfd 100644 --- a/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c +++ b/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c @@ -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; diff --git a/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c b/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c index e494571f54..ceb7d0f601 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c +++ b/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c @@ -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) { diff --git a/libs/sofia-sip/libsofia-sip-ua/stun/stun.c b/libs/sofia-sip/libsofia-sip-ua/stun/stun.c index 09ecff41cb..d2fabe3329 100644 --- a/libs/sofia-sip/libsofia-sip-ua/stun/stun.c +++ b/libs/sofia-sip/libsofia-sip-ua/stun/stun.c @@ -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: diff --git a/libs/sofia-sip/libsofia-sip-ua/stun/stun_dns.c b/libs/sofia-sip/libsofia-sip-ua/stun/stun_dns.c index bfbfe77e41..86ef0b2c37 100644 --- a/libs/sofia-sip/libsofia-sip-ua/stun/stun_dns.c +++ b/libs/sofia-sip/libsofia-sip-ua/stun/stun_dns.c @@ -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; } diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c b/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c index edc47e5da9..51259ade1a 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c @@ -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); diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c b/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c index de7279e493..523599c7a7 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c @@ -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; diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport.c index a33b77f3e2..8ebab4fd31 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport.c @@ -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); diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_stun.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_stun.c index 55f67a9e2c..3233e1c616 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_stun.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_stun.c @@ -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); diff --git a/libs/sofia-sip/libsofia-sip-ua/url/url.c b/libs/sofia-sip/libsofia-sip-ua/url/url.c index bef523e5c9..71544735e1 100644 --- a/libs/sofia-sip/libsofia-sip-ua/url/url.c +++ b/libs/sofia-sip/libsofia-sip-ua/url/url.c @@ -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] == ':') { diff --git a/libs/spandsp/src/plc.c b/libs/spandsp/src/plc.c index fb1cea78be..392a7b01a6 100644 --- a/libs/spandsp/src/plc.c +++ b/libs/spandsp/src/plc.c @@ -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) { diff --git a/libs/sqlite/src/sqliteInt.h b/libs/sqlite/src/sqliteInt.h index 6483912cc9..3686a091e7 100644 --- a/libs/sqlite/src/sqliteInt.h +++ b/libs/sqlite/src/sqliteInt.h @@ -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) diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index d8797f7cd0..9e5fcf3b22 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -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); } diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 0ef64d1079..8102d038e3 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -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; diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index febaf40f75..dc8175b202 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -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); diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 5a2b8992b2..88e8152f2a 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -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 diff --git a/src/include/switch_event.h b/src/include/switch_event.h index 56acbd3a4b..9046bc711a 100644 --- a/src/include/switch_event.h +++ b/src/include/switch_event.h @@ -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 /*! diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index b08c204889..88c13379b3 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -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); diff --git a/src/include/switch_xml.h b/src/include/switch_xml.h index f1164cee2e..2d3f994878 100644 --- a/src/include/switch_xml.h +++ b/src/include/switch_xml.h @@ -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 diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index 8e6f2e124d..d0c9f6e419 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -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 */ diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.2008.vcproj b/src/mod/applications/mod_callcenter/mod_callcenter.2008.vcproj new file mode 100644 index 0000000000..85c60c56cf --- /dev/null +++ b/src/mod/applications/mod_callcenter/mod_callcenter.2008.vcproj @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.2010.vcxproj b/src/mod/applications/mod_callcenter/mod_callcenter.2010.vcxproj new file mode 100644 index 0000000000..224de6286f --- /dev/null +++ b/src/mod/applications/mod_callcenter/mod_callcenter.2010.vcxproj @@ -0,0 +1,131 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + mod_callcenter + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A} + mod_callcenter + Win32Proj + + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + + + + + + + + false + + + + + + + X64 + + + + + + + false + + + MachineX64 + + + + + + + + + false + + + + + + + X64 + + + + + + + false + + + MachineX64 + + + + + + + + {202d7a4e-760d-4d0e-afa1-d7459ced30ff} + false + + + + + + diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index f8beb7c0f7..552eee9518 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -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); - switch_xml_free(xml); + 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)))) { @@ -1877,8 +1906,16 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames h->reject_delay_time = atoi(agent_reject_delay_time); 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); } @@ -1985,45 +2021,104 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName cbt.strategy = queue_strategy; cbt.record_template = queue_record_template; cbt.agent_found = SWITCH_FALSE; - - 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")) { - sql_order_by = switch_mprintf("level, agents.talk_time, position"); - } else if (!strcasecmp(queue_strategy, "agent-with-fewest-calls")) { - sql_order_by = switch_mprintf("level, agents.calls_answered, position"); - } else if (!strcasecmp(queue_strategy, "ring-all")) { - sql = switch_mprintf("UPDATE members SET state = '%q' WHERE state = '%q' AND uuid = '%q' AND system = 'single_box'", - cc_member_state2str(CC_MEMBER_STATE_TRYING), cc_member_state2str(CC_MEMBER_STATE_WAITING), cbt.member_uuid); - cc_execute_sql(NULL, sql, NULL); - switch_safe_free(sql); - sql_order_by = switch_mprintf("level, position"); - } 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 { - /* If the strategy doesn't exist, just fallback to the following */ - 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)" - " 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); + 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")) { + sql_order_by = switch_mprintf("level, agents.talk_time, position"); + } else if (!strcasecmp(queue_strategy, "agent-with-fewest-calls")) { + sql_order_by = switch_mprintf("level, agents.calls_answered, position"); + } else if (!strcasecmp(queue_strategy, "ring-all")) { + sql = switch_mprintf("UPDATE members SET state = '%q' WHERE state = '%q' AND uuid = '%q' AND system = 'single_box'", + cc_member_state2str(CC_MEMBER_STATE_TRYING), cc_member_state2str(CC_MEMBER_STATE_WAITING), cbt.member_uuid); + 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 { + /* If the strategy doesn't exist, just fallback to the following */ + 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.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); diff --git a/src/mod/applications/mod_cidlookup/mod_cidlookup.c b/src/mod/applications/mod_cidlookup/mod_cidlookup.c index 2ec41f19e4..64e5fc7520 100755 --- a/src/mod/applications/mod_cidlookup/mod_cidlookup.c +++ b/src/mod/applications/mod_cidlookup/mod_cidlookup.c @@ -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) diff --git a/src/mod/applications/mod_cluechoo/mod_cluechoo.c b/src/mod/applications/mod_cluechoo/mod_cluechoo.c index 2699d82fc4..b4eaee0acb 100644 --- a/src/mod/applications/mod_cluechoo/mod_cluechoo.c +++ b/src/mod/applications/mod_cluechoo/mod_cluechoo.c @@ -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); diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 501b3f88b2..d7d67223e4 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -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, ""); 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, " [ ]"); SWITCH_ADD_API(commands_api_interface, "in_group", "determine if a user is in a group", in_group_function, "[@] "); SWITCH_ADD_API(commands_api_interface, "is_lan_addr", "see if an ip is a lan addr", lan_addr_function, ""); diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 57b241c57d..b9b485a1b8 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -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,82 +2530,77 @@ 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.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)); + /* Start the input thread */ + launch_conference_loop_input(member, switch_core_session_get_pool(member->session)); - if ((call_list = switch_channel_get_private(channel, "_conference_autocall_list_"))) { - const char *cid_name = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_name"); - const char *cid_num = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_number"); - const char *toval = switch_channel_get_variable(channel, "conference_auto_outcall_timeout"); - const char *flags = switch_channel_get_variable(channel, "conference_auto_outcall_flags"); - const char *profile = switch_channel_get_variable(channel, "conference_auto_outcall_profile"); - const char *ann = switch_channel_get_variable(channel, "conference_auto_outcall_announce"); - const char *prefix = switch_channel_get_variable(channel, "conference_auto_outcall_prefix"); - int to = 60; - - if (ann && !switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_REQ)) { - member->conference->special_announce = switch_core_strdup(member->conference->pool, ann); - } - - switch_channel_set_private(channel, "_conference_autocall_list_", NULL); - - switch_set_flag(member->conference, CFLAG_OUTCALL); - - if (toval) { - to = atoi(toval); - if (to < 10 || to > 500) { - to = 60; - } - } - - for (cp = call_list; cp; cp = cp->next) { - int argc; - char *argv[512] = { 0 }; - char *cpstr = strdup(cp->string); - int x = 0; - - switch_assert(cpstr); - argc = switch_separate_string(cpstr, ',', argv, (sizeof(argv) / sizeof(argv[0]))); - for (x = 0; x < argc; x++) { - char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]); - switch_assert(dial_str); - conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num, NULL, - profile, &member->conference->cancel_cause); - switch_safe_free(dial_str); - } - switch_safe_free(cpstr); - } - - do { - switch_ivr_sleep(member->session, 500, SWITCH_TRUE, NULL); - } while(switch_channel_up(channel) && member->conference->originating); - - if (!switch_channel_ready(channel)) { - member->conference->cancel_cause = SWITCH_CAUSE_ORIGINATOR_CANCEL; - goto end; - } - - conference_member_play_file(member, "tone_stream://%(500,0,640)", 0); + if ((call_list = switch_channel_get_private(channel, "_conference_autocall_list_"))) { + const char *cid_name = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_name"); + const char *cid_num = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_number"); + const char *toval = switch_channel_get_variable(channel, "conference_auto_outcall_timeout"); + const char *flags = switch_channel_get_variable(channel, "conference_auto_outcall_flags"); + const char *profile = switch_channel_get_variable(channel, "conference_auto_outcall_profile"); + const char *ann = switch_channel_get_variable(channel, "conference_auto_outcall_announce"); + const char *prefix = switch_channel_get_variable(channel, "conference_auto_outcall_prefix"); + int to = 60; + if (ann && !switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_REQ)) { + member->conference->special_announce = switch_core_strdup(member->conference->pool, ann); } + + switch_channel_set_private(channel, "_conference_autocall_list_", NULL); + + switch_set_flag(member->conference, CFLAG_OUTCALL); + + if (toval) { + to = atoi(toval); + if (to < 10 || to > 500) { + to = 60; + } + } + + for (cp = call_list; cp; cp = cp->next) { + int argc; + char *argv[512] = { 0 }; + char *cpstr = strdup(cp->string); + int x = 0; + + switch_assert(cpstr); + argc = switch_separate_string(cpstr, ',', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { + char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]); + switch_assert(dial_str); + conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num, NULL, + profile, &member->conference->cancel_cause); + switch_safe_free(dial_str); + } + 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; + goto end; + } + + 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; } diff --git a/src/mod/applications/mod_curl/mod_curl.c b/src/mod/applications/mod_curl/mod_curl.c index 633e4c80e2..adcfe453de 100644 --- a/src/mod/applications/mod_curl/mod_curl.c +++ b/src/mod/applications/mod_curl/mod_curl.c @@ -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"; } diff --git a/src/mod/applications/mod_db/mod_db.c b/src/mod/applications/mod_db/mod_db.c index e611d036ea..165e02e949 100644 --- a/src/mod/applications/mod_db/mod_db.c +++ b/src/mod/applications/mod_db/mod_db.c @@ -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; diff --git a/src/mod/applications/mod_directory/mod_directory.c b/src/mod/applications/mod_directory/mod_directory.c index 0127363064..b4c7d94e78 100644 --- a/src/mod/applications/mod_directory/mod_directory.c +++ b/src/mod/applications/mod_directory/mod_directory.c @@ -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"); diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 5d51ffdb60..5b982111d5 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -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"); diff --git a/src/mod/applications/mod_esf/mod_esf.c b/src/mod/applications/mod_esf/mod_esf.c index a2f8ddb8cd..39952f2a8c 100644 --- a/src/mod/applications/mod_esf/mod_esf.c +++ b/src/mod/applications/mod_esf/mod_esf.c @@ -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); diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 2e074138ba..1984406eff 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -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); diff --git a/src/mod/applications/mod_hash/mod_hash.c b/src/mod/applications/mod_hash/mod_hash.c index e3f01cec96..f9b808fad1 100644 --- a/src/mod/applications/mod_hash/mod_hash.c +++ b/src/mod/applications/mod_hash/mod_hash.c @@ -531,16 +531,33 @@ SWITCH_STANDARD_API(hash_api_function) return SWITCH_STATUS_SUCCESS; } -#define HASH_DUMP_SYNTAX "all|limit|db" +#define HASH_DUMP_SYNTAX "all|limit|db []" 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; @@ -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,8 +593,13 @@ SWITCH_STANDARD_API(hash_dump_function) const void *key; switch_ssize_t keylen; switch_hash_this(hi, &key, &keylen, &val); - - stream->write_function(stream, "D/%s/%s\n", key, (char*)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"); diff --git a/src/mod/applications/mod_ladspa/mod_ladspa.c b/src/mod/applications/mod_ladspa/mod_ladspa.c index 43ea87a3ca..bab6ff5216 100644 --- a/src/mod/applications/mod_ladspa/mod_ladspa.c +++ b/src/mod/applications/mod_ladspa/mod_ladspa.c @@ -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); } diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c index 93f9c9617d..fcb75ef4d5 100644 --- a/src/mod/applications/mod_lcr/mod_lcr.c +++ b/src/mod/applications/mod_lcr/mod_lcr.c @@ -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,10 +671,12 @@ 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); if (switch_core_hash_find(cbt->dedup_hash, key)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, @@ -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) { diff --git a/src/mod/applications/mod_nibblebill/mod_nibblebill.c b/src/mod/applications/mod_nibblebill/mod_nibblebill.c index 8487d0be62..068a31f5f3 100755 --- a/src/mod/applications/mod_nibblebill/mod_nibblebill.c +++ b/src/mod/applications/mod_nibblebill/mod_nibblebill.c @@ -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")) { diff --git a/src/mod/applications/mod_protovm/Makefile b/src/mod/applications/mod_protovm/Makefile new file mode 100644 index 0000000000..92f8441104 --- /dev/null +++ b/src/mod/applications/mod_protovm/Makefile @@ -0,0 +1,3 @@ +BASE=../../../.. +LOCAL_OBJS=ivr.o util.o config.o menu.o +include $(BASE)/build/modmake.rules diff --git a/src/mod/applications/mod_protovm/config.c b/src/mod/applications/mod_protovm/config.c new file mode 100644 index 0000000000..feec69b79e --- /dev/null +++ b/src/mod/applications/mod_protovm/config.c @@ -0,0 +1,130 @@ +/* Copy paste from FS mod_voicemail */ +#include + +#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; +} + diff --git a/src/mod/applications/mod_protovm/config.h b/src/mod/applications/mod_protovm/config.h new file mode 100644 index 0000000000..04713fb7ae --- /dev/null +++ b/src/mod/applications/mod_protovm/config.h @@ -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_ */ diff --git a/src/mod/applications/mod_protovm/ivr.c b/src/mod/applications/mod_protovm/ivr.c new file mode 100644 index 0000000000..4b1f6ef0cc --- /dev/null +++ b/src/mod/applications/mod_protovm/ivr.c @@ -0,0 +1,249 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Marc Olivier Chouinard + * + * + * ivr.c -- MT IVR System Interface + * + */ + +#include + +#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 + */ diff --git a/src/mod/applications/mod_protovm/ivr.h b/src/mod/applications/mod_protovm/ivr.h new file mode 100644 index 0000000000..99136475fd --- /dev/null +++ b/src/mod/applications/mod_protovm/ivr.h @@ -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); + diff --git a/src/mod/applications/mod_protovm/menu.c b/src/mod/applications/mod_protovm/menu.c new file mode 100644 index 0000000000..4dc3e19e78 --- /dev/null +++ b/src/mod/applications/mod_protovm/menu.c @@ -0,0 +1,599 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Marc Olivier Chouinard + * + * + * menu.c -- VoiceMail Menu + * + */ +#include + +#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 + */ diff --git a/src/mod/applications/mod_protovm/menu.h b/src/mod/applications/mod_protovm/menu.h new file mode 100644 index 0000000000..a2d8cb09f5 --- /dev/null +++ b/src/mod/applications/mod_protovm/menu.h @@ -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_ */ + diff --git a/src/mod/applications/mod_protovm/mod_protovm.c b/src/mod/applications/mod_protovm/mod_protovm.c new file mode 100644 index 0000000000..7d826e03c2 --- /dev/null +++ b/src/mod/applications/mod_protovm/mod_protovm.c @@ -0,0 +1,139 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Marc Olivier Chouinard + * + * + * mod_protovm.c -- MT VoiceMail System + * + */ +#include + +#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 " 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 + */ diff --git a/src/mod/applications/mod_protovm/protovm.conf.xml b/src/mod/applications/mod_protovm/protovm.conf.xml new file mode 100644 index 0000000000..e25b8760c8 --- /dev/null +++ b/src/mod/applications/mod_protovm/protovm.conf.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/applications/mod_protovm/sounds.xml b/src/mod/applications/mod_protovm/sounds.xml new file mode 100644 index 0000000000..1760e7cc07 --- /dev/null +++ b/src/mod/applications/mod_protovm/sounds.xml @@ -0,0 +1,376 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/applications/mod_protovm/util.c b/src/mod/applications/mod_protovm/util.c new file mode 100644 index 0000000000..476e99bd26 --- /dev/null +++ b/src/mod/applications/mod_protovm/util.c @@ -0,0 +1,175 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Marc Olivier Chouinard + * + * + * utils.c -- MT VoiceMail / Different utility that might need to go into the core (after cleanup) + * + */ +#include + +#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); +} + diff --git a/src/mod/applications/mod_protovm/util.h b/src/mod/applications/mod_protovm/util.h new file mode 100644 index 0000000000..1c46329e18 --- /dev/null +++ b/src/mod/applications/mod_protovm/util.h @@ -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_ */ + diff --git a/src/mod/applications/mod_redis/mod_redis.c b/src/mod/applications/mod_redis/mod_redis.c index ebf2a9e324..36376dd069 100755 --- a/src/mod/applications/mod_redis/mod_redis.c +++ b/src/mod/applications/mod_redis/mod_redis.c @@ -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; diff --git a/src/mod/applications/mod_rss/mod_rss.c b/src/mod/applications/mod_rss/mod_rss.c index b85d86bb99..073b471bb4 100644 --- a/src/mod/applications/mod_rss/mod_rss.c +++ b/src/mod/applications/mod_rss/mod_rss.c @@ -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]; diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.c b/src/mod/applications/mod_spandsp/mod_spandsp.c index d9b9ff084a..fd2ac7f947 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp.c @@ -70,33 +70,89 @@ 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; - - if (zstr(data) || strcasecmp(data, "self")) { - data = "peer"; - } - - switch_channel_set_variable(channel, "t38_leg", data); - - if ((var = switch_channel_get_variable(channel, "t38_gateway_detect_timeout"))) { - long to = atol(var); - if (to > -1) { - timeout = (time_t) (switch_epoch_time_now(NULL) + to); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s invalid timeout value.\n", switch_channel_get_name(channel)); + int argc = 0; + char *argv[2] = { 0 }; + char *dupdata; + const char *direction = NULL, *flags = NULL; + + if (!zstr(data) && (dupdata = switch_core_session_strdup(session, data))) { + if ((argc = switch_split(dupdata, ' ', argv))) { + if (argc > 0) { + direction = argv[0]; + } + + if (argc > 1) { + flags = argv[1]; + } } } + + if (zstr(direction) || strcasecmp(direction, "self")) { + direction = "peer"; + } - switch_ivr_tone_detect_session(session, "t38", "1100.0", "rw", timeout, 1, data, NULL, t38_gateway_start); + 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) { + timeout = (time_t) (switch_epoch_time_now(NULL) + to); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s invalid timeout value.\n", switch_channel_get_name(channel)); + } + } + + //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, + "[ ][ ]", 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); diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.h b/src/mod/applications/mod_spandsp/mod_spandsp.h index 09e816627a..21de3fa22b 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp.h +++ b/src/mod/applications/mod_spandsp/mod_spandsp.h @@ -68,3 +68,9 @@ switch_status_t spandsp_inband_dtmf_session(switch_core_session_t *session); switch_status_t callprogress_detector_start(switch_core_session_t *session, const char *name); switch_status_t callprogress_detector_stop(switch_core_session_t *session); + +switch_status_t spandsp_fax_detect_session(switch_core_session_t *session, + const char *flags, time_t timeout, + int hits, const char *app, const char *data, switch_tone_detect_callback_t callback); + +switch_status_t spandsp_fax_stop_detect_session(switch_core_session_t *session); diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index 4dd936b8c6..94d6bc752b 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -433,7 +433,6 @@ static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uin { switch_frame_t out_frame = { 0 }; switch_core_session_t *session; - switch_channel_t *channel; pvt_t *pvt; uint8_t pkt[LOCAL_FAX_MAX_DATAGRAM]; int x; @@ -441,22 +440,33 @@ static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uin pvt = (pvt_t *) user_data; session = pvt->session; - channel = switch_core_session_get_channel(session); /* we need to build a real packet here and make write_frame.packet and write_frame.packetlen point to it */ out_frame.flags = SFF_UDPTL_PACKET | SFF_PROXY_PACKET; out_frame.packet = pkt; - out_frame.packetlen = udptl_build_packet(pvt->udptl_state, pkt, buf, len); - - //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "WRITE %d udptl bytes\n", out_frame.packetlen); + if ((r = udptl_build_packet(pvt->udptl_state, pkt, buf, len)) > 0) { + out_frame.packetlen = r; + //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "WRITE %d udptl bytes\n", out_frame.packetlen); - for (x = 0; x < count; x++) { - if (switch_core_session_write_frame(session, &out_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { - r = -1; - break; + for (x = 0; x < count; x++) { + if (switch_core_session_write_frame(session, &out_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { + r = -1; + break; + } + } + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "INVALID PACKETLEN: %d PASSED: %d:%d\n", r, len, count); + } + + if (r < 0) { + t30_state_t *t30; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "TERMINATING T30 STATE\n"); + if (pvt->t38_state && (t30 = t38_terminal_get_t30_state(pvt->t38_state))) { + t30_terminate(t30); } } + return r; } @@ -1772,8 +1782,8 @@ switch_bool_t t38_gateway_start(switch_core_session_t *session, const char *app, switch_channel_set_variable(channel, "t38_peer", switch_core_session_get_uuid(other_session)); switch_channel_set_variable(other_channel, "t38_peer", switch_core_session_get_uuid(session)); - switch_channel_set_variable(peer ? other_channel : channel, "t38_gateway_format", "audio"); - switch_channel_set_variable(peer ? channel : other_channel, "t38_gateway_format", "udptl"); + switch_channel_set_variable(peer ? other_channel : channel, "t38_gateway_format", "udptl"); + switch_channel_set_variable(peer ? channel : other_channel, "t38_gateway_format", "audio"); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s starting gateway mode to %s\n", @@ -1803,6 +1813,250 @@ switch_bool_t t38_gateway_start(switch_core_session_t *session, const char *app, return SWITCH_FALSE; } +typedef struct { + char *app; + char *data; + char *key; + int up; + int total_hits; + int hits; + int sleep; + int expires; + int default_sleep; + int default_expires; + switch_tone_detect_callback_t callback; + modem_connect_tones_rx_state_t rx_tones; + + switch_media_bug_t *bug; + switch_core_session_t *session; + int bug_running; + +} spandsp_fax_tone_container_t; + +static switch_status_t tone_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + spandsp_fax_tone_container_t *cont = switch_channel_get_private(channel, "_fax_tone_detect_"); + + + if (!cont || dtmf->digit != 'f') { + return SWITCH_STATUS_SUCCESS; + } + + if (cont->callback) { + cont->callback(cont->session, cont->app, cont->data); + } else { + switch_channel_execute_on(switch_core_session_get_channel(cont->session), "execute_on_fax_detect"); + if (cont->app) { + switch_core_session_execute_application_async(cont->session, cont->app, cont->data); + } + } + + return SWITCH_STATUS_SUCCESS; + +} + + +static switch_bool_t tone_detect_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) +{ + spandsp_fax_tone_container_t *cont = (spandsp_fax_tone_container_t *) user_data; + switch_frame_t *frame = NULL; + switch_bool_t rval = SWITCH_TRUE; + + switch (type) { + case SWITCH_ABC_TYPE_INIT: + if (cont) { + cont->bug_running = 1; + modem_connect_tones_rx_init(&cont->rx_tones, MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE, NULL, NULL); + } + break; + case SWITCH_ABC_TYPE_CLOSE: + break; + case SWITCH_ABC_TYPE_READ_REPLACE: + case SWITCH_ABC_TYPE_WRITE_REPLACE: + { + int skip = 0; + + if (type == SWITCH_ABC_TYPE_READ_REPLACE) { + frame = switch_core_media_bug_get_read_replace_frame(bug); + } else { + frame = switch_core_media_bug_get_write_replace_frame(bug); + } + + if (cont->sleep) { + cont->sleep--; + if (cont->sleep) { + skip = 1; + } + } + + if (cont->expires) { + cont->expires--; + if (!cont->expires) { + cont->hits = 0; + cont->sleep = 0; + cont->expires = 0; + } + } + + if (!cont->up) { + skip = 1; + } + + if (skip) { + return SWITCH_TRUE; + } + + cont->hits = 0; + modem_connect_tones_rx(&cont->rx_tones, frame->data, frame->samples); + cont->hits = modem_connect_tones_rx_get(&cont->rx_tones); + + if (cont->hits) { + switch_event_t *event; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_DEBUG, + "Fax Tone Detected. [%s][%s]\n", cont->app, switch_str_nil(cont->data)); + + if (cont->callback) { + cont->callback(cont->session, cont->app, cont->data); + } else { + switch_channel_execute_on(switch_core_session_get_channel(cont->session), "execute_on_fax_detect"); + if (cont->app) { + switch_core_session_execute_application_async(cont->session, cont->app, cont->data); + } + } + + + if (switch_event_create(&event, SWITCH_EVENT_DETECTED_TONE) == SWITCH_STATUS_SUCCESS) { + switch_event_t *dup; + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detected-Fax-Tone", "true"); + + if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) { + switch_event_fire(&dup); + } + + if (switch_core_session_queue_event(cont->session, &event) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_ERROR, + "Event queue failed!\n"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true"); + switch_event_fire(&event); + } + } + + rval = SWITCH_FALSE; + } + + } + break; + case SWITCH_ABC_TYPE_WRITE: + default: + break; + } + + if (rval == SWITCH_FALSE) { + cont->bug_running = 0; + } + + return rval; +} + +switch_status_t spandsp_fax_stop_detect_session(switch_core_session_t *session) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + spandsp_fax_tone_container_t *cont = switch_channel_get_private(channel, "_fax_tone_detect_"); + + if (cont) { + switch_channel_set_private(channel, "_fax_tone_detect_", NULL); + cont->up = 0; + switch_core_media_bug_remove(session, &cont->bug); + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + +switch_status_t spandsp_fax_detect_session(switch_core_session_t *session, + const char *flags, time_t timeout, + int hits, const char *app, const char *data, switch_tone_detect_callback_t callback) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_status_t status; + spandsp_fax_tone_container_t *cont = switch_channel_get_private(channel, "_fax_tone_detect_"); + switch_media_bug_flag_t bflags = 0; + const char *var; + switch_codec_implementation_t read_impl = { 0 }; + switch_core_session_get_read_impl(session, &read_impl); + + if (cont) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Max Tones Reached!\n"); + return SWITCH_STATUS_FALSE; + } + + if (!cont && !(cont = switch_core_session_alloc(session, sizeof(*cont)))) { + return SWITCH_STATUS_MEMERR; + } + + if (app) { + cont->app = switch_core_session_strdup(session, app); + } + + if (data) { + cont->data = switch_core_session_strdup(session, data); + } + + cont->callback = callback; + cont->up = 1; + cont->session = session; + + if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_FALSE; + } + + cont->default_sleep = 25; + cont->default_expires = 250; + + if ((var = switch_channel_get_variable(channel, "fax_tone_detect_sleep"))) { + int tmp = atoi(var); + if (tmp > 0) { + cont->default_sleep = tmp; + } + } + + if ((var = switch_channel_get_variable(channel, "fax_tone_detect_expires"))) { + int tmp = atoi(var); + if (tmp > 0) { + cont->default_expires = tmp; + } + } + + if (zstr(flags)) { + bflags = SMBF_READ_REPLACE; + } else { + if (strchr(flags, 'r')) { + bflags |= SMBF_READ_REPLACE; + } else if (strchr(flags, 'w')) { + bflags |= SMBF_WRITE_REPLACE; + } + } + + bflags |= SMBF_NO_PAUSE; + + + switch_core_event_hook_add_send_dtmf(session, tone_on_dtmf); + switch_core_event_hook_add_recv_dtmf(session, tone_on_dtmf); + + + if ((status = switch_core_media_bug_add(session, "fax_tone_detect", "", + tone_detect_callback, cont, timeout, bflags, &cont->bug)) != SWITCH_STATUS_SUCCESS) { + cont->bug_running = 0; + return status; + } + + switch_channel_set_private(channel, "_fax_tone_detect_", cont); + + return SWITCH_STATUS_SUCCESS; +} + + /* For Emacs: diff --git a/src/mod/applications/mod_spandsp/udptl.c b/src/mod/applications/mod_spandsp/udptl.c index f5b3be2445..cde248c3d9 100644 --- a/src/mod/applications/mod_spandsp/udptl.c +++ b/src/mod/applications/mod_spandsp/udptl.c @@ -61,7 +61,6 @@ static int decode_open_type(const uint8_t *buf, int limit, int *len, const uint8 int octet_cnt; int octet_idx; int stat; - int i; const uint8_t **pbuf; for (octet_idx = 0, *p_num_octets = 0;; octet_idx += octet_cnt) { @@ -71,7 +70,6 @@ static int decode_open_type(const uint8_t *buf, int limit, int *len, const uint8 *p_num_octets += octet_cnt; pbuf = &p_object[octet_idx]; - i = 0; /* Make sure the buffer contains at least the number of bits requested */ if ((*len + octet_cnt) > limit) return -1; diff --git a/src/mod/applications/mod_vmd/mod_vmd.c b/src/mod/applications/mod_vmd/mod_vmd.c index 4a20df8183..3bb1e6b16e 100644 --- a/src/mod/applications/mod_vmd/mod_vmd.c +++ b/src/mod/applications/mod_vmd/mod_vmd.c @@ -237,9 +237,8 @@ static switch_bool_t process_data(vmd_session_info_t *vmd_info, switch_frame_t * double pts[P]; int16_t *data; int16_t max; - switch_ssize_t len; - len = frame->samples * sizeof(int16_t); + //len = frame->samples * sizeof(int16_t); data = (int16_t *) frame->data; for (max = (int16_t) abs(data[0]), i = 1; i < frame->samples; i++) { diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index a046021034..4d31279882 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -204,6 +204,36 @@ static switch_status_t vm_execute_sql(vm_profile_t *profile, char *sql, switch_m return status; } +char *vm_execute_sql2str(vm_profile_t *profile, switch_mutex_t *mutex, char *sql, char *resbuf, size_t len) +{ + switch_cache_db_handle_t *dbh = NULL; + + char *ret = NULL; + + if (mutex) { + switch_mutex_lock(mutex); + } + + if (!(dbh = vm_get_db_handle(profile))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n"); + goto end; + } + + ret = switch_cache_db_execute_sql2str(dbh, sql, resbuf, len, NULL); + +end: + + switch_cache_db_release_db_handle(&dbh); + + if (mutex) { + switch_mutex_unlock(mutex); + } + + return ret; + +} + + static switch_bool_t vm_execute_sql_callback(vm_profile_t *profile, switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback, void *pdata) { @@ -2384,7 +2414,6 @@ static switch_status_t deliver_vm(vm_profile_t *profile, char *vm_email = NULL; char *vm_email_from = NULL; char *vm_notify_email = NULL; - char *email_addr = NULL; char *vm_timezone = NULL; int send_mail = 0; int send_main = 0; @@ -2449,8 +2478,6 @@ static switch_status_t deliver_vm(vm_profile_t *profile, vm_notify_email = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "vm-mailfrom")) { vm_email_from = switch_core_strdup(pool, val); - } else if (!strcasecmp(var, "email-addr")) { - email_addr = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "vm-email-all-messages") && (send_main = switch_true(val))) { send_mail++; } else if (!strcasecmp(var, "vm-notify-email-all-messages") && (send_notify = switch_true(val))) { @@ -2487,12 +2514,26 @@ static switch_status_t deliver_vm(vm_profile_t *profile, goto failed; } - file_path = switch_mprintf("%s%smsg_%s_broadcast_%s", dir_path, SWITCH_PATH_SEPARATOR, use_uuid, filename); - if (copy) { + file_path = switch_mprintf("%s%smsg_%s_broadcast_%s", dir_path, SWITCH_PATH_SEPARATOR, use_uuid, filename); + + if (strlen(file_path) >= 250 /* Max size of the SQL field */) { + char *ext; + switch_safe_free(file_path); + + if (!(ext = strrchr(filename, '.'))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Filename doesn't include a file format %s\n", filename); + ret = SWITCH_STATUS_FALSE; + goto failed; + } + + ext++; + + file_path = switch_mprintf("%s%smsg_%s_broadcast_%" SWITCH_TIME_T_FMT ".%s", dir_path, SWITCH_PATH_SEPARATOR, use_uuid, switch_micro_time_now(), ext); + } + switch_file_copy(path, file_path, SWITCH_FPROT_FILE_SOURCE_PERMS, pool); } else { - switch_safe_free(file_path); file_path = (char *) path; } @@ -2957,8 +2998,6 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p int send_mail = 0; cc_t cc = { 0 }; char *read_flags = NORMAL_FLAG_STRING; - int priority = 3; - int email_attach = 1; char *operator_ext = NULL; char buf[2]; char key_buf[80]; @@ -2973,7 +3012,6 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p char *record_macro = VM_RECORD_MESSAGE_MACRO; int send_main = 0; int send_notify = 0; - int insert_db = 1; const char *read_id = NULL; const char *caller_id_name = NULL; const char *caller_id_number = NULL; @@ -3030,10 +3068,6 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p vm_storage_dir = switch_core_session_strdup(session, val); } else if (!strcasecmp(var, "vm-notify-email-all-messages") && (send_notify = switch_true(val))) { send_mail++; - } else if (!strcasecmp(var, "vm-keep-local-after-email")) { - insert_db = switch_true(val); - } else if (!strcasecmp(var, "vm-attach-file")) { - email_attach = switch_true(val); } else if (!strcasecmp(var, "vm-disk-quota")) { disk_quota = atoi(val); } else if (!strcasecmp(var, "vm-alternate-greet-id")) { @@ -3073,11 +3107,6 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Falling back to leaving message locally due to too many misconfiguration.\n"); send_mail = 0; - insert_db = 1; - } - - if (send_notify && !send_main) { - insert_db = 1; } } else { @@ -3259,7 +3288,6 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p (void) vm_macro_get(session, VM_RECORD_URGENT_CHECK_MACRO, key_buf, input, sizeof(input), 1, "", &term, profile->digit_timeout); if (*profile->urgent_key == *input) { read_flags = URGENT_FLAG_STRING; - priority = 1; (void) switch_ivr_phrase_macro(session, VM_ACK_MACRO, "marked-urgent", NULL, NULL); } else { (void) switch_ivr_phrase_macro(session, VM_ACK_MACRO, "saved", NULL, NULL); @@ -3301,7 +3329,6 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p SWITCH_STANDARD_APP(voicemail_function) { - int argc = 0; char *argv[6] = { 0 }; char *mydata = NULL; vm_profile_t *profile = NULL; @@ -3315,7 +3342,7 @@ SWITCH_STANDARD_APP(voicemail_function) 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]))); } for (;;) { @@ -4329,7 +4356,6 @@ SWITCH_STANDARD_API(voicemail_list_api_function) #define VOICEMAIL_SYNTAX "rss [ ] | [load|unload|reload] [reloadxml]" SWITCH_STANDARD_API(voicemail_api_function) { - int argc = 0; char *mydata = NULL, *argv[6]; char *host = NULL, *port = NULL, *uri = NULL; char *user = NULL, *domain = NULL; @@ -4341,7 +4367,7 @@ SWITCH_STANDARD_API(voicemail_api_function) void *val = NULL; switch_xml_t xml_root; const char *err; - + int argc = 0; if (session) { return SWITCH_STATUS_FALSE; @@ -4480,6 +4506,795 @@ SWITCH_STANDARD_API(voicemail_api_function) return SWITCH_STATUS_SUCCESS; } +struct msg_get_callback { + switch_event_t *my_params; +}; +typedef struct msg_get_callback msg_get_callback_t; + +static int message_get_callback(void *pArg, int argc, char **argv, char **columnNames) +{ + msg_get_callback_t *cbt = (msg_get_callback_t *) pArg; + + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Received-Epoch", "%s", argv[0]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Read-Epoch", "%s", argv[1]); + /* switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, user, argv[2], 255); */ + /* switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, domain, argv[3], 255); */ + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-UUID", "%s", argv[4]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Caller-Name", "%s", argv[5]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Caller-Number", "%s", argv[6]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Folder", "%s", argv[7]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-File-Path", "%s", argv[8]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Duration", "%s", argv[9]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Flags", "%s", argv[10]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Read-Flags", "%s", argv[11]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Forwarded-By", "%s", argv[12]); + + return 0; +} + +struct msg_lst_callback { + char *buf; + size_t len; + switch_event_t *my_params; +}; +typedef struct msg_lst_callback msg_lst_callback_t; + +static int message_list_callback(void *pArg, int argc, char **argv, char **columnNames) +{ + msg_lst_callback_t *cbt = (msg_lst_callback_t *) pArg; + char *varname = NULL; + /* Message # never start with 0 */ + varname = switch_mprintf("VM-List-Message-%ld-UUID", ++cbt->len); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, varname, "%s", argv[0]); + switch_safe_free(varname); + return 0; +} + +static int message_purge_callback(void *pArg, int argc, char **argv, char **columnNames) +{ + const char *profile_name = argv[0]; + const char *uuid = argv[1]; + const char *id = argv[2]; + const char *domain = argv[3]; + const char *file_path = argv[4]; + char *sql; + vm_profile_t *profile = get_profile(profile_name); + + if (unlink(file_path) != 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to delete file [%s]\n", file_path); + } else { + sql = switch_mprintf("DELETE FROM voicemail_msgs WHERE username='%q' AND domain='%q' AND uuid = '%q'", id, domain, uuid); + vm_execute_sql(profile, sql, profile->mutex); + switch_safe_free(sql); + } + profile_rwunlock(profile); + + return 0; +} + +/* Preference API */ +#define VM_FSDB_PREF_GREETING_SET_USAGE " [file-path]" +SWITCH_STANDARD_API(vm_fsdb_pref_greeting_set_function) +{ + int slot = -1; + const char *file_path = NULL; + char *sql = NULL; + char res[254] = ""; + + char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + if (argv[3]) + slot = atoi(argv[3]); + if (argv[4]) + file_path = argv[4]; + + if (!profile_name || !domain || !id || !slot) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } else { + char *dir_path = switch_core_sprintf(pool, "%s%svoicemail%s%s%s%s%s%s", SWITCH_GLOBAL_dirs.storage_dir, + SWITCH_PATH_SEPARATOR, + SWITCH_PATH_SEPARATOR, + profile->name, SWITCH_PATH_SEPARATOR, domain, SWITCH_PATH_SEPARATOR, id); + char *final_file_path = switch_core_sprintf(pool, "%s%sgreeting_%d.%s", dir_path, SWITCH_PATH_SEPARATOR, slot, profile->file_ext); + + if (file_path) { + if (switch_file_exists(file_path, pool) != SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "-ERR Filename doesn't exist\n"); + profile_rwunlock(profile); + goto done; + } + + switch_file_rename(file_path, final_file_path, pool); + } + + if (switch_file_exists(final_file_path, pool) == SWITCH_STATUS_SUCCESS) { + + sql = switch_mprintf("SELECT count(*) FROM voicemail_prefs WHERE username = '%q' AND domain = '%q'", id, domain); + vm_execute_sql2str(profile, profile->mutex, sql, res, sizeof(res)); + switch_safe_free(sql); + + if (atoi(res) == 0) { + sql = switch_mprintf("INSERT INTO voicemail_prefs (username, domain, greeting_path) VALUES('%q', '%q', '%q')", id, domain, final_file_path); + } else { + sql = switch_mprintf("UPDATE voicemail_prefs SET greeting_path = '%q' WHERE username = '%q' AND domain = '%q'", final_file_path, id, domain); + } + vm_execute_sql(profile, sql, profile->mutex); + switch_safe_free(sql); + } else { + stream->write_function(stream, "-ERR Recording doesn't exist [%s]\n", final_file_path); + } + profile_rwunlock(profile); + } + + stream->write_function(stream, "-OK\n"); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_PREF_RECNAME_SET_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_pref_recname_set_function) +{ + const char *file_path = NULL; + + char *sql = NULL; + char res[254] = ""; + + char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + if (argv[3]) + file_path = argv[3]; + + if (!profile_name || !domain || !id || !file_path) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + if (switch_file_exists(file_path, pool) != SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "-ERR Filename doesn't exist\n"); + profile_rwunlock(profile); + goto done; + } + + sql = switch_mprintf("SELECT count(*) FROM voicemail_prefs WHERE username = '%q' AND domain = '%q'", id, domain); + vm_execute_sql2str(profile, profile->mutex, sql, res, sizeof(res)); + switch_safe_free(sql); + + if (atoi(res) == 0) { + sql = switch_mprintf("INSERT INTO voicemail_prefs (username, domain, name_path) VALUES('%q', '%q', '%q')", id, domain, file_path); + } else { + sql = switch_mprintf("UPDATE voicemail_prefs SET name_path = '%q' WHERE username = '%q' AND domain = '%q'", file_path, id, domain); + } + vm_execute_sql(profile, sql, profile->mutex); + switch_safe_free(sql); + { + char *dir_path = switch_core_sprintf(pool, "%s%svoicemail%s%s%s%s%s%s", SWITCH_GLOBAL_dirs.storage_dir, + SWITCH_PATH_SEPARATOR, + SWITCH_PATH_SEPARATOR, + profile->name, SWITCH_PATH_SEPARATOR, domain, SWITCH_PATH_SEPARATOR, id); + char *final_file_path = switch_core_sprintf(pool, "%s%srecorded_name.%s", dir_path, SWITCH_PATH_SEPARATOR, profile->file_ext); + + if (switch_file_exists(file_path, pool) != SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "-ERR Filename doesn't exist\n"); + profile_rwunlock(profile); + goto done; + } + + switch_file_rename(file_path, final_file_path, pool); + + } + profile_rwunlock(profile); + stream->write_function(stream, "-OK\n"); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_PREF_PASSWORD_SET_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_pref_password_set_function) +{ + const char *password = NULL; + + char *sql = NULL; + char res[254] = ""; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + if (argv[3]) + password = argv[3]; + + if (!profile_name || !domain || !id || !password) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + sql = switch_mprintf("SELECT count(*) FROM voicemail_prefs WHERE username = '%q' AND domain = '%q'", id, domain); + vm_execute_sql2str(profile, profile->mutex, sql, res, sizeof(res)); + switch_safe_free(sql); + + if (atoi(res) == 0) { + sql = switch_mprintf("INSERT INTO voicemail_prefs (username, domain, password) VALUES('%q', '%q', '%q')", id, domain, password); + } else { + sql = switch_mprintf("UPDATE voicemail_prefs SET password = '%q' WHERE username = '%q' AND domain = '%q'", password, id, domain); + } + vm_execute_sql(profile, sql, profile->mutex); + switch_safe_free(sql); + profile_rwunlock(profile); + + stream->write_function(stream, "-OK\n"); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + + + +/* Message API */ + +#define VM_FSDB_MSG_LIST_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_msg_list_function) +{ + char *sql; + msg_lst_callback_t cbt = { 0 }; + char *ebuf = NULL; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[1]) + profile_name = argv[1]; + if (argv[2]) + domain = argv[2]; + if (argv[3]) + id = argv[3]; + + if (!profile_name || !domain || !id) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + sql = switch_mprintf("SELECT uuid FROM voicemail_msgs WHERE username = '%q' AND domain = '%q' AND read_epoch = 0 ORDER BY read_flags, created_epoch", id, domain); + + memset(&cbt, 0, sizeof(cbt)); + + switch_event_create(&cbt.my_params, SWITCH_EVENT_REQUEST_PARAMS); + + vm_execute_sql_callback(profile, profile->mutex, sql, message_list_callback, &cbt); + + profile_rwunlock(profile); + + switch_event_add_header(cbt.my_params, SWITCH_STACK_BOTTOM, "VM-List-Count", "%"SWITCH_SIZE_T_FMT, cbt.len); + switch_event_serialize_json(cbt.my_params, &ebuf); + switch_event_destroy(&cbt.my_params); + + switch_safe_free(sql); + stream->write_function(stream, "%s", ebuf); + switch_safe_free(ebuf); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_MSG_PURGE_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_msg_purge_function) +{ + char *sql; + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + + if (!profile_name || !domain || !id) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + sql = switch_mprintf("SELECT '%q', uuid, username, domain, file_path FROM voicemail_msgs WHERE username = '%q' AND domain = '%q' AND flags = 'delete'", profile_name, id, domain); + vm_execute_sql_callback(profile, profile->mutex, sql, message_purge_callback, NULL); + profile_rwunlock(profile); + + stream->write_function(stream, "-OK\n"); + +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_MSG_DELETE_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_msg_delete_function) +{ + char *sql; + const char *uuid = NULL; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + if (argv[3]) + uuid = argv[3]; + + if (!profile_name || !domain || !id || !uuid) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + sql = switch_mprintf("UPDATE voicemail_msgs SET flags = 'delete' WHERE username = '%q' AND domain = '%q' AND uuid = '%q'", id, domain, uuid); + vm_execute_sql(profile, sql, profile->mutex); + profile_rwunlock(profile); + + stream->write_function(stream, "-OK\n"); + +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_MSG_SAVE_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_msg_save_function) +{ + char *sql; + const char *uuid = NULL; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + if (argv[3]) + uuid = argv[3]; + + if (!profile_name || !domain || !id || !uuid) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + sql = switch_mprintf("UPDATE voicemail_msgs SET flags='save' WHERE username='%q' AND domain='%q' AND uuid = '%q'", id, domain, uuid); + vm_execute_sql(profile, sql, profile->mutex); + profile_rwunlock(profile); + + stream->write_function(stream, "-OK\n"); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_MSG_UNDELETE_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_msg_undelete_function) +{ + char *sql; + const char *uuid = NULL; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + if (argv[3]) + uuid = argv[3]; + + if (!profile_name || !domain || !id || !uuid) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + sql = switch_mprintf("UPDATE voicemail_msgs SET flags='' WHERE username='%q' AND domain='%q' AND uuid = '%q'", id, domain, uuid); + vm_execute_sql(profile, sql, profile->mutex); + profile_rwunlock(profile); + + stream->write_function(stream, "-OK\n"); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_AUTH_LOGIN_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_auth_login_function) +{ + char *sql; + char *password = NULL; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + char user_db_password[64] = { 0 }; + const char *user_xml_password = NULL; + + switch_event_t *params = NULL; + switch_xml_t x_user = NULL; + switch_bool_t vm_enabled = SWITCH_TRUE; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + if (argv[3]) + password = argv[3]; + + if (!profile_name || !domain || !id || !password) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + switch_event_create(¶ms, SWITCH_EVENT_GENERAL); + if (switch_xml_locate_user_merged("id", id, domain, NULL, &x_user, params) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", id, domain); + stream->write_function(stream, "-ERR User not found\n"); + } else { + switch_xml_t x_param, x_params; + + x_params = switch_xml_child(x_user, "params"); + + for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) { + const char *var = switch_xml_attr_soft(x_param, "name"); + const char *val = switch_xml_attr_soft(x_param, "value"); + if (zstr(var) || zstr(val)) { + continue; /* Ignore empty entires */ + } + + if (!strcasecmp(var, "vm-enabled")) { + vm_enabled = !switch_false(val); + } + if (!strcasecmp(var, "vm-password")) { + user_xml_password = val; + } + } + + sql = switch_mprintf("SELECT password FROM voicemail_prefs WHERE username = '%q' AND domain = '%q'", id, domain); + vm_execute_sql2str(profile, profile->mutex, sql, user_db_password, sizeof(user_db_password)); + switch_safe_free(sql); + } + + if (vm_enabled == SWITCH_FALSE) { + stream->write_function(stream, "%s", "-ERR Login Denied"); + } else if (!zstr(user_db_password)) { + if (!strcasecmp(user_db_password, password)) { + stream->write_function(stream, "%s", "-OK"); + } else { + stream->write_function(stream, "%s", "-ERR"); + } + } else if (!zstr(user_xml_password)) { + if (!strcasecmp(user_xml_password, password)) { + stream->write_function(stream, "%s", "-OK"); + } else { + stream->write_function(stream, "%s", "-ERR"); + } + } else { + stream->write_function(stream, "%s", "-ERR"); + + } + + switch_xml_free(x_user); + profile_rwunlock(profile); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_MSG_GET_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_msg_get_function) +{ + char *sql; + msg_get_callback_t cbt = { 0 }; + char *ebuf = NULL; + char *uuid = NULL; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[1]) + profile_name = argv[1]; + if (argv[2]) + domain = argv[2]; + if (argv[3]) + id = argv[3]; + if (argv[4]) + uuid = argv[4]; + + if (!profile_name || !domain || !id || !uuid) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + sql = switch_mprintf("SELECT * FROM voicemail_msgs WHERE username = '%q' AND domain = '%q' AND uuid = '%q' ORDER BY read_flags, created_epoch", id, domain, uuid); + + memset(&cbt, 0, sizeof(cbt)); + + switch_event_create(&cbt.my_params, SWITCH_EVENT_REQUEST_PARAMS); + + vm_execute_sql_callback(profile, profile->mutex, sql, message_get_callback, &cbt); + + profile_rwunlock(profile); + + switch_event_serialize_json(cbt.my_params, &ebuf); + switch_event_destroy(&cbt.my_params); + + switch_safe_free(sql); + stream->write_function(stream, "%s", ebuf); + switch_safe_free(ebuf); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_MSG_COUNT_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_msg_count_function) +{ + char *sql; + msg_cnt_callback_t cbt = { 0 }; + switch_event_t *my_params = NULL; + char *ebuf = NULL; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[1]) + profile_name = argv[1]; + if (argv[2]) + domain = argv[2]; + if (argv[3]) + id = argv[3]; + + if (!profile_name || !domain || !id) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + sql = switch_mprintf( + "SELECT 1, read_flags, count(read_epoch) FROM voicemail_msgs WHERE username = '%q' AND domain = '%q' AND in_folder = '%q' AND read_epoch = 0 GROUP BY read_flags " + "UNION " + "SELECT 0, read_flags, count(read_epoch) FROM voicemail_msgs WHERE username = '%q' AND domain = '%q' AND in_folder = '%q' AND read_epoch <> 0 GROUP BY read_flags;", + id, domain, "inbox", + id, domain, "inbox"); + + + vm_execute_sql_callback(profile, profile->mutex, sql, message_count_callback, &cbt); + + profile_rwunlock(profile); + + switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS); + switch_event_add_header(my_params, SWITCH_STACK_BOTTOM, "VM-Total-New-Messages", "%d", cbt.total_new_messages + cbt.total_new_urgent_messages); + switch_event_add_header(my_params, SWITCH_STACK_BOTTOM, "VM-Total-New-Urgent-Messages", "%d", cbt.total_new_urgent_messages); + switch_event_add_header(my_params, SWITCH_STACK_BOTTOM, "VM-Total-Saved-Messages", "%d", cbt.total_saved_messages + cbt.total_saved_urgent_messages); + switch_event_add_header(my_params, SWITCH_STACK_BOTTOM, "VM-Total-Saved-Urgent-Messages", "%d", cbt.total_saved_urgent_messages); + switch_event_serialize_json(my_params, &ebuf); + switch_event_destroy(&my_params); + + switch_safe_free(sql); + stream->write_function(stream, "%s", ebuf); + switch_safe_free(ebuf); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + SWITCH_MODULE_LOAD_FUNCTION(mod_voicemail_load) { switch_application_interface_t *app_interface; @@ -4521,6 +5336,23 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_voicemail_load) SWITCH_ADD_API(commands_api_interface, "vm_read", "vm_read", voicemail_read_api_function, VM_READ_USAGE); SWITCH_ADD_API(commands_api_interface, "vm_list", "vm_list", voicemail_list_api_function, VM_LIST_USAGE); + /* Auth API */ + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_auth_login", "vm_fsdb_auth_login", vm_fsdb_auth_login_function, VM_FSDB_AUTH_LOGIN_USAGE); + + /* Message Targeted API */ + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_msg_count", "vm_fsdb_msg_count", vm_fsdb_msg_count_function, VM_FSDB_MSG_COUNT_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_msg_list", "vm_fsdb_msg_list", vm_fsdb_msg_list_function, VM_FSDB_MSG_LIST_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_msg_get", "vm_fsdb_msg_get", vm_fsdb_msg_get_function, VM_FSDB_MSG_GET_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_msg_delete", "vm_fsdb_msg_delete", vm_fsdb_msg_delete_function, VM_FSDB_MSG_DELETE_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_msg_undelete", "vm_fsdb_msg_undelete", vm_fsdb_msg_undelete_function, VM_FSDB_MSG_UNDELETE_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_msg_purge", "vm_fsdb_msg_purge", vm_fsdb_msg_purge_function, VM_FSDB_MSG_PURGE_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_msg_save", "vm_fsdb_msg_save", vm_fsdb_msg_save_function, VM_FSDB_MSG_SAVE_USAGE); + + /* Preferences */ + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_pref_greeting_set", "vm_fsdb_pref_greeting_set", vm_fsdb_pref_greeting_set_function, VM_FSDB_PREF_GREETING_SET_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_pref_recname_set", "vm_fsdb_pref_recname_set", vm_fsdb_pref_recname_set_function, VM_FSDB_PREF_RECNAME_SET_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_pref_password_set", "vm_fsdb_pref_password_set", vm_fsdb_pref_password_set_function, VM_FSDB_PREF_PASSWORD_SET_USAGE); + return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/asr_tts/mod_cepstral/mod_cepstral.c b/src/mod/asr_tts/mod_cepstral/mod_cepstral.c index 432a0b7c99..63ed2a23d9 100644 --- a/src/mod/asr_tts/mod_cepstral/mod_cepstral.c +++ b/src/mod/asr_tts/mod_cepstral/mod_cepstral.c @@ -65,6 +65,14 @@ typedef struct { } cepstral_t; +static struct { + char *encoding; +} globals; + +SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_encoding, globals.encoding); + + + /* This callback caches the audio in the buffer */ static swift_result_t write_audio(swift_event * event, swift_event_t type, void *udata) { @@ -223,7 +231,7 @@ static switch_status_t cepstral_speech_feed_tts(switch_speech_handle_t *sh, char if (zstr(text)) { return SWITCH_STATUS_FALSE; } - swift_port_speak_file(cepstral->port, text, NULL, &cepstral->tts_stream, NULL); + swift_port_speak_file(cepstral->port, text, globals.encoding, &cepstral->tts_stream, NULL); } else { char *to_say; if (zstr(text)) { @@ -231,7 +239,7 @@ static switch_status_t cepstral_speech_feed_tts(switch_speech_handle_t *sh, char } if ((to_say = switch_mprintf(" %s ", text))) { - swift_port_speak_text(cepstral->port, to_say, 0, NULL, &cepstral->tts_stream, NULL); + swift_port_speak_text(cepstral->port, to_say, 0, globals.encoding, &cepstral->tts_stream, NULL); switch_safe_free(to_say); } } @@ -401,10 +409,54 @@ static void cepstral_float_param_tts(switch_speech_handle_t *sh, char *param, do } +static switch_status_t load_config(void) +{ + char *cf = "cepstral.conf"; + switch_xml_t cfg, xml = NULL, param, settings; + + /* Init to SWIFT default encoding */ + set_global_encoding(SWIFT_DEFAULT_ENCODING); + + if (xml = switch_xml_open_cfg(cf, &cfg, NULL)) { + if ((settings = switch_xml_child(cfg, "settings"))) { + for (param = switch_xml_child(settings, "param"); param; param = param->next) { + char *var = (char *) switch_xml_attr_soft(param, "name"); + char *val = (char *) switch_xml_attr_soft(param, "value"); + if (!strcasecmp(var, "encoding")) { + if (!strcasecmp(val, "utf-8")) { + set_global_encoding(SWIFT_UTF8); + } else if (!strcasecmp(val, "us-ascii")) { + set_global_encoding(SWIFT_ASCII); + } else if (!strcasecmp(val, "iso8859-1")) { + set_global_encoding(SWIFT_ISO_8859_1); + } else if (!strcasecmp(val, "iso8859-15")) { + set_global_encoding(SWIFT_ISO_8859_15); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown value \"%s\" for param \"%s\". Setting to default.\n", val, var); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Param \"%s\" unknown\n", var); + } + } + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Open of \"%s\" failed. Using default settings.\n", cf); + } + + if (xml) { + switch_xml_free(xml); + } + + return SWITCH_STATUS_SUCCESS; +} + SWITCH_MODULE_LOAD_FUNCTION(mod_cepstral_load) { switch_speech_interface_t *speech_interface; + memset(&globals, 0, sizeof(globals)); + load_config(); + /* Open the Swift TTS Engine */ if (!(engine = swift_engine_open(NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open Swift Engine."); diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c index 9d7c21574a..53281bc389 100644 --- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c +++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c @@ -3369,7 +3369,7 @@ static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp speech_channel_set_state(schannel, SPEECH_CHANNEL_PROCESSING); } else if (message->start_line.request_state == MRCP_REQUEST_STATE_COMPLETE) { /* RECOGNIZE failed to start */ - if (recog_hdr->completion_cause == RECOGNIZER_COMPLETION_CAUSE_UNKNOWN) { + if (!recog_hdr || recog_hdr->completion_cause == RECOGNIZER_COMPLETION_CAUSE_UNKNOWN) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) RECOGNIZE failed: status = %d\n", schannel->name, message->start_line.status_code); } else { diff --git a/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c b/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c index 0553607bfe..a5bf1ecad7 100644 --- a/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c +++ b/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c @@ -250,7 +250,6 @@ static switch_status_t switch_dahdi_encode(switch_codec_t *codec, { int32_t res; short *dbuf_linear; - unsigned char *ebuf_g729; unsigned char ebuf_ulaw[decoded_data_len / 2]; uint32_t i; struct dahdi_context *context = NULL; @@ -268,7 +267,6 @@ static switch_status_t switch_dahdi_encode(switch_codec_t *codec, } dbuf_linear = decoded_data; - ebuf_g729 = encoded_data; for (i = 0; i < decoded_data_len / sizeof(short); i++) { ebuf_ulaw[i] = linear_to_ulaw(dbuf_linear[i]); } diff --git a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c index 3bc5cb4a3d..4e62a00da8 100644 --- a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c +++ b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c @@ -164,7 +164,6 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt) int argc; char *argv[3] = { 0 }; char *pattern = NULL; - char *pri = NULL; char *app = NULL; char *argument = NULL; char *expression = NULL, expression_buf[1024] = ""; @@ -242,7 +241,7 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt) switch_channel_set_variable(channel, "CHANNEL", switch_channel_get_name(channel)); switch_channel_set_variable(channel, "UNIQUEID", switch_core_session_get_uuid(session)); - pri = argv[1]; + //pri = argv[1]; app = argv[2]; if ((argument = strchr(app, '('))) { diff --git a/src/mod/endpoints/mod_h323/changes.txt b/src/mod/endpoints/mod_h323/changes.txt index 4f75aef8b4..3af956f0cb 100644 --- a/src/mod/endpoints/mod_h323/changes.txt +++ b/src/mod/endpoints/mod_h323/changes.txt @@ -1,3 +1,4 @@ +fix race condition on destroying signaling thread in h323 library Adds an extra switch_rtp_destroy or switch_rtp_release_port when a session ends - to make sure the port is returned to FS. thx to Peter Olsson. fix issues with Progress message type if pre_answer enabled diff --git a/src/mod/endpoints/mod_h323/mod_h323.cpp b/src/mod/endpoints/mod_h323/mod_h323.cpp index 44295f618f..233e972e32 100644 --- a/src/mod/endpoints/mod_h323/mod_h323.cpp +++ b/src/mod/endpoints/mod_h323/mod_h323.cpp @@ -1,9 +1,12 @@ /* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2011, Anthony Minessale II + * H323 endpoint interface for Freeswitch Modular Media Switching Software Library / + * Soft-Switch Application * * Version: MPL 1.1 * + * Copyright (c) 2010 Ilnitskiy Mixim (max.h323@gmail.com) + * Copyright (c) 2010 Georgiewskiy Yuriy (bottleman@icf.org.ru) + * * 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 @@ -14,6 +17,11 @@ * for the specific language governing rights and limitations under the * License. * + * Contributor(s): + * + * + * + * * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is @@ -24,7 +32,7 @@ * * mod_h323.cpp -- H323 endpoint * - * Version 0.0.56 + * Version 0.0.57 */ //#define DEBUG_RTP_PACKETS @@ -708,6 +716,7 @@ FSH323Connection::FSH323Connection(FSH323EndPoint& endpoint, H323Transport* tran h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_alloc(m_fsSession, sizeof(*tech_pvt)); tech_pvt->me = this; + tech_pvt->active_connection = true; switch_core_session_set_private(m_fsSession, tech_pvt); switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(m_fsSession)); @@ -748,8 +757,9 @@ FSH323Connection::~FSH323Connection() } else if (m_RTPlocalPort) { switch_rtp_release_port((const char *)m_RTPlocalIP.AsString(), m_RTPlocalPort); } - + tech_pvt->me = NULL; + tech_pvt->active_connection = false; // switch_mutex_unlock(tech_pvt->h323_mutex); // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"------------->h323_mutex_unlock\n"); } @@ -2387,6 +2397,9 @@ static switch_status_t on_hangup(switch_core_session_t *session) switch_mutex_lock(tech_pvt->h323_mutex); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"------------->h323_mutex_unlock\n"); switch_mutex_unlock(tech_pvt->h323_mutex); - + while (tech_pvt->active_connection){ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Wait clear h323 connection\n"); + h_timer(1); + } return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/endpoints/mod_h323/mod_h323.h b/src/mod/endpoints/mod_h323/mod_h323.h index 5477f9aa59..3a0d7aa235 100644 --- a/src/mod/endpoints/mod_h323/mod_h323.h +++ b/src/mod/endpoints/mod_h323/mod_h323.h @@ -1,9 +1,12 @@ /* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2011, Anthony Minessale II + * H323 endpoint interface for Freeswitch Modular Media Switching Software Library / + * Soft-Switch Application * * Version: MPL 1.1 * + * Copyright (c) 2010 Ilnitskiy Mixim (max.h323@gmail.com) + * Copyright (c) 2010 Georgiewskiy Yuriy (bottleman@icf.org.ru) + * * 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 @@ -14,6 +17,11 @@ * for the specific language governing rights and limitations under the * License. * + * Contributor(s): + * + * + * + * * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is @@ -24,7 +32,8 @@ * * mod_h323.h -- H323 endpoint * - */ + * Version 0.0.57 +*/ #if defined(__GNUC__) && defined(HAVE_VISIBILITY) #pragma GCC visibility push(default) @@ -184,6 +193,7 @@ typedef struct { switch_mutex_t *h323_io_mutex; FSH323Connection *me; + bool active_connection; char *token; } h323_private_t; diff --git a/src/mod/endpoints/mod_portaudio/pablio.c b/src/mod/endpoints/mod_portaudio/pablio.c index b994d21c2a..05fdf0f280 100644 --- a/src/mod/endpoints/mod_portaudio/pablio.c +++ b/src/mod/endpoints/mod_portaudio/pablio.c @@ -251,7 +251,7 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, PABLIO_Stream *aStream; long numFrames; //long numBytes; - int channels = 1; + //int channels = 1; if (!(inputParameters || outputParameters)) { return -1; @@ -262,11 +262,13 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, switch_assert(aStream); memset(aStream, 0, sizeof(PABLIO_Stream)); + /* if (inputParameters) { channels = inputParameters->channelCount; } else if (outputParameters) { channels = outputParameters->channelCount; } + */ numFrames = RoundUpToNextPowerOf2(samples_per_packet * 5); aStream->bytesPerFrame = bytesPerSample; diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c index b05806b8d9..3879cca7d4 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.c +++ b/src/mod/endpoints/mod_skinny/mod_skinny.c @@ -58,7 +58,10 @@ static char devices_sql[] = " type INTEGER,\n" " max_streams INTEGER,\n" " port INTEGER,\n" - " codec_string VARCHAR(255)\n" + " codec_string VARCHAR(255),\n" + " headset INTEGER,\n" + " handset INTEGER,\n" + " speaker INTEGER\n" ");\n"; static char lines_sql[] = @@ -459,7 +462,6 @@ uint32_t skinny_line_get_state(listener_t *listener, uint32_t line_instance, uin switch_status_t skinny_tech_set_codec(private_t *tech_pvt, int force) { - int ms; switch_status_t status = SWITCH_STATUS_SUCCESS; int resetting = 0; @@ -539,7 +541,7 @@ switch_status_t skinny_tech_set_codec(private_t *tech_pvt, int force) } tech_pvt->read_frame.rate = tech_pvt->rm_rate; - ms = tech_pvt->write_codec.implementation->microseconds_per_packet / 1000; + //ms = tech_pvt->write_codec.implementation->microseconds_per_packet / 1000; if (!switch_core_codec_ready(&tech_pvt->read_codec)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Can't load codec?\n"); @@ -877,7 +879,6 @@ switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_ { switch_channel_t *channel = switch_core_session_get_channel(session); private_t *tech_pvt = switch_core_session_get_private(session); - int payload = 0; while (!(tech_pvt->read_codec.implementation && switch_rtp_ready(tech_pvt->rtp_session))) { if (switch_channel_ready(channel)) { @@ -905,7 +906,7 @@ switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_ return SWITCH_STATUS_FALSE; } - payload = tech_pvt->read_frame.payload; + //payload = tech_pvt->read_frame.payload; if (switch_rtp_has_dtmf(tech_pvt->rtp_session)) { switch_dtmf_t dtmf = { 0 }; @@ -1317,6 +1318,9 @@ static int dump_device_callback(void *pArg, int argc, char **argv, char **column char *max_streams = argv[5]; char *port = argv[6]; char *codec_string = argv[7]; + char *headset = argv[8]; + char *handset = argv[9]; + char *speaker = argv[10]; const char *line = "================================================================================================="; stream->write_function(stream, "%s\n", line); @@ -1329,6 +1333,12 @@ static int dump_device_callback(void *pArg, int argc, char **argv, char **column stream->write_function(stream, "MaxStreams \t%s\n", max_streams); stream->write_function(stream, "Port \t%s\n", port); stream->write_function(stream, "Codecs \t%s\n", codec_string); + stream->write_function(stream, "HeadsetId \t%s\n", headset); + stream->write_function(stream, "Headset \t%s\n", skinny_accessory_state2str(atoi(headset))); + stream->write_function(stream, "HandsetId \t%s\n", handset); + stream->write_function(stream, "Handset \t%s\n", skinny_accessory_state2str(atoi(handset))); + stream->write_function(stream, "SpeakerId \t%s\n", speaker); + stream->write_function(stream, "Speaker \t%s\n", skinny_accessory_state2str(atoi(speaker))); stream->write_function(stream, "%s\n", line); return 0; @@ -1337,7 +1347,7 @@ static int dump_device_callback(void *pArg, int argc, char **argv, char **column switch_status_t dump_device(skinny_profile_t *profile, const char *device_name, switch_stream_handle_t *stream) { char *sql; - if ((sql = switch_mprintf("SELECT name, user_id, instance, ip, type, max_streams, port, codec_string " + if ((sql = switch_mprintf("SELECT name, user_id, instance, ip, type, max_streams, port, codec_string, headset, handset, speaker " "FROM skinny_devices WHERE name='%s'", device_name))) { skinny_execute_sql_callback(profile, profile->sql_mutex, sql, dump_device_callback, stream); @@ -1916,10 +1926,10 @@ static switch_status_t load_skinny_config(void) switch_odbc_handle_exec(profile->master_odbc, active_lines_sql, NULL, NULL); } else { if ((db = switch_core_db_open_file(profile->dbname))) { - switch_core_db_test_reactive(db, "SELECT * FROM skinny_devices", NULL, devices_sql); - switch_core_db_test_reactive(db, "SELECT * FROM skinny_lines", NULL, lines_sql); - switch_core_db_test_reactive(db, "SELECT * FROM skinny_buttons", NULL, buttons_sql); - switch_core_db_test_reactive(db, "SELECT * FROM skinny_active_lines", NULL, active_lines_sql); + switch_core_db_test_reactive(db, "SELECT headset FROM skinny_devices", "DROP TABLE skinny_devices", devices_sql); + switch_core_db_test_reactive(db, "SELECT * FROM skinny_lines", "DROP TABLE skinny_lines", lines_sql); + switch_core_db_test_reactive(db, "SELECT * FROM skinny_buttons", "DROP TABLE skinny_buttons", buttons_sql); + switch_core_db_test_reactive(db, "SELECT * FROM skinny_active_lines", "DROP TABLE skinny_active_lines", active_lines_sql); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database!\n"); continue; diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index 8f8911f2a7..1eed692157 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -178,7 +178,7 @@ struct PACKED soft_key_event_message { /* HeadsetStatusMessage */ #define HEADSET_STATUS_MESSAGE 0x002B struct PACKED headset_status_message { - uint32_t mode; + uint32_t mode; /* 1=HeadsetOn; 2=HeadsetOff */ }; /* RegisterAvailableLinesMessage */ @@ -234,6 +234,23 @@ struct PACKED extended_data_message { #define DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE 0x0042 /* See struct PACKED extended_data_message */ +/* DialedPhoneBookMessage */ +#define DIALED_PHONE_BOOK_MESSAGE 0x0048 +struct PACKED dialed_phone_book_message { + uint32_t number_index; /* must be shifted 4 bits right */ + uint32_t line_instance; + uint32_t unknown; + char phone_number[256]; +}; + +/* AccessoryStatusMessage */ +#define ACCESSORY_STATUS_MESSAGE 0x0049 +struct PACKED accessory_status_message { + uint32_t accessory_id; + uint32_t accessory_status; + uint32_t unknown; +}; + /* RegisterAckMessage */ #define REGISTER_ACK_MESSAGE 0x0081 struct PACKED register_ack_message { @@ -507,7 +524,7 @@ struct PACKED display_prompt_status_message { }; /* ClearPromptStatusMessage */ -#define CLEAR_PROMPT_STATUS_MESSAGE 0x0113 +#define CLEAR_PROMPT_STATUS_MESSAGE 0x0113 struct PACKED clear_prompt_status_message { uint32_t line_instance; uint32_t call_id; @@ -573,6 +590,15 @@ struct PACKED service_url_stat_res_message { #define USER_TO_DEVICE_DATA_VERSION1_MESSAGE 0x013F /* See struct PACKED extended_data_message */ +/* DialedPhoneBookAckMessage */ +#define DIALED_PHONE_BOOK_ACK_MESSAGE 0x0152 +struct PACKED dialed_phone_book_ack_message { + uint32_t number_index; /* must be shifted 4 bits right */ + uint32_t line_instance; + uint32_t unknown; + uint32_t unknown2; +}; + /* XMLAlarmMessage */ #define XML_ALARM_MESSAGE 0x015A @@ -614,6 +640,8 @@ union skinny_data { struct feature_stat_req_message feature_req; /* see field "extended_data" for DEVICE_TO_USER_DATA_VERSION1_MESSAGE */ /* see field "extended_data" for DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE */ + struct dialed_phone_book_message dialed_phone_book; + struct accessory_status_message accessory_status; struct register_ack_message reg_ack; struct start_tone_message start_tone; struct stop_tone_message stop_tone; @@ -651,6 +679,7 @@ union skinny_data { struct display_pri_notify_message display_pri_notify; struct service_url_stat_res_message service_url_res; /* see field "extended_data" for USER_TO_DEVICE_DATA_VERSION1_MESSAGE */ + struct dialed_phone_book_ack_message dialed_phone_book_ack; struct data_message data; struct extended_data_message extended_data; diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index 2c338d6ce5..f6887060fc 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -588,14 +588,12 @@ switch_call_cause_t skinny_ring_lines(private_t *tech_pvt, switch_core_session_t switch_status_t skinny_session_ring_out(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { - switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; switch_assert(session); switch_assert(listener); switch_assert(listener->profile); - channel = switch_core_session_get_channel(session); tech_pvt = switch_core_session_get_private(session); send_start_tone(listener, SKINNY_TONE_ALERT, 0, line_instance, tech_pvt->call_id); @@ -732,14 +730,12 @@ switch_status_t skinny_session_start_media(switch_core_session_t *session, liste switch_status_t skinny_session_hold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { - switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; switch_assert(session); switch_assert(listener); switch_assert(listener->profile); - channel = switch_core_session_get_channel(session); tech_pvt = switch_core_session_get_private(session); skinny_session_stop_media(session, listener, line_instance); @@ -760,17 +756,15 @@ switch_status_t skinny_session_hold_line(switch_core_session_t *session, listene switch_status_t skinny_session_unhold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { - switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; switch_assert(session); switch_assert(listener); switch_assert(listener->profile); - channel = switch_core_session_get_channel(session); tech_pvt = switch_core_session_get_private(session); - skinny_hold_active_calls(listener); + skinny_hold_active_calls(listener); send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, tech_pvt->call_id); send_set_speaker_mode(listener, SKINNY_SPEAKER_ON); send_select_soft_keys(listener, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_RING_OUT, 0xffff); @@ -825,14 +819,12 @@ switch_status_t skinny_session_transfer(switch_core_session_t *session, listener switch_status_t skinny_session_stop_media(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { - switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; switch_assert(session); switch_assert(listener); switch_assert(listener->profile); - channel = switch_core_session_get_channel(session); tech_pvt = switch_core_session_get_private(session); switch_clear_flag_locked(tech_pvt, TFLAG_IO); @@ -1773,7 +1765,6 @@ switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinn uint32_t call_id = 0; switch_core_session_t *session = NULL; switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; skinny_check_data_length(request, sizeof(request->data.soft_key_event.event)); @@ -1790,7 +1781,6 @@ switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinn break; case SOFTKEY_NEWCALL: status = skinny_create_incoming_session(listener, &line_instance, &session); - tech_pvt = switch_core_session_get_private(session); skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0); break; @@ -1874,13 +1864,10 @@ switch_status_t skinny_handle_unregister(listener_t *listener, skinny_message_t switch_status_t skinny_handle_soft_key_template_request(listener_t *listener, skinny_message_t *request) { skinny_message_t *message; - skinny_profile_t *profile; switch_assert(listener->profile); switch_assert(listener->device_name); - profile = listener->profile; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.soft_key_template)); message->type = SOFT_KEY_TEMPLATE_RES_MESSAGE; message->length = 4 + sizeof(message->data.soft_key_template); @@ -1900,9 +1887,20 @@ switch_status_t skinny_handle_soft_key_template_request(listener_t *listener, sk switch_status_t skinny_headset_status_message(listener_t *listener, skinny_message_t *request) { + char *sql; + skinny_check_data_length(request, sizeof(request->data.headset_status)); - /* Nothing to do */ + if ((sql = switch_mprintf( + "UPDATE skinny_devices SET headset=%d WHERE name='%s' and instance=%d", + (request->data.headset_status.mode==1) ? SKINNY_ACCESSORY_STATE_OFFHOOK : SKINNY_ACCESSORY_STATE_ONHOOK, + listener->device_name, + listener->device_instance + ))) { + skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); + switch_safe_free(sql); + } + return SWITCH_STATUS_SUCCESS; } @@ -2012,6 +2010,66 @@ switch_status_t skinny_handle_extended_data_message(listener_t *listener, skinny return SWITCH_STATUS_SUCCESS; } +switch_status_t skinny_handle_dialed_phone_book_message(listener_t *listener, skinny_message_t *request) +{ + skinny_message_t *message; + + skinny_check_data_length(request, sizeof(request->data.dialed_phone_book)); + + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.dialed_phone_book_ack)); + message->type = DIALED_PHONE_BOOK_ACK_MESSAGE; + message->length = 4 + sizeof(message->data.dialed_phone_book_ack); + message->data.dialed_phone_book_ack.number_index = request->data.dialed_phone_book.number_index; + message->data.dialed_phone_book_ack.line_instance = request->data.dialed_phone_book.line_instance; + message->data.dialed_phone_book_ack.unknown = request->data.dialed_phone_book.unknown; + message->data.dialed_phone_book_ack.unknown2 = 0; + + return SWITCH_STATUS_SUCCESS; +} +switch_status_t skinny_handle_accessory_status_message(listener_t *listener, skinny_message_t *request) +{ + char *sql; + + skinny_check_data_length(request, sizeof(request->data.accessory_status)); + + switch(request->data.accessory_status.accessory_id) { + case SKINNY_ACCESSORY_HEADSET: + if ((sql = switch_mprintf( + "UPDATE skinny_devices SET headset=%d WHERE name='%s' and instance=%d", + request->data.accessory_status.accessory_status, + listener->device_name, + listener->device_instance + ))) { + skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); + switch_safe_free(sql); + } + break; + case SKINNY_ACCESSORY_HANDSET: + if ((sql = switch_mprintf( + "UPDATE skinny_devices SET handset=%d WHERE name='%s' and instance=%d", + request->data.accessory_status.accessory_status, + listener->device_name, + listener->device_instance + ))) { + skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); + switch_safe_free(sql); + } + break; + case SKINNY_ACCESSORY_SPEAKER: + if ((sql = switch_mprintf( + "UPDATE skinny_devices SET speaker=%d WHERE name='%s' and instance=%d", + request->data.accessory_status.accessory_status, + listener->device_name, + listener->device_instance + ))) { + skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); + switch_safe_free(sql); + } + break; + } + + return SWITCH_STATUS_SUCCESS; +} switch_status_t skinny_handle_xml_alarm(listener_t *listener, skinny_message_t *request) { @@ -2106,6 +2164,10 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re return skinny_handle_extended_data_message(listener, request); case DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE: return skinny_handle_extended_data_message(listener, request); + case DIALED_PHONE_BOOK_MESSAGE: + return skinny_handle_dialed_phone_book_message(listener, request); + case ACCESSORY_STATUS_MESSAGE: + return skinny_handle_accessory_status_message(listener, request); case XML_ALARM_MESSAGE: return skinny_handle_xml_alarm(listener, request); default: diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c index 04237ad3ea..59bb4a1f2f 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.c +++ b/src/mod/endpoints/mod_skinny/skinny_tables.c @@ -65,6 +65,8 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { {FEATURE_STAT_REQ_MESSAGE, "FeatureStatReqMessage"}, {DEVICE_TO_USER_DATA_VERSION1_MESSAGE, "DeviceToUserDataVersion1Message"}, {DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE, "DeviceToUserDataResponseVersion1Message"}, + {DIALED_PHONE_BOOK_MESSAGE, "DialedPhoneBookMessage"}, + {ACCESSORY_STATUS_MESSAGE, "AccessoryStatusMessage"}, {REGISTER_ACK_MESSAGE, "RegisterAckMessage"}, {START_TONE_MESSAGE, "StartToneMessage"}, {STOP_TONE_MESSAGE, "StopToneMessage"}, @@ -102,6 +104,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { {DISPLAY_PRI_NOTIFY_MESSAGE, "DisplayPriNotifyMessage"}, {SERVICE_URL_STAT_RES_MESSAGE, "ServiceUrlStatMessage"}, {USER_TO_DEVICE_DATA_VERSION1_MESSAGE, "UserToDeviceDataVersion1Message"}, + {DIALED_PHONE_BOOK_ACK_MESSAGE, "DialedPhoneBookAckMessage"}, {XML_ALARM_MESSAGE, "XMLAlarmMessage"}, {0, NULL} }; @@ -253,6 +256,25 @@ struct skinny_table SKINNY_DEVICE_RESET_TYPES[] = { SKINNY_DECLARE_ID2STR(skinny_device_reset_type2str, SKINNY_DEVICE_RESET_TYPES, "DeviceResetTypeUnknown") SKINNY_DECLARE_STR2ID(skinny_str2device_reset_type, SKINNY_DEVICE_RESET_TYPES, -1) +struct skinny_table SKINNY_ACCESSORY_TYPES[] = { + {SKINNY_ACCESSORY_NONE, "AccessoryNone"}, + {SKINNY_ACCESSORY_HEADSET, "Headset"}, + {SKINNY_ACCESSORY_HANDSET, "Handset"}, + {SKINNY_ACCESSORY_SPEAKER, "Speaker"}, + {0, NULL} +}; +SKINNY_DECLARE_ID2STR(skinny_accessory_type2str, SKINNY_ACCESSORY_TYPES, "AccessoryUnknown") +SKINNY_DECLARE_STR2ID(skinny_str2accessory_type, SKINNY_ACCESSORY_TYPES, -1) + +struct skinny_table SKINNY_ACCESSORY_STATES[] = { + {SKINNY_ACCESSORY_STATE_NONE, "AccessoryNoState"}, + {SKINNY_ACCESSORY_STATE_OFFHOOK, "OffHook"}, + {SKINNY_ACCESSORY_STATE_ONHOOK, "OnHook"}, + {0, NULL} +}; +SKINNY_DECLARE_ID2STR(skinny_accessory_state2str, SKINNY_ACCESSORY_STATES, "AccessoryStateUnknown") +SKINNY_DECLARE_STR2ID(skinny_str2accessory_state, SKINNY_ACCESSORY_STATES, -1) + /* For Emacs: * Local Variables: * mode:c diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h index abfdfc2aa0..383e5bb2b1 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.h +++ b/src/mod/endpoints/mod_skinny/skinny_tables.h @@ -87,7 +87,7 @@ uint32_t func(const char *str)\ } -extern struct skinny_table SKINNY_MESSAGE_TYPES[69]; +extern struct skinny_table SKINNY_MESSAGE_TYPES[72]; const char *skinny_message_type2str(uint32_t id); uint32_t skinny_str2message_type(const char *str); #define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES) @@ -248,6 +248,27 @@ const char *skinny_device_reset_type2str(uint32_t id); uint32_t skinny_str2device_reset_type(const char *str); #define SKINNY_PUSH_DEVICE_RESET_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_DEVICE_RESET_TYPES) +enum skinny_accessory_types { + SKINNY_ACCESSORY_NONE = 0x00, + SKINNY_ACCESSORY_HEADSET = 0x01, + SKINNY_ACCESSORY_HANDSET = 0x02, + SKINNY_ACCESSORY_SPEAKER = 0x03 +}; +extern struct skinny_table SKINNY_ACCESSORY_TYPES[5]; +const char *skinny_accessory_type2str(uint32_t id); +uint32_t skinny_str2accessory_type(const char *str); +#define SKINNY_PUSH_ACCESSORY_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_ACCESSORY_TYPES) + +enum skinny_accessory_states { + SKINNY_ACCESSORY_STATE_NONE = 0x00, + SKINNY_ACCESSORY_STATE_OFFHOOK = 0x01, + SKINNY_ACCESSORY_STATE_ONHOOK = 0x02 +}; +extern struct skinny_table SKINNY_ACCESSORY_STATES[4]; +const char *skinny_accessory_state2str(uint32_t id); +uint32_t skinny_str2accessory_state(const char *str); +#define SKINNY_PUSH_ACCESSORY_STATES SKINNY_DECLARE_PUSH_MATCH(SKINNY_ACCESSORY_STATES) + #endif /* _SKINNY_TABLES_H */ /* For Emacs: diff --git a/src/mod/endpoints/mod_skypopen/alsa/alsa-driver-1.0.20-dummy.c b/src/mod/endpoints/mod_skypopen/alsa/alsa-driver-1.0.20-dummy.c deleted file mode 120000 index 1635114f26..0000000000 --- a/src/mod/endpoints/mod_skypopen/alsa/alsa-driver-1.0.20-dummy.c +++ /dev/null @@ -1 +0,0 @@ -./dummy.c \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/README.skypopen_auth b/src/mod/endpoints/mod_skypopen/configs/old-stuff/README.skypopen_auth similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/README.skypopen_auth rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/README.skypopen_auth diff --git a/src/mod/endpoints/mod_skypopen/configs/copy b/src/mod/endpoints/mod_skypopen/configs/old-stuff/copy similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/copy rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/copy diff --git a/src/mod/endpoints/mod_skypopen/configs/create b/src/mod/endpoints/mod_skypopen/configs/old-stuff/create similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/create rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/create diff --git a/src/mod/endpoints/mod_skypopen/configs/multiple-instance-same-skype-username/README b/src/mod/endpoints/mod_skypopen/configs/old-stuff/multiple-instance-same-skype-username/README similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/multiple-instance-same-skype-username/README rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/multiple-instance-same-skype-username/README diff --git a/src/mod/endpoints/mod_skypopen/configs/multiple-instance-same-skype-username/multi.sh b/src/mod/endpoints/mod_skypopen/configs/old-stuff/multiple-instance-same-skype-username/multi.sh similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/multiple-instance-same-skype-username/multi.sh rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/multiple-instance-same-skype-username/multi.sh diff --git a/src/mod/endpoints/mod_skypopen/configs/multiple-instance-same-skype-username/skypopen.conf.xml b/src/mod/endpoints/mod_skypopen/configs/old-stuff/multiple-instance-same-skype-username/skypopen.conf.xml similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/multiple-instance-same-skype-username/skypopen.conf.xml rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/multiple-instance-same-skype-username/skypopen.conf.xml diff --git a/src/mod/endpoints/mod_skypopen/configs/skypopen_auth.c b/src/mod/endpoints/mod_skypopen/configs/old-stuff/skypopen_auth.c similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/skypopen_auth.c rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/skypopen_auth.c diff --git a/src/mod/endpoints/mod_skypopen/configs/startskype.sh b/src/mod/endpoints/mod_skypopen/configs/old-stuff/startskype.sh similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/startskype.sh rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/startskype.sh diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/shared.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/shared.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/shared.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/shared.xml new file mode 100644 index 0000000000..4b72e67eb5 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/shared.xml @@ -0,0 +1,99 @@ + + + + + <_2>00001000A563932E7DE5A581942041A820F8437512A079C7ACB1B73281F191D109521E265BCD38C4133596B834AD9AA1D6BB5E1AC3D59E8675785321F722D39FBFAFB9A24E6482FA3030FFA3692D2C4A53BBCE9DC63F25D10207A20FA969982FEDC1DCC2A7C599071F4735E52AB2E06E34CA232C08B3AA2FB88A0C4A5763E0CD23C3AA37D1D2A7D6EED691EE99BA08BE294F68C24F9AE777DAF294F0AEB8346325A978DC6CF7C210AD11EF3F38111F6D98F388CF41CCBA40ABE9F0D6CBBD3118BA0588344953DF3C5E88B2CCAEDE2E692F320D20EBF16D7DB36156E617C0CC9FB2855D7FDB4C7F8638CC9830E7448D5EAE301A2810277062989841EE679E00E4E277615FEC038DE3A0A20DD7C6A2A00DFBC6A2A00DA6E2B6F404FDC6A2A00DFEC6A2A00DF7FBBB990CF2C6A2A00D8EB4FE8A0C8FB4FE8A0C95C7A6E00CF5FBBB990CD6C7A6E00CD0F896950CCCE2B6F40485CCA2A00DA1D8EEA50DFDFBBB990CA7C7A6E00CA8C7A6E00CA9C7A6E00C97C7A6E00C90B4FE8A0CFE90D59308C290D59308D1E2B6F404C5E2B6F404C6AAF18705C7AAF18705C8AAF18705BBD8EEA50DBCD8EEA50DBDD8EEA50D93CCA2A00D94CCA2A00DEFE2B6F40491B4FE8A0CE2FBBB990CE3FBBB990CBED8EEA50DA0CCA2A00DA1CCA2A00DA6B4FE8A0CA7B4FE8A0CCED8EEA50DA3CCA2A00DA4CCA2A00D84E698AD0DB8C7A6E00CD9E2B6F404E0E2B6F40486E698AD0DFDF896950C0013A60400173D0018DE0200190300AB01F40300449875044518C15F9A278109D4BBAC4E8109D408A6238109D5A63304810904460CC15F9A26303ED408A624303E0047B054004801004980A305004A80E90F004BE0A801004C80A305004D01005CAC02045E5A50FC55465BA050FC55475BA050FC55485BA0C32EFDEE5BA0C32EFDEF5BA0C2A5BC4A5BA0C2A5BC4B5BA0D4BBAC055BA0D4BBAC145BA0D4BBAC215BA0D408A3575BA0D408A37D5BA0D408A37E5BA08275487E5BA0827548425BA00060B817046506CC09A3D6303E04AE018C0125F8D500021A25F9D500011A162102200301220125FFD50025FAD5000C03E4000D2580D6000F060125F8D5000302172105050103080D06010501011C210302060125FCD50025F9D5000A25FDD50025FED5000A0D06020502050119211305020380808080100C05010D0380808080100B25FDD5000C01080005000380808080100D060307010503220101220104AC01BF012597CE002597CE002590CE0019152590CE002597CE000B033C1815210220030122012593CE0014212E2594CE002103030B220125A5CE00030F172103030B22012596CE00142103030B22012597CE00142103030B22012599CE00142103030A220125A5CE00030A1A2590CE002592CE000B031E1B15142103030A220125A4CE000380201D14210303092201259BCE0014210A2594CE002103030B2201259DCE00142103030822012593CE002103012201259ECE001421030306220103022201006800006901006A01006C987504740CC2A5BC4C303ED408A34C303E007828047912CC09A3D3303E82754864303E4E8DB16F303E047DBF010203020800050003020D0B0601030308000500020501030508000500021A03060800050003041A16030508000500021D160C0A0C060203D00F251205020A03020D0A050103D00F0C0A0603010800050003FFFFFFFF0F18030208000500021D141506042512020800050003030D05040C10030205040B0C06050306050505020A0C060603040800050003050800050003E400180C0607050703E400250A0B250A011C0C0A0314100608050303C03E0F03B8171005060388270F03DC0B100508047E5E0380010304080005000B03040D250403E4000F03140D0A2503250203030D0A0B0110060101080005000380020D0302080005000380020D172103010601250A03E4001B210D0501030A03E400250A210303DF002002250A0B0D0F0601050100800180EA49008101E003036F3139352E34362E3235332E3235333A313233353000038201706F6F6C313D2A2E6C6976657461622E736B7970653B706F6F6C323D7765622E6578747261732E736B7970653B706F6F6C333D6578747261732E646F776E6C6F6164732E736B7970653B706F6F6C343D2A2E736B79706566696E642E736B7970653B706F6F6C353D2A2E7072656D69756D2E736B7970653B706F6F6C363D2A2E6D756C74696D656469612E736B7970653B706F6F6C373D2A2E6D756C74696D656469612E6D657461636166653B706F6F6C383D2A2E6D756C74696D656469612E6461696C796D6F74696F6E3B706F6F6C393D2A2E6D756C74696D656469612E6D6574616F6D6E69747572653B706F6F6C31303D77686174736E65772E736B7970653B706F6F6C31313D7061792E736B7970653B706F6F6C31323D7365637572652E7061792E736B7970653B706F6F6C31333D2A2E70696373746F72653B706F6F6C31343D2A2E6D796163636F756E742E736B7970653B706F6F6C31353D2A2E62696269743B706F6F6C31363D2A2E70726F6363796265723B706F6F6C31373D747261636B696E672E6F6D6E69747572653B706F6F6C31383D676F2E736B7970653B706F6F6C31393D747261636B2E736B7970657C706F6F6C313D3139342E3139322E3139392E3235313A31323335303B706F6F6C323D3139342E3139322E3139392E3235323A31323335303B706F6F6C333D3139342E3139322E3139392E3235323A31323335303B706F6F6C343D3139342E3136352E3138382E3130313A31323335303B706F6F6C353D3139332E39352E3135342E31353A31323335313B706F6F6C363D3139342E3136352E3138382E3130303A31323335303B706F6F6C373D3139342E3136352E3138382E3130303A31323335303B706F6F6C383D3139342E3136352E3138382E3130303A31323335303B706F6F6C393D3139342E3136352E3138382E3130303A31323335303B706F6F6C31303D3230342E392E3136332E3134313A31323335303B706F6F6C31313D3139352E34362E3235332E3234353A31323335303B706F6F6C31323D3139352E34362E3235332E3234353A31323335303B706F6F6C31333D3139332E39352E3135342E31343A31323335313B706F6F6C31343D3139332E39352E3135342E31343A31323335313B706F6F6C31353D3139332E39352E3135342E31343A31323335313B706F6F6C31363D3139332E39352E3135342E31343A31323335313B706F6F6C31373D3139342E3136352E3138382E3130303A31323335303B706F6F6C31383D3139342E3136352E3138382E3130303A31323335303B706F6F6C31393D3139332E39352E3135342E31343A31323335310003B101706F6F6C313D2A2E6C6976657461622E736B7970653B706F6F6C323D7765622E6578747261732E736B797065206578747261732E646F776E6C6F6164732E736B7970653B706F6F6C333D2A2E687773746F72652E736B7970653B706F6F6C343D2A2E736B79706566696E642E736B797065202A2E6469726563746F72792E736B7970653B706F6F6C353D2A2E70696373746F7265202A2E6D796163636F756E742E736B797065202A2E6269626974202A2E70726F63637962657220747261636B2E736B79706520617070732E736B7970656173736574733B706F6F6C363D2A2E6D756C74696D656469612E736B797065202A2E6D756C74696D656469612E6D65746163616665202A2E6D756C74696D656469612E6461696C796D6F74696F6E202A2E6D756C74696D656469612E6D6574616F6D6E6974757265207777772E736B7970652077686174736E65772E736B7970653B706F6F6C373D7061792E736B797065207365637572652E7061792E736B7970653B706F6F6C383D6170692E736B7970653B706F6F6C393D63616C6C70686F6E65732E736B7970652063616C6C72617465732E736B7970653B706F6F6C31303D2A2E7072656D69756D2E736B7970653B706F6F6C31323D6C6F67732E736B7970653B706F6F6C31333D617661746172736572766963652E736B79706520636F6E74616374696D706F72742E736B7970653B706F6F6C31343D676F2E736B7970653B706F6F6C31353D747261636B696E672E6F6D6E69747572657C706F6F6C313D3139342E3139322E3139392E3235312C31323335302C312C4E4C2C77652C35302C313B706F6F6C323D3139342E3139322E3139392E3235322C31323335302C312C444B2C77652C35302C313B706F6F6C333D3139332E39352E3135342E31372C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36322C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3232372C31323335312C312C4C552C77652C35302C31203231322E382E3136362E33332C31323335312C312C4C552C77652C35302C313B706F6F6C343D3139342E3136352E3138382E3130312C31323335302C312C49452C77652C35302C313B706F6F6C353D3139332E39352E3135342E31342C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3230352C31323335312C312C4C552C77652C35302C31203231322E3138372E3137322E35392C31323335312C312C49452C77652C35302C31203231322E382E3136362E31392C31323335312C312C4C552C77652C35302C313B706F6F6C363D3139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C31203230342E392E3136332E3134302C31323335302C312C43412C6E612C35302C313B706F6F6C373D3139352E34362E3235332E3234352C31323335302C312C4C552C77652C35302C31203139332E39352E3135342E31362C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36312C31323335312C312C49452C77652C35302C31203231322E382E3136362E32302C31323335302C312C4C552C77652C35302C313B706F6F6C383D3230342E392E3136332E3138342C31323335302C312C43412C6E612C35302C312037382E3134312E3137372E38392C31323335302C312C4C552C77652C35302C313B706F6F6C393D3139342E3136352E3138382E3131352C31323335302C312C49452C77652C35302C31203230342E392E3136332E3134312C31323335302C312C43412C6E612C35302C313B706F6F6C31303D3139332E39352E3135342E31352C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36302C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3232362C31323335312C312C4C552C77652C35302C31203231322E382E3136362E33322C31323335312C312C4C552C77652C35302C313B706F6F6C31323D37382E3134312E3137372E37362C31323335302C312C4C552C77652C35302C313B706F6F6C31333D3230342E392E3136332E3136372C31323335302C312C43412C6E612C35302C312037382E3134312E3137372E38312C31323335302C312C4C552C77652C35302C313B706F6F6C31343D3230342E392E3136332E3136382C31323335302C312C43412C6E612C35302C31203139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C313B706F6F6C31353D3230342E392E3136332E3136392C31323335302C312C43412C6E612C35302C31203139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C3100039701736B79706566696E642E736B7970653D31372C362C382C2D33392C3139206469726563746F72792E736B7970653D31372C362C382C2D33392C31390003A60138302E3235322E38352E37302C32333435362C312C6E6C2C77652C35302C312038302E3235322E38352E37312C32333435362C312C6E6C2C77652C35302C312038302E3235322E38352E37322C32333435362C312C6E6C2C77652C35302C31203139352E34362E3235332E3233382C32333435362C322C6C752C77652C35302C31203139352E34362E3235332E3233392C32333435362C322C6C752C77652C35302C31203139342E3136352E3138382E37342C32333435362C332C69652C77652C35302C31203139342E3136352E3138382E37352C32333435362C332C69652C77652C35302C31203231322E3138372E3137322E352C32333435362C342C69652C77652C35302C31203231322E3138372E3137322E32302C32333435362C342C69652C77652C35302C31203231322E3138372E3137322E33332C32333435362C342C69652C77652C35302C31203231322E382E3136332E38372C32333435362C362C6C752C77652C35302C31203231322E382E3136332E3132352C32333435362C362C6C752C77652C35302C31203231322E382E3136332E3132362C32333435362C362C6C752C77652C35302C31203133302E3131372E37322E3132362C32333435362C372C6E6C2C77652C35302C31203133302E3131372E37322E36362C32333435362C372C6E6C2C77652C35302C310004B2010B03A09C0125B3EA010B220104A5012A24A39C012102220025A19C010401F3C2011A142103030A220125B0EA0103051A2103030B2201030522010384012B39393030303131313A37382E3134312E3137372E39363A3233343536000086010C008701880E039101000493010CC2A5BC5C2774C32EFDD927740496010CD592BC1034504E8DB5F2345006C20105F801F901FA01FB01FC010395016272617465303D31206272617465313D31206272617465323D31206272617465333D31206272617465343D31206272617465353D31206272617465363D31206272617465373D31206272617465383D31207372617465303D31207372617465313D31207372617465323D31207372617465333D31207372617465343D31207372617465353D31207372617465363D31207372617465373D31207372617465383D310003B4013139342E3136352E3138382E37373A3132333530203231322E382E3136332E3130333A31323335300000C0010100C1010103CB012E6163636573732E736B7970652E6E65740000E1010F00F0010100F101A982CA950303D50137382E3134312E3137372E33383A3132333530203230342E392E3136332E3135313A31323335300003CF0137382E3134312E3137372E36393A3132333530203230342E392E3136332E3134393A31323335300000D6010103E4013139342E3136352E3138382E38303A3132333530203231322E382E3136362E353A31323335300003E5010000F8016403F7015B574845453A204F4646203130302C20563120302C20563220305D205B496E70757445513A204F46462035302C2056312035305D205B4945513A204F46462031362C2056312031322C2056322031322C2056332031322C2056342031322C2056352031322C2056362031322C2056372031325D205B53453A204453203130302C2057494F20305D205B5345323A2044532039302C2057494F2031305D205B414D504D3A204F4C442035302C20444147432035305D205B4B54523A204F46462035302C204F4E2035305D205B49414D323A204F46462039392C204D3120312C204D3220305D0003FA0152434F4E3D350003F901302F342E322E2A2E2A2C33322C3320302F352E302E2A2E2A2C31342C3320302F352E312E2A2E3130342C342C330003A80168747470733A2F2F7777775C2E70617970616C5C2E2E3F2E3F2E3F247C68747470733A2F2F696D616765735C2E70617970616C5C2E636F6D247C68747470733A2F2F7777775C2E70617970616C6F626A656374735C2E636F6D247C68747470733F3A2F2F2E2B5C2E666263646E5C2E6E6574247C68747470733F3A2F2F2E2B5C2E66616365626F6F6B5C2E636F6D247C68747470733F3A2F2F6368616E6E656C5C2E736B7970655C2E636F6D247C68747470733A2F2F617070735C2E736B7970655C2E636F6D247C68747470733F3A2F2F7161617070735C2E736B7970655C2E6E6574247C68747470733F3A2F2F636F6E6E6563745C2E66616365626F6F6B5C2E6E6574247C68747470733A2F2F2E2A5C2E736B7970656173736574735C2E636F6D247C68747470733A2F2F61645C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F61642D656D65615C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F61642D617061635C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F737461746963323F5C2E736B7970655C2E636F6D247C68747470733A2F2F7161737461746963323F5C2E736B7970655C2E6E6574247C68747470733A2F2F7072657374617469635C2E736B7970655C2E6E6574240003FF013078313030303230343030393136333231372D642D723230342E392E3136332E3231373A38313932203078313030303230343030393136333231392D642D723230342E392E3136332E3231393A38313932203078313030303230343030393136333232312D642D723230342E392E3136332E3232313A38313932203078313030303230343030393136333232332D642D723230342E392E3136332E3232333A38313932203078313030303230343030393136333232352D642D723230342E392E3136332E3232353A38313932203078313030303230343030393136333232372D642D723230342E392E3136332E3232373A38313932203078313030303230383038383138363030352D642D723230382E38382E3138362E353A38313932203078313030303230383038383138363030372D642D723230382E38382E3138362E373A38313932203078313030303230383038383138363030392D642D723230382E38382E3138362E393A38313932203078313030303230383038383138363031312D642D723230382E38382E3138362E31313A38313932203078313030303230383038383138363031332D642D723230382E38382E3138362E31333A38313932203078313030303230383038383138363031352D642D723230382E38382E3138362E31353A38313932203078313030303230383038383138363031372D642D723230382E38382E3138362E31373A38313932203078313030303230383038383138363031392D642D723230382E38382E3138362E31393A38313932203078313030303230383038383138363032312D642D723230382E38382E3138362E32313A38313932203078313030303230383038383138363032332D642D723230382E38382E3138362E32333A38313932203078313030303230383038383138363032352D642D723230382E38382E3138362E32353A38313932203078313030303230383038383138363032372D642D723230382E38382E3138362E32373A38313932203078313030303230383038383138363032392D642D723230382E38382E3138362E32393A38313932203078313030303230383038383138363033312D642D723230382E38382E3138362E33313A38313932203078313030303230383038383138363033332D642D723230382E38382E3138362E33333A38313932203078313030303230383038383138363033352D642D723230382E38382E3138362E33353A38313932203078313030303230383038383138363033372D642D723230382E38382E3138362E33373A38313932203078313030303230383038383138363033392D642D723230382E38382E3138362E33393A38313932203078313030303230383038383138363034372D642D723230382E38382E3138362E34373A38313932203078313030303230383038383138363034392D642D723230382E38382E3138362E34393A38313932203078313030303230383038383138363035312D642D723230382E38382E3138362E35313A38313932203078313030303230383038383138363035332D642D723230382E38382E3138362E35333A38313932203078313030303230383038383138363035352D642D723230382E38382E3138362E35353A38313932203078313030303230383038383138363035372D642D723230382E38382E3138362E35373A38313932203078313030303230383038383138363035392D642D723230382E38382E3138362E35393A38313932203078313030303230383038383138363036312D642D723230382E38382E3138362E36313A38313932203078313030303230383038383138363036332D642D723230382E38382E3138362E36333A38313932203078313030303230383038383138363035392D642D723230382E38382E3138362E36353A38313932203078313030303230383038383138363036312D642D723230382E38382E3138362E36373A38313932203078313030303230383038383138363036332D642D723230382E38382E3138362E36393A38313932203078313030303230383038383138363037312D642D723230382E38382E3138362E37313A38313932203078313030303230383038383138363037332D642D723230382E38382E3138362E37333A38313932203078313030303230383038383138363037352D642D723230382E38382E3138362E37353A38313932203078313030303230383038383138363037372D642D723230382E38382E3138362E37373A38313932203078313030303230383038383138363037392D642D723230382E38382E3138362E37393A38313932203078313030303230383038383138363038312D642D723230382E38382E3138362E38313A38313932203078313030303230383038383138363038332D642D723230382E38382E3138362E38333A38313932203078313030303230383038383138363038352D642D723230382E38382E3138362E38353A38313932203078313030303230383038383138363038372D642D723230382E38382E3138362E38373A38313932203078313030303230383038383138363038392D642D723230382E38382E3138362E38393A38313932203078313030303230383038383138363039312D642D723230382E38382E3138362E39313A38313932203078313030303230383038383138363039332D642D723230382E38382E3138362E39333A38313932203078313030303230383038383138363039352D642D723230382E38382E3138362E39353A38313932203078313030303230383038383138363039372D642D723230382E38382E3138362E39373A38313932203078313030303230383038383138363039392D642D723230382E38382E3138362E39393A38313932203078313030303230383038383138363130312D642D723230382E38382E3138362E3130313A38313932203078313030303230383038383138363130332D642D723230382E38382E3138362E3130333A38313932203078313030303230383038383138363130352D642D723230382E38382E3138362E3130353A38313932203078313030303230383038383138363130372D642D723230382E38382E3138362E3130373A38313932203078313030303230383038383138363130392D642D723230382E38382E3138362E3130393A38313932203078313030303230383038383138363131312D642D723230382E38382E3138362E3131313A38313932203078313030303230383038383138363131332D642D723230382E38382E3138362E3131333A38313932203078313030303230383038383138363131352D642D723230382E38382E3138362E3131353A38313932203078313030303230383038383138363131372D642D723230382E38382E3138362E3131373A38313932203078323030303134393030353034353031312D642D723134392E352E34352E31313A38313932203078323030303134393030353034353031332D642D723134392E352E34352E31333A38313932203078323030303134393030353034353031352D642D723134392E352E34352E31353A38313932203078323030303134393030353034353031372D642D723134392E352E34352E31373A38313932203078323030303134393030353034353031392D642D723134392E352E34352E31393A38313932203078323030303134393030353034353032312D642D723134392E352E34352E32313A38313932203078323030303134393030353034353032332D642D723134392E352E34352E32333A38313932203078323030303134393030353034353032352D642D723134392E352E34352E32353A38313932203078323030303134393030353034353032372D642D723134392E352E34352E32373A38313932203078323030303134393030353034353032392D642D723134392E352E34352E32393A38313932203078323030303134393030353034353033312D642D723134392E352E34352E33313A38313932203078323030303134393030353034353033332D642D723134392E352E34352E33333A38313932203078323030303134393030353034353033352D642D723134392E352E34352E33353A38313932203078323030303134393030353034353033372D642D723134392E352E34352E33373A38313932203078323030303134393030353034353033392D642D723134392E352E34352E33393A38313932203078323030303134393030353034353034312D642D723134392E352E34352E34313A38313932203078323030303134393030353034353034332D642D723134392E352E34352E34333A38313932203078323030303134393030353034353034352D642D723134392E352E34352E34353A38313932203078323030303134393030353034353034372D642D723134392E352E34352E34373A38313932203078323030303134393030353034353034392D642D723134392E352E34352E34393A38313932203078323030303134393030353034353035312D642D723134392E352E34352E35313A38313932203078323030303134393030353034353035332D642D723134392E352E34352E35333A38313932203078323030303134393030353034353035352D642D723134392E352E34352E35353A38313932203078323030303134393030353034353035372D642D723134392E352E34352E35373A38313932203078323030303134393030353034353035392D642D723134392E352E34352E35393A38313932203078323030303134393030353034353036312D642D723134392E352E34352E36313A38313932203078323030303134393030353034353036332D642D723134392E352E34352E36333A38313932203078323030303134393030353034353036352D642D723134392E352E34352E36353A38313932203078323030303134393030353034353036372D642D723134392E352E34352E36373A38313932203078323030303134393030353034353036392D642D723134392E352E34352E36393A38313932203078323030303134393030353034353037312D642D723134392E352E34352E37313A38313932203078323030303134393030353034353037332D642D723134392E352E34352E37333A38313932203078323030303134393030353034353037352D642D723134392E352E34352E37353A38313932203078323030303134393030353034353037372D642D723134392E352E34352E37373A38313932203078323030303134393030353034353037392D642D723134392E352E34352E37393A38313932203078323030303134393030353034353038312D642D723134392E352E34352E38313A38313932203078323030303134393030353034353038332D642D723134392E352E34352E38333A38313932203078323030303134393030353034353038352D642D723134392E352E34352E38353A38313932203078323030303134393030353034353038372D642D723134392E352E34352E38373A38313932203078323030303134393030353034353038392D642D723134392E352E34352E38393A38313932203078323030303134393030353034353039312D642D723134392E352E34352E39313A38313932203078323030303134393030353034353039332D642D723134392E352E34352E39333A38313932203078323030303134393030353034353039352D642D723134392E352E34352E39353A38313932203078323030303134393030353034353039372D642D723134392E352E34352E39373A38313932203078323030303134393030353034353039392D642D723134392E352E34352E39393A38313932203078323030303134393030353034353130312D642D723134392E352E34352E3130313A38313932203078323030303134393030353034353130332D642D723134392E352E34352E3130333A38313932203078323030303134393030353034353130352D642D723134392E352E34352E3130353A38313932203078323030303134393030353034353130372D642D723134392E352E34352E3130373A38313932203078323030303134393030353034353130392D642D723134392E352E34352E3130393A38313932203078323030303134393030353034353131312D642D723134392E352E34352E3131313A38313932203078323030303134393030353034353131332D642D723134392E352E34352E3131333A38313932203078323030303134393030353034353131352D642D723134392E352E34352E3131353A38313932203078323030303134393030353034353131372D642D723134392E352E34352E3131373A38313932203078323030303134393030353034353131392D642D723134392E352E34352E3131393A38313932203078323030303134393030353034353132312D642D723134392E352E34352E3132313A38313932203078323030303134393030353034353132332D642D723134392E352E34352E3132333A38313932203078323030303134393030353034353132352D642D723134392E352E34352E3132353A38313932203078323030303134393030353034353132372D642D723134392E352E34352E3132373A38313932203078323030303134393030353034353132392D642D723134392E352E34352E3132393A38313932000089020A062E19AEBFD5A40B80D4B6B30280D2AFF205808CFD910B80DEB9F1048FA486F4049CA486F404D5A486F404ACC686F404C2C686F404878F87F404CEB887F404ADC487F404BCC687F404D4D087F404F9EA87F4049CF587F404C8F487F404C9F487F404CAF487F404EACCBB9C05F7CCBB9C05E694D7BB058E96D7BB05A896D7BB050094023C0095021400930201039902536B79706520546563686E6F6C6F6769657320534100008E0200008F0280BAB70300910280A30503F2013231332E3134362E3138392E3230313A3132333530203231332E3134362E3138392E3230323A3132333530203231332E3134362E3138392E3230333A3132333530203231332E3134362E3138392E3230343A3132333530203231332E3134362E3138392E3230353A3132333530203231332E3134362E3138392E3230363A3132333530203231322E3136312E382E31303A3132333530203231322E3136312E382E323A3132333530203231322E3136312E382E333A3132333530203231322E3136312E382E343A3132333530203231322E3136312E382E353A3132333530203231322E3136312E382E363A31323335300000FC010106FD0106011E64AC02A403E807009002C20103C301687474703A2F2F37392E3132352E36332E3732247C68747470733F3A2F2F2E2B5C2E66616365626F6F6B5C2E636F6D240000DE0148 + <_256>000010011AC0AA3BA66DF7FB48228AE35F9BB4A032FE4A6A898DA7A1A5AE37DC59FB3D09607F1CACD46A5DBC008DABF8F09C797DF5A8903307D04C318825CEA7C481303C655A9EEE099E9A0AF1158373B458BB8FDACB336A6EC63C043E6782688E2350B417DDDDFF96B474DAEA7D1DF3742303B79111FC752BFB5D6887A5B822F945CC761FAF6E80DE5EC60868768CB8A9F9C876137806DCEA0DD1300181558ABFDBA26592078F5F84195C526D8C7F339EF82700FD93F8FB71ADA5ED3E977D27FA52D1F489EF5DA0A9E00B146BADCBDEBFB0DFEBCD61E5B8352A49893357E0DC3A736743929DA975782EA4D8184605FD064641986C47706D264281C876F926BF58003E9E + <_3>0000100498ECF8A7A4585F76C930739A1EAE590DE96D9EF3AA9B231E67965F3F08ECFC493E1DA23ECDE17A85C94CBE034E88F9414E9BBC82F32AAFCFFB2C09F6F57A478238BAEC9EEF2BB9C67F71257722E6786D88D6400F6B7D81450FB3B6CCCC3986E3782D2387E354EBA9099331AEF510D479C6601D2383D866E2B5B525DF0BA975D58C120EFAE88C89EE365FC696CC891B77F67CFA18FDE8E95DDAC25A7C7D70FA7A1414BAE593856A658888C622836006C1C131B4B2E805554DCFA52F3EFD34C1B759BF8A302E491835DCE701E84D37ED150C8ADD699AD3DCA9F515123C5B5AD94E253E173BA3465E64A0079D5EF4E6075E66D0F5FBC3D9BC25C4E80C4CB2FE9B87040003000004D00F0005D00F050041040400B80125C20003141B14230025D50003031B14230024E100142300250003191714230025EA0003141714230025EA00011724EA00140A14230025E400030F1C14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025E10025E10003A006100A0309031725000325180C0A25C20003140B0C03040D0A03882725C3000C0A03E43225C4000C0A0602050228038407DC08FA1E0601050102050203FA1E1C0603250028061D1E1F202122060105010205010503050141060300636F756E74206279207175616C697479000001CC080002040003000004010005010501410603006261647175616C69747920636F756E742062792076657273696F6E000001D6080002070003000004010005010501410603006261647175616C6974792073756D2062792076657273696F6E000001E0080002070003000004010005010500410304005424E400142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025E40025E40028043CB401D804901C060105010205014106030073756D206F66206C61737463616C6C206475726174696F6E73000001B009000201000300000480A3050005B054050141060300636F756E74206279206C61737463616C6C206475726174696F6E000001BA090002050003000004010005010500410204005025EB00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EB0028031E32D0000601050102050141060300636F756E742062792073797374656D20637075207573616765000001940A0002040003000004010005010500410204004F25EC00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EC0028030F1E320601050102050141060300636F756E742062792070726F63657373206370752075736167650000019E0A0002040003000004010005010500410304006824C20014230024E60014230025E600011A14230025EC00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EC0028030F1E320601050102050125C2000501410603006A6974746572636F756E742062792070726F6365737320637075207573616765000001F80A0002040003000004010005010501410603006A69747465722062792070726F6365737320637075207573616765000001820B0002040003000004D00F0005D00F0500410304004424E700142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A1423000225E700050141060300706F74656E7469616C207463702066616C6C6261636B73000001DC0B00020100030000040100050105014106030061637475616C207463702066616C6C6261636B73000001E60B00020100030000040100050105004103040056240C142300250C030A1814230025EA0003141714230025EA00011724EA00140A14230024E70014230025E700011A14230024E50014230025E500011C0602250C29050306070809280401020405060105010205010502050141060300636F756E74206279206E617474797065000001C00C0002050003000004010005010501410603007564706661696C75726573206279206E617474797065000001CA0C0002050003000004010005010500410204001B25D90014230025D90025DA000B0602050228030102040601050102050141060300636F756E74206279206E726F666D756C74696368617473000001A40D0002040003000004010005010500410304001425F700011C14230025000319171423000225F90005014106030075736572732077686F206861766520636F6D706C65746564204943000001880E0002010003000004010005010501410603006C617374204943207969656C6420676C6F62616C73756D000001920E0002010003000004E8070005500500410304001224F60014230025000319171423000225F60005014106030075736572732077686F206861766520494320737570706F7274000001EC0E0002010003000004010005010501410603004943207374617274757020636F756E7420676C6F62616C73756D000001F60E00020100030000046400051405004102040025240C142300250C030A18142300250C011C142300250C280802030405060708090601050102050141060300636F756E74206279206E617474797065000001D00F0002090003000004010005010500410404001A250003191714230025E20025E30025FC00280201020601050102050141060300766964656F2073656E642063617061626C650000019811000201000300000401000501050141060300766964656F20706172616C6C656C2063616C6C730000019911000201000300000414000502050141060300636F756E7420627920766964656F2063616C6C73206D616465000001A2110002030003000004010005010500410204003A250003191714230025EA0003141714230025EA00011724EA00140A14230024E50014230025E50003031914230025E50028030102030601050102050141060300636F756E742062792073747265616D7472616E73706F7274000001FC11000204000300000401000501050041090400E00125C20003141B25E400030F1C1514230024E100142300250003191714230025EA0003141725EA0001171514230025FF002580010A011A14230025E60003031A25E50003031A1514230024F5001423002412142300249F0114230025C30025E10025E10003A006100A03A0060B0309031725000325180C0A25C20003140B0C03040D0A2512030A0C251025F5001703CC080C0A1C160602020502250003231B241D150603050305020503150503251D03808080808080808080011D14150603050305020503150503251D038080808080808080C0011D1415060305030502050315050141060300706F74656E7469616C2052555F756E65787065637465645F62616471000001E01200020100030000040100050105014106030061637475616C2052555F756E65787065637465645F62616471000001EA1200020100030000040100050105014106030042435020706F74656E7469616C2052555F756E65787065637465645F62616471000001F4120002010003000004010005010501410603004243502061637475616C2052555F756E65787065637465645F62616471000001FE12000201000300000401000501050141060300424350203220706F74656E7469616C2052555F756E65787065637465645F62616471000001881300020100030000040100050105014106030042435020322061637475616C2052555F756E65787065637465645F626164710000019213000201000300000401000501050141060300424350203420706F74656E7469616C2052555F756E65787065637465645F626164710000019C130002010003000004010005010501410603004243502031362061637475616C2052555F756E65787065637465645F62616471000001A6130002010003000004010005010500410304000825B801011C25B701050141060300757365727320696E207075626C6963206368617473000001C4130002010003000004010005010501410603007075626C69632063686174206D6573736167657320696E206C617374206D696E757465000001CE1300020100030000046400050A0500410404005F248E0114230024D5001423002500032B1B1423002500032B1C250D03021C16250E03FFFFFFFF0F1D03B4E2C8F10217250E0380808080100D03B4E2C8F10217151614230025D500280219C80106010501020501258E010501258E0103880E1C050141060300636F756E742062792062756464696573000001A814000203000300000401000501050141060300617661696C6162696C697479206167652062792062756464696573000001B2140002030003000004C0FC150005A099020501410603006C6F6E6720617661696C6162696C697479206167652062792062756464696573000001BC140002030003000004010005010500410204003324C000142300250003191714230025F301290300E5C68583B7AEDE36F2CAB9A3A7AE983806020502280202030601050125C00005014106030073696D756C74616E656F75732063616C6C7320706572206E616D6573706163650000018C15000203000300000419000519050041020400C50125C00006020502142300250006030503031917142300050303231B06040504210302200225A1010605050421030502200225A2010606030606070505021A050503021A160506021A15210305072002010607050203021B050603021B152103050720020206070502021A050603021B15210305072002030206070502021A050503041A15210305072002030306070502021A050503031A15210305072002030406070502021A050503051A152103050720020305060705072806010203040506060105010205014106030063616C6C6572733A207332735F313120636F6E665F686F737420636F6E665F636C69656E7420736B7970656F757420736B797065696E20766F6963656D61696C20756E6B6E6F776E000001F015000207000300000401000501 + <_4>000010052A0B6759B71FBC1EF05BE97DFEA4EE6C1E15AF19ED70DEC1130B14C13CE41246D302B9662592907E3CA508A57702B5C00C2A05170857FA22012E0F235B425B4D919B23A541D3AD6E948FC634DE71A29493634884DFD5E9D89C5D951CBCD71B9B3ABFD3C4E2779BB1817D76E7C223CA36BD75A6A05B730AF138057E4048B2FFDD522BB588EC0B9D3E014BF9E354EB608150BC613C739D9E8C7465F05F047FAF7AFA3EE89B9B58BF0FC35F07B55CF3E4B59A7C4ED48B1C0C7F0305E6AC2E80AAEAD6064EB6ACDC1806FCE0B5CB66F0840DA7F0FE7B228E3898E3E42A9AFEFE13DDF019EF8D8F02A631AF2615BBC6E1EDB65C89A775F642C88109E6247EC4B463DC302E2A2E323000050541020006020307322E302E2A2E3100050541030006020307322E302E2A2E3200000AE4ED8009050541030006020307322E302E2A2E33000009B3E6CC990B050541040006020307322E302E2A2E3400000AE4ED8009000BA00B050541030006020308322E302E2A2E35000307322E302E2A2E3900050541040006020308322E302E2A2E39000307322E302E2A2E313100000AE4ED8009050541040006020308322E302E2A2E3131000307322E302E2A2E3135000009E6CC99B306050541050006020308322E302E2A2E3135000307322E302E2A2E323000000AE4ED8009000BA00B050041050303557067726164655465737433000301332E302E302E3130300003044E6963654272616E6400050541040006020307332E302E302E2A0003074E6963654272616E6400000AE4ED8009050541040006020307322E302E302E2A0003074E6963654272616E6400000AE4ED80090500410E0303557067726164655465737433000301332E302E302E31303000050541040006020307332E302E302E39390003074F746865724272616E6400000AE4ED8009050541040006020307322E302E302E39390003074F746865724272616E6400000AE4ED8009050541040006020307332E302E302E39380003074F746865724272616E64000009B3E6CC990B050541040006020307322E302E302E39380003074F746865724272616E64000009B3E6CC990B050541050006020307332E302E302E39370003074F746865724272616E6400000AE4ED8009000BA00B050541050006020307322E302E302E39370003074F746865724272616E6400000AE4ED8009000BA00B050541030006020307332E302E302E393900000AE4ED8009050541030006020307322E302E302E393900000AE4ED8009050541030006020307332E302E302E3938000009B3E6CC990B050541030006020307322E302E302E3938000009B3E6CC990B050541040006020307332E302E302E393700000AE4ED8009000BA00B050541040006020307322E302E302E393700000AE4ED8009000BA00B0500410303033130303031000301302E302E302E313000050541020006020307302E302E302E3900 + <_5>00001006739CA527EF827847E16F23CD52458C3EBA3460A42935EC6948BEFA626B49E3BDF279FC62486E2DDBCA19609ED23D31F4E5175920F282AD74A74A997C3909E67B622480C68A058E886C7D5F3C40954880D7798CD61CEA0FBAFB389BE5B2B8A887348F7AADB4DF642B194B814047CDA0E698EDDE61DFA731DCA5883A76F913D8C94066718054E85ADA7AE009F2B2A9AF762FDCB9B6CAF64C156911E3AB172CFD795F66FB6E8E15048A54E4AB17979D6C447DEBADE75CC6F606050D980061112AFF9AE7C7BF8065D711949E41FA4C8B6CBF0916BB395B3E186A7D617D353C6BFFC687FE79475DFA095D113D70B828FB597BC3665B7C9C3669CA9CBE5D308D3FC23803044E45544745415200050541020006040307302E392E302E2A000500410503033130303033000301312E302E302E3137000304534D4300050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E312E302E313000030442454C4B494E00050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E302E302E3137000304454447452D434F524500050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E302E302E31330003044C4F474954454300050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303035000301312E342E38382E31333636000304544F50434F4D00050541020006040307312E342E38382E3133353600050541020006020307312E342E38382E31333635000500410503033130303035000301312E342E38382E313336360003045043484F4D4500050541020006040307312E342E38382E3133353600050541020006020307312E342E38382E31333635000500410403033130303036000301302E302E302E313000050541020006040307302E302E302E3500050541020006020307302E302E302E39000500410503033130303037000301312E302E312E330003045445434F00050541020006040307312E302E302E3800050541020006020307312E302E312E31000500410503033130303038000301302E392E332E3339370003044C494E4B53595300050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410503033130303038000301302E392E332E3339370003044E45544745415200050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410503033130303038000301302E392E332E3339370003045048494C49505300050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410403033130303130000301302E392E302E31310003044C494E4B53595300050541020006040307302E392E302E3130000500410403033130303130000301302E392E302E313100030442554646414C4F00050541020006040307302E392E302E3130000500410503033130303132000301312E302E302E310003044353544E00050541020006040307302E302E302E3500050541020006020307302E302E302E39000500410503033130303133000301302E302E332E3234000304414B00050541020006040307302E302E312E323400050541020006020307302E302E322E3234000500410303033130303134000301312E372E34332E33382E3200050541020006040307312E372E32332E32372E34000500410503033130303135000301312E322E31372E30000304415A5445434800050541020006040307312E322E31312E3000050541020006020307312E322E31352E30000500410303033130303230000301312E302E302E343700050541030006020308312E302E302E3233000307312E302E302E3233000500410403033130303234000301332E322E302E323800050541030006040308332E302E302E35000307332E302E302E3500050541030006020308332E312E302E31000307332E322E302E38000500410503033130303232000301302E302E302E3900030450414E41534F4E494300050541020006040307302E302E302E3100050541020006020307302E302E302E38000500410503033130303232000301302E302E302E3900030450414E41534F4E4943434F4E53554D455200050541020006040307302E302E302E3100050541020006020307302E302E302E3800 + + 1 + + 400 + + + + 8118 + 39,64,8184 + 37,50,13164 + + 1 + + 1 + + + -1431699456 + -1431699456 + 1610612735 + + 41C801050041050200D9AF0D45D9E900010400028788BCED0400038788BCED04000400050041050200BB0AB3FDD1A40001040002B7DCBCED040003B7DCBCED040004000500410502005C3766C2DA6B00010400029FB2BCED0400039FB2BCED04000400050041050200D9F8DC20CA33000104000296DAAAED04000396DAAAED0400040005004105020063847B3765900001040002D794BDED040003D794BDED040004000500410502004E80142FD3C70001040002CF86BDED040003CF86BDED04000400050041050200C3B213EA24A50001040002BF89BBED040003BF89BBED040004000500410502006FFEF1BA804C0001040002CF86BDED040003CF86BDED0400040005004105020052ED923CB3A700010400028788BCED0400038788BCED040004000500410502005243330D305B000104000283FFB2ED04000383FFB2ED040004000500410502006FF9438E9E5D0001040002CF86BDED040003CF86BDED04000400050041050200585515F19D77000104000283FFB2ED04000383FFB2ED04000400050041050200729EE3A8DD460001040002CF86BDED040003CF86BDED040004000500410502004572795D3BB300010400029FB2BCED0400039FB2BCED040004000500410502009F94D72CABA40001040002CF86BDED040003CF86BDED0400040005004105020095052D9C81090001040002B7DCBCED040003B7DCBCED040004000500410502005859A15FD7FC0001040002DC8FB5ED040003DC8FB5ED0400040005004105020059D7AB3EBBFB0001020002F8FABCED040003CF86BDED04000400050041050200BB2481B9390E0001040002CF86BDED040003CF86BDED0400040005004105020059D7F395A7BA0001040002B7DCBCED040003B7DCBCED040004000500410502006DC4BEF5D52E0001040002B0DFBAED040003B0DFBAED040004000500410502004B6E709CF4290001040002B7DCBCED040003B7DCBCED040004000500410502007A7D5CEC2B8D0001040002CF86BDED040003CF86BDED040004000500410502006FFFA8AFB19D0001040002B7DCBCED040003B7DCBCED040004000500410502003E4475A07A6F0001040002B7DCBCED040003B7DCBCED040004000500410502003EDD8384A4F90001040002BF89BBED040003BF89BBED04000400050041050200560FBFA4E4900001040002B7DCBCED040003B7DCBCED04000400050041050200C24FAEEE43F10001040002B3CEB5ED040003B3CEB5ED040004000500410502004F378778C6F30001040002CF86BDED040003CF86BDED04000400050041050200C94418BB0EDF0001040002B7DCBCED040003B7DCBCED040004000500410502003B75A58BECB30001040002CF86BDED040003CF86BDED04000400050041050200772A7A0908890001040002CF86BDED040003CF86BDED0400040005004105020048BB63586DE100010400029088BCED0400039088BCED040004000500410502005544F881BEDA000104000283FFB2ED04000383FFB2ED040004000500410502005B4C1468EDF80001040002B7DCBCED040003B7DCBCED04000400050041050200538BAF3F934F0001040002B3CEB5ED040003B3CEB5ED0400040005004105020055D6F93A4FD70001040002D7B3BBED040003D7B3BBED04000400050041050200D5D64561E55F00010400028788BCED0400038788BCED0400040005004105020046ADF229B8570001040002CF86BDED040003CF86BDED04000400050041050200D5151C19FFD600010200029FB2BCED040003B7DCBCED04000400050041050200973CA35DB82400010400029FB2BCED0400039FB2BCED04000400050041050200C249E5B953700001040002CF86BDED040003CF86BDED04000400050041050200722C69D8C4F500010400029FB2BCED0400039FB2BCED0400040005004105020058CBB311F2400001040002DC8FB5ED040003DC8FB5ED040004000500410502004BB7A090766E0001040002CF86BDED040003CF86BDED040004000500410502007DEF80FBEBD90001040002EFDDBBED040003EFDDBBED0400040005004105020076A03698F87A0001040002CF86BDED040003CF86BDED0400040005004105020050E5DFDD0C700001040002CF86BDED040003CF86BDED040004000500410502004D4C85E0CEC80001040002CF86BDED040003CF86BDED040004000500410502006FEA6BCD92A10001020002F8FABCED040003CF86BDED0400040005004105020043BAA930F28600010400029FB2BCED0400039FB2BCED04000400050041050200722DB82DDB780001040002CF86BDED040003CF86BDED0400040005004105020052E995118B9F0001040002CF86BDED040003CF86BDED040004000500410502005403013B36D20001040002EFDDBBED040003EFDDBBED04000400050041050200B27C0C920B260001040002B7DCBCED040003B7DCBCED04000400050041050200D9AF0997A7450001040002BCD9AAED040003BCD9AAED04000400050041050200BC00130BB5F60001040002CF86BDED040003CF86BDED04000400050041050200591FF23B53830001040002CF86BDED040003CF86BDED04000400050041050200557EB01367590001040002CF86BDED040003CF86BDED04000400050041050200505F157093A2000102000297A4BCED04000397A4BCED040004000500410502003A036C495C670001040002CF86BDED040003CF86BDED0400040005004105020050D8CF0B7D480001040002B7DCBCED040003B7DCBCED040004000500410502004E34E4D0FF250001040002B7DCBCED040003B7DCBCED040004000500410502007A1E50A46E770001040002CF86BDED040003CF86BDED040004000500410502005F18C666CBB80001040002EFDDBBED040003EFDDBBED04000400050041050200C19335603A9E0001040002DC8FB5ED040003DC8FB5ED0400040005004105020097142BD7DF890001040002AFDFBAED040003AFDFBAED0400040005004105020052F3355FFED400010400029FB2BCED0400039FB2BCED04000400050041050200BCBA857EECDF0001040002D7B3BBED040003D7B3BBED04000400050041050200729259D605EF0001040002CF86BDED040003CF86BDED04000400050041050200BEC2F57655B300010400029FB2BCED0400039FB2BCED040004000500410502005BD905C8304B0001020002A8EEBBED0400038788BCED0400040005004105020055F2C0360F360001040002EFDDBBED040003EFDDBBED0400040005004105020082C01DB9605D00010400028788BCED0400038788BCED04000400050041050200BC73B8FB30360001040002CF86BDED040003CF86BDED0400040005004105020050390E32DF8B0001040002B0DFBAED040003B0DFBAED040004000500410502005BCE8A2D7B8000010400028788BCED0400038788BCED0400040005004105020042292BB45D2D0001040002CF86BDED040003CF86BDED040004000500410502004F1A354DCA9A00010400029FB2BCED0400039FB2BCED04000400050041050200591C1D7F0EC900010400028788BCED0400038788BCED04000400050041050200722E9D2CCB030001040002CF86BDED040003CF86BDED04000400050041050200443AB71D3F8A0001040002CF86BDED040003CF86BDED0400040005004105020018DEF34EB70600010400028788BCED0400038788BCED0400040005004105020097215860080F00010400029FB2BCED0400039FB2BCED040004000500410502007229C156A49E0001040002B7DCBCED040003B7DCBCED040004000500410502003A72EDECB0250001040002B3F7B4ED040003B3F7B4ED04000400050041050200D52F8CD18F640001040002E285B0ED040003E285B0ED040004000500410502006B0325208B4C0001040002EFDDBBED040003EFDDBBED040004000500410502005164424285660001040002938AB5ED040003938AB5ED04000400050041050200D4E9D6AB12F80001040002AFDFBAED040003AFDFBAED0400040005004105020059B3090F459C0001040002FCDDAAED040003FCDDAAED04000400050041050200BC10C41E7AAB0001040002CF86BDED040003CF86BDED040004000500410502009F9532B560C100010400028788BCED0400038788BCED0400040005004105020050EA7B4A63750001040002CF86BDED040003CF86BDED0400040005004105020045A658245E790001040002CF86BDED040003CF86BDED0400040005004105020047E3059299620001040002CF86BDED040003CF86BDED0400040005004105020081164AFC3B450001040002CF86BDED040003CF86BDED040004000500410502005703C3FC60FF00010400028788BCED0400038788BCED0400040005004105020063FAEB02F39300010400028788BCED0400038788BCED040004000500410502005714F2D9F6650001020002AFDFBAED040003ECE7BAED04000400050041050200505F1B22B00D0001040002CF86BDED040003CF86BDED0400040005004105020062C2F2A80C7900010400029FB2BCED0400039FB2BCED04000400050041050200425CA6CCD1FF0001040002CF86BDED040003CF86BDED0400040005004105020084C778D4AB110001040002CF86BDED040003CF86BDED040004000500410502005106437CD3B60001040002CF86BDED040003CF86BDED0400040005004105020058506B2B47D40001040002D7B3BBED040003D7B3BBED04000400050041050200DD70204563390001040002B7DCBCED040003B7DCBCED040004000500410502005CFFA5BE4A0000010200028888BCED040003F8FABCED0400040005004105020089BD8692E0400001040002B7DCBCED040003B7DCBCED040004000500410502004AC12BB2AB8D0001040002B7DCBCED040003B7DCBCED04000400050041050200DB555CBAEE6B0001040002CF86BDED040003CF86BDED0400040005004105020095052D8F81090001020002A7FDBCED040003CF86BDED04000400050041050200473AA0E1C9110001020002A7FDBCED040003CF86BDED040004000500410502004EFA971D2E4C0001040002B7DCBCED040003B7DCBCED04000400050041050200BCE6C5A829D900010400029E90B5ED0400039E90B5ED0400040005004105020051699F18DC540001040002D7B3BBED040003D7B3BBED040004000500410502005CFB85D7E6460001040002B3CEB5ED040003B3CEB5ED0400040005004105020052D17CE5A9840001040002BF89BBED040003BF89BBED0400040005004105020054DD54C818F20001040002CF86BDED040003CF86BDED040004000500410502005C3555EBDC670001040002B7DCBCED040003B7DCBCED0400040005004105020051D92EE554370001040002BF89BBED040003BF89BBED0400040005004105020095549556182D0001040002CF86BDED040003CF86BDED040004000500410502005419C1F7F52A0001040002B3CEB5ED040003B3CEB5ED040004000500410502008C7259638E1D0001040002B7DCBCED040003B7DCBCED04000400050041050200516745231C2200010400029FB2BCED0400039FB2BCED0400040005004105020055FB3DEAE2380001040002B7DCBCED040003B7DCBCED040004000500410502005D5470BCB83A00010400028788BCED0400038788BCED0400040005004105020054C6D511E6810001040002CF86BDED040003CF86BDED0400040005004105020062A7FAC0119000010200028788BCED0400038888BCED040004000500410502007225A1DCFB1A00010200028788BCED0400038888BCED04000400050041050200708B358CF15C00010400028788BCED0400038788BCED04000400050041050200D9A293C3FE550001040002AFDFBAED040003AFDFBAED04000400050041050200722119BAFCB600010400029FB2BCED0400039FB2BCED0400040005004105020054369C95EAC60001040002CF86BDED040003CF86BDED04000400050041050200AE74419813810001040002B7DCBCED040003B7DCBCED0400040005004105020048C613BC68510001040002EFDDBBED040003EFDDBBED04000400050041050200516E168D638B0001040002EFDDBBED040003EFDDBBED040004000500410502001819CFB484D20001040002CF86BDED040003CF86BDED04000400050041050200ADE013B3E9F10001040002CF86BDED040003CF86BDED040004000500410502005C708ABFAC890001040002B3CEB5ED040003B3CEB5ED04000400050041050200BC81882E891C0001040002B7DCBCED040003B7DCBCED0400040005004105020057785543EB480001040002CF86BDED040003CF86BDED040004000500410502006FF0CE6CB4500001040002CF86BDED040003CF86BDED040004000500410502005CE13B7199D4000102000283ADE7E304000383ADE7E30400040005004105020063F610137D170001040002B7DCBCED040003B7DCBCED04000400050041050200DC887BC89E210001040002CF86BDED040003CF86BDED040004000500410502005D9324151E7F0001020002A7FDBCED040003CF86BDED04000400050041050200BC02D363924D00010400029FB2BCED0400039FB2BCED040004000500410502004F28848E1AC50001040002CF86BDED040003CF86BDED0400040005004105020054C606DD0D260001040002D984B5ED040003D984B5ED04000400050041050200D5F586558C850001040002BF89BBED040003BF89BBED0400040005004105020082582B0468CF00010400028788BCED0400038788BCED040004000500410502005CE21BB9BD7C00010400029FB2BCED0400039FB2BCED0400040005004105020059A9ACE3BC02000104000296DAAAED04000396DAAAED040004000500410502005557DB28EDA300010400028788BCED0400038788BCED0400040005004105020076ABA00FF52C0001040002CF86BDED040003CF86BDED0400040005004105020052185C5CB8440001040002B7DCBCED040003B7DCBCED04000400050041050200441402A770A800010200028788BCED0400038888BCED04000400050041050200516623CC99760001040002CF86BDED040003CF86BDED040004000500410502005A3D6D867C2A0001040002BF89BBED040003BF89BBED04000400050041050200BC70864FCE530001040002B3F7B4ED040003B3F7B4ED040004000500410502005E9C9B4E7A740001040002CF86BDED040003CF86BDED0400040005004105020058ABF63F0EA70001040002FCDDAAED040003FCDDAAED040004000500410502005556BDBE86AC000104000286FFB2ED04000386FFB2ED0400040005004105020059D0D49C9B8000010400028788BCED0400038788BCED0400040005004105020059A934952E920001040002B3F7B4ED040003B3F7B4ED040004000500410502007220ABEC82C80001040002B7DCBCED040003B7DCBCED04000400050041050200807AB45544310001040002BF89BBED040003BF89BBED04000400050041050200187A8DFCCDCF0001040002BF89BBED040003BF89BBED04000400050041050200616B5C35801000010400028788BCED0400038788BCED040004000500410502005ABCE5EAE3790001040002938AB5ED040003938AB5ED0400040005004105020048DF5F3311D10001020002F8FABCED040003CF86BDED04000400050041050200D3146B24D6340001040002CF86BDED040003CF86BDED0400040005004105020059037023AC7D00010400029FB2BCED0400039FB2BCED040004000500410502003EDD92C929340001040002BF89BBED040003BF89BBED040004000500410502004C4EB0C1270D0001040002CF86BDED040003CF86BDED04000400050041050200BCA300CD17370001040002CF86BDED040003CF86BDED040004000500410502005BC42D9E789A0001040002D7B3BBED040003D7B3BBED04000400050041050200589755D3E75F0001020002D884B5ED040003B3CEB5ED040004000500410502007A7CC86B21530001040002CF86BDED040003CF86BDED040004000500410502005352A2DA24D300010400028788BCED0400038788BCED0400040005004105020058C9F9B6A86F0001040002B7DCBCED040003B7DCBCED040004000500410502005706A79DEAE60001020002AFDFBAED040003ECE7BAED0400040005004105020082D1B28F7A3A0001040002CF86BDED040003CF86BDED0400040005004105020052217343E79C0001040002CF86BDED040003CF86BDED0400040005004105020082CEA3A289FE000104000296DAAAED04000396DAAAED04000400050041050200D9E0FF79D1180001040002B7DCBCED040003B7DCBCED0400040005004105020052FD31513EE90001040002938AB5ED040003938AB5ED0400040005004105020052128CCDBA7C00010400029FB2BCED0400039FB2BCED040004000500410502006FB83DA167580001040002CF86BDED040003CF86BDED040004000500410502002E14B9387F540001020002B7DCBCED040003CF86BDED040004000500410502004F7E6F098A990001040002CF86BDED040003CF86BDED040004000500410502005D98B7099E1F0001040002B7DCBCED040003B7DCBCED04000400050041050200722A7476317600010400029FB2BCED0400039FB2BCED04000400050041050200BC18CE5EBDA10001020002AFDFBAED040003ECE7BAED040004000500410502005CF890CF3E270001040002B7DCBCED040003B7DCBCED040004000500410502008D72AE6DBEE30001040002CF86BDED040003CF86BDED0400040005004105020076A6D8E9EAAB0001040002CF86BDED040003CF86BDED04000400050041050200721B63925A140001040002CF86BDED040003CF86BDED040004000500410502007608B348A53A0001040002CF86BDED040003CF86BDED04000400 + + 0 + + -645574544 + 0 + 47500 + + 1 + + + 217.133.80.112:1076 217.133.80.112:47500 217.133.80.112:1083 217.133.80.112:1083 217.133.80.112:49734 + 7 + + <_1303289856>6C81442204F3D9855070B98CAE5879A505F3D9855070B98C4D4320134B66D9855070B98C5F4E60ED0D34D98550700434 + <_1303293952>4287274ED659D9855070B98C4287274ED74BD9855070B98C4287274EC15CD9855070B98C4287274ECE92D9855070B98C4287274EA75BD9855070B98C4287274E4B98D9855070B98C4287274EAA2DD9855070B98C4287274EA175D9855070B98C4287274ED735D9855070B98C4287274EAE25D9855070B98C4287274E1A2BD9855070B98C3D7D44372576D9855070B98CCF86DF304366D9855070B98C3D2E02A2259CD9855070B98C4287274EB98CD9855070B98C + <_1303298048>2E3363049108D9855070B98C2E3795FA3202D9855070B98C2E2F6F42E86DD9855070B98CB4B0620AA528D9855070B98C + <_1303306240>5F1894D8122BD9855070B98C2E40484969A3D9855070B98CD592A70A5566D9855070B98C2E26119F8DBED9855070B98C2E3754264E48D9855070B98C + <_1303314432>4D2BFFCAEC6CD9855070043B54BAD08D05E0D9855070B98C9D9D4DA11995D9855070B98C59584CCBB5CED9855070B98C972AC71733DDD9855070B98C + <_1303322624>5F3B0DCEB535D9855070043BD5150C1746D3D9855070B98C4D4B8646EF29D9855070B98CD5152F4D12BBD9855070B98C + <_1303326720>59D0D11D89DCD9855070C2462E755D8E1E97D9855070B98C2E492F875789D9855070B98C2E378784E9C6D9855070B98C2E2F6F6B48FCD9855070B98C + + + <_1303289856>9A4A56D31C619325C6601C71B23E13FDFAF5CA49F15C34A4E33F239B524D6BBC226021F010D2270A3B48DFA2E8CDB6FD37531B1118DB2D471CB980D0 + <_1303293952>D5A2186D0B45088ADDFA7B626C0904CED47E3DF13172672AED483E1EAD69DB781ABEC0D8812B1B5EFF91BC28C67FB5A3404D875A + <_1303298048>DB0EC5161D10171C7C6A4C7109DD + <_1303302144>5379BD98 + <_1303306240>88B19442A48D863ED54D712EEC36D53127BCE36653FE + <_1303310336>1908404B0F7BA3BE952CB1C533456D3CDA410BCB774AF93880FB8BD8C110 + <_1303314432>4B015AD444DD027FD3F61B2A51A53BA0 + <_1303322624>878BAF81A9F053B39E35081485E24B4EDA5F79D37E176C409B6E237A336451F42CFA7CEC013C98A18B51 + <_1303326720>CFB137906F6CCE77246BD5B6B434875570B1F9B9140C85D5114EE6953110B04F3557C0D1686D46A9F69106521979AE49E19F8622F93A + <_1303330816>BA4B81F735FDCDA4E4EF57ACF8A37051C66401E41CA4E562A5A49ACC2E246CCE + + + + 1 + + + 1 + + + 0 + + + 1 + + + + 9BF92EA4B417A7F6 + + + 4102030E322F322E302E302E37322F31373400000FF6EB9ADC04 + + + 0 + + + + 2 + en + + 357 + 258 + 0 + 0 + + 0 + + diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/config.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/config.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/config.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/config.xml new file mode 100644 index 0000000000..f7af8873ad --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/config.xml @@ -0,0 +1,74 @@ + + + + + 300 + 1800 + 63 + + + 41010300676D6172757A7A3400 + 1268962216 + + + 0 + 0 + 1303202372 + 0 + + + 35716ecf:2 + 98e6c103:0 + + + + + + 1 + 3 + 65535 + 1266110339 + + + 1 + + + 1 + + + 1000000166 + 1303166852 + 1303209779 + + + 1267114269 + + 2 + + 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 + + + 1267114267 + 11 + 4263C0064DD5ACF9A03594DAB928D2B81510 + + + noone + 1 + noone + + + <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 + + + + + skypopen + + + 0 + 2 + 2 + 2 + + diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/httpfe/cookies.dat new file mode 100644 index 0000000000..fc7f2b1150 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/httpfe/cookies.dat @@ -0,0 +1 @@ +B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/index2.dat new file mode 100644 index 0000000000..b8b96d8431 Binary files /dev/null and b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/index2.dat differ diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/main.lock new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.xml new file mode 100644 index 0000000000..f7af8873ad --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.xml @@ -0,0 +1,74 @@ + + + + + 300 + 1800 + 63 + + + 41010300676D6172757A7A3400 + 1268962216 + + + 0 + 0 + 1303202372 + 0 + + + 35716ecf:2 + 98e6c103:0 + + + + + + 1 + 3 + 65535 + 1266110339 + + + 1 + + + 1 + + + 1000000166 + 1303166852 + 1303209779 + + + 1267114269 + + 2 + + 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 + + + 1267114267 + 11 + 4263C0064DD5ACF9A03594DAB928D2B81510 + + + noone + 1 + noone + + + <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 + + + + + skypopen + + + 0 + 2 + 2 + 2 + + diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/httpfe/cookies.dat new file mode 100644 index 0000000000..fc7f2b1150 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/httpfe/cookies.dat @@ -0,0 +1 @@ +B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/index2.dat new file mode 100644 index 0000000000..b8b96d8431 Binary files /dev/null and b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/index2.dat differ diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/main.lock new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.xml new file mode 100644 index 0000000000..4b72e67eb5 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.xml @@ -0,0 +1,99 @@ + + + + + <_2>00001000A563932E7DE5A581942041A820F8437512A079C7ACB1B73281F191D109521E265BCD38C4133596B834AD9AA1D6BB5E1AC3D59E8675785321F722D39FBFAFB9A24E6482FA3030FFA3692D2C4A53BBCE9DC63F25D10207A20FA969982FEDC1DCC2A7C599071F4735E52AB2E06E34CA232C08B3AA2FB88A0C4A5763E0CD23C3AA37D1D2A7D6EED691EE99BA08BE294F68C24F9AE777DAF294F0AEB8346325A978DC6CF7C210AD11EF3F38111F6D98F388CF41CCBA40ABE9F0D6CBBD3118BA0588344953DF3C5E88B2CCAEDE2E692F320D20EBF16D7DB36156E617C0CC9FB2855D7FDB4C7F8638CC9830E7448D5EAE301A2810277062989841EE679E00E4E277615FEC038DE3A0A20DD7C6A2A00DFBC6A2A00DA6E2B6F404FDC6A2A00DFEC6A2A00DF7FBBB990CF2C6A2A00D8EB4FE8A0C8FB4FE8A0C95C7A6E00CF5FBBB990CD6C7A6E00CD0F896950CCCE2B6F40485CCA2A00DA1D8EEA50DFDFBBB990CA7C7A6E00CA8C7A6E00CA9C7A6E00C97C7A6E00C90B4FE8A0CFE90D59308C290D59308D1E2B6F404C5E2B6F404C6AAF18705C7AAF18705C8AAF18705BBD8EEA50DBCD8EEA50DBDD8EEA50D93CCA2A00D94CCA2A00DEFE2B6F40491B4FE8A0CE2FBBB990CE3FBBB990CBED8EEA50DA0CCA2A00DA1CCA2A00DA6B4FE8A0CA7B4FE8A0CCED8EEA50DA3CCA2A00DA4CCA2A00D84E698AD0DB8C7A6E00CD9E2B6F404E0E2B6F40486E698AD0DFDF896950C0013A60400173D0018DE0200190300AB01F40300449875044518C15F9A278109D4BBAC4E8109D408A6238109D5A63304810904460CC15F9A26303ED408A624303E0047B054004801004980A305004A80E90F004BE0A801004C80A305004D01005CAC02045E5A50FC55465BA050FC55475BA050FC55485BA0C32EFDEE5BA0C32EFDEF5BA0C2A5BC4A5BA0C2A5BC4B5BA0D4BBAC055BA0D4BBAC145BA0D4BBAC215BA0D408A3575BA0D408A37D5BA0D408A37E5BA08275487E5BA0827548425BA00060B817046506CC09A3D6303E04AE018C0125F8D500021A25F9D500011A162102200301220125FFD50025FAD5000C03E4000D2580D6000F060125F8D5000302172105050103080D06010501011C210302060125FCD50025F9D5000A25FDD50025FED5000A0D06020502050119211305020380808080100C05010D0380808080100B25FDD5000C01080005000380808080100D060307010503220101220104AC01BF012597CE002597CE002590CE0019152590CE002597CE000B033C1815210220030122012593CE0014212E2594CE002103030B220125A5CE00030F172103030B22012596CE00142103030B22012597CE00142103030B22012599CE00142103030A220125A5CE00030A1A2590CE002592CE000B031E1B15142103030A220125A4CE000380201D14210303092201259BCE0014210A2594CE002103030B2201259DCE00142103030822012593CE002103012201259ECE001421030306220103022201006800006901006A01006C987504740CC2A5BC4C303ED408A34C303E007828047912CC09A3D3303E82754864303E4E8DB16F303E047DBF010203020800050003020D0B0601030308000500020501030508000500021A03060800050003041A16030508000500021D160C0A0C060203D00F251205020A03020D0A050103D00F0C0A0603010800050003FFFFFFFF0F18030208000500021D141506042512020800050003030D05040C10030205040B0C06050306050505020A0C060603040800050003050800050003E400180C0607050703E400250A0B250A011C0C0A0314100608050303C03E0F03B8171005060388270F03DC0B100508047E5E0380010304080005000B03040D250403E4000F03140D0A2503250203030D0A0B0110060101080005000380020D0302080005000380020D172103010601250A03E4001B210D0501030A03E400250A210303DF002002250A0B0D0F0601050100800180EA49008101E003036F3139352E34362E3235332E3235333A313233353000038201706F6F6C313D2A2E6C6976657461622E736B7970653B706F6F6C323D7765622E6578747261732E736B7970653B706F6F6C333D6578747261732E646F776E6C6F6164732E736B7970653B706F6F6C343D2A2E736B79706566696E642E736B7970653B706F6F6C353D2A2E7072656D69756D2E736B7970653B706F6F6C363D2A2E6D756C74696D656469612E736B7970653B706F6F6C373D2A2E6D756C74696D656469612E6D657461636166653B706F6F6C383D2A2E6D756C74696D656469612E6461696C796D6F74696F6E3B706F6F6C393D2A2E6D756C74696D656469612E6D6574616F6D6E69747572653B706F6F6C31303D77686174736E65772E736B7970653B706F6F6C31313D7061792E736B7970653B706F6F6C31323D7365637572652E7061792E736B7970653B706F6F6C31333D2A2E70696373746F72653B706F6F6C31343D2A2E6D796163636F756E742E736B7970653B706F6F6C31353D2A2E62696269743B706F6F6C31363D2A2E70726F6363796265723B706F6F6C31373D747261636B696E672E6F6D6E69747572653B706F6F6C31383D676F2E736B7970653B706F6F6C31393D747261636B2E736B7970657C706F6F6C313D3139342E3139322E3139392E3235313A31323335303B706F6F6C323D3139342E3139322E3139392E3235323A31323335303B706F6F6C333D3139342E3139322E3139392E3235323A31323335303B706F6F6C343D3139342E3136352E3138382E3130313A31323335303B706F6F6C353D3139332E39352E3135342E31353A31323335313B706F6F6C363D3139342E3136352E3138382E3130303A31323335303B706F6F6C373D3139342E3136352E3138382E3130303A31323335303B706F6F6C383D3139342E3136352E3138382E3130303A31323335303B706F6F6C393D3139342E3136352E3138382E3130303A31323335303B706F6F6C31303D3230342E392E3136332E3134313A31323335303B706F6F6C31313D3139352E34362E3235332E3234353A31323335303B706F6F6C31323D3139352E34362E3235332E3234353A31323335303B706F6F6C31333D3139332E39352E3135342E31343A31323335313B706F6F6C31343D3139332E39352E3135342E31343A31323335313B706F6F6C31353D3139332E39352E3135342E31343A31323335313B706F6F6C31363D3139332E39352E3135342E31343A31323335313B706F6F6C31373D3139342E3136352E3138382E3130303A31323335303B706F6F6C31383D3139342E3136352E3138382E3130303A31323335303B706F6F6C31393D3139332E39352E3135342E31343A31323335310003B101706F6F6C313D2A2E6C6976657461622E736B7970653B706F6F6C323D7765622E6578747261732E736B797065206578747261732E646F776E6C6F6164732E736B7970653B706F6F6C333D2A2E687773746F72652E736B7970653B706F6F6C343D2A2E736B79706566696E642E736B797065202A2E6469726563746F72792E736B7970653B706F6F6C353D2A2E70696373746F7265202A2E6D796163636F756E742E736B797065202A2E6269626974202A2E70726F63637962657220747261636B2E736B79706520617070732E736B7970656173736574733B706F6F6C363D2A2E6D756C74696D656469612E736B797065202A2E6D756C74696D656469612E6D65746163616665202A2E6D756C74696D656469612E6461696C796D6F74696F6E202A2E6D756C74696D656469612E6D6574616F6D6E6974757265207777772E736B7970652077686174736E65772E736B7970653B706F6F6C373D7061792E736B797065207365637572652E7061792E736B7970653B706F6F6C383D6170692E736B7970653B706F6F6C393D63616C6C70686F6E65732E736B7970652063616C6C72617465732E736B7970653B706F6F6C31303D2A2E7072656D69756D2E736B7970653B706F6F6C31323D6C6F67732E736B7970653B706F6F6C31333D617661746172736572766963652E736B79706520636F6E74616374696D706F72742E736B7970653B706F6F6C31343D676F2E736B7970653B706F6F6C31353D747261636B696E672E6F6D6E69747572657C706F6F6C313D3139342E3139322E3139392E3235312C31323335302C312C4E4C2C77652C35302C313B706F6F6C323D3139342E3139322E3139392E3235322C31323335302C312C444B2C77652C35302C313B706F6F6C333D3139332E39352E3135342E31372C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36322C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3232372C31323335312C312C4C552C77652C35302C31203231322E382E3136362E33332C31323335312C312C4C552C77652C35302C313B706F6F6C343D3139342E3136352E3138382E3130312C31323335302C312C49452C77652C35302C313B706F6F6C353D3139332E39352E3135342E31342C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3230352C31323335312C312C4C552C77652C35302C31203231322E3138372E3137322E35392C31323335312C312C49452C77652C35302C31203231322E382E3136362E31392C31323335312C312C4C552C77652C35302C313B706F6F6C363D3139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C31203230342E392E3136332E3134302C31323335302C312C43412C6E612C35302C313B706F6F6C373D3139352E34362E3235332E3234352C31323335302C312C4C552C77652C35302C31203139332E39352E3135342E31362C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36312C31323335312C312C49452C77652C35302C31203231322E382E3136362E32302C31323335302C312C4C552C77652C35302C313B706F6F6C383D3230342E392E3136332E3138342C31323335302C312C43412C6E612C35302C312037382E3134312E3137372E38392C31323335302C312C4C552C77652C35302C313B706F6F6C393D3139342E3136352E3138382E3131352C31323335302C312C49452C77652C35302C31203230342E392E3136332E3134312C31323335302C312C43412C6E612C35302C313B706F6F6C31303D3139332E39352E3135342E31352C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36302C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3232362C31323335312C312C4C552C77652C35302C31203231322E382E3136362E33322C31323335312C312C4C552C77652C35302C313B706F6F6C31323D37382E3134312E3137372E37362C31323335302C312C4C552C77652C35302C313B706F6F6C31333D3230342E392E3136332E3136372C31323335302C312C43412C6E612C35302C312037382E3134312E3137372E38312C31323335302C312C4C552C77652C35302C313B706F6F6C31343D3230342E392E3136332E3136382C31323335302C312C43412C6E612C35302C31203139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C313B706F6F6C31353D3230342E392E3136332E3136392C31323335302C312C43412C6E612C35302C31203139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C3100039701736B79706566696E642E736B7970653D31372C362C382C2D33392C3139206469726563746F72792E736B7970653D31372C362C382C2D33392C31390003A60138302E3235322E38352E37302C32333435362C312C6E6C2C77652C35302C312038302E3235322E38352E37312C32333435362C312C6E6C2C77652C35302C312038302E3235322E38352E37322C32333435362C312C6E6C2C77652C35302C31203139352E34362E3235332E3233382C32333435362C322C6C752C77652C35302C31203139352E34362E3235332E3233392C32333435362C322C6C752C77652C35302C31203139342E3136352E3138382E37342C32333435362C332C69652C77652C35302C31203139342E3136352E3138382E37352C32333435362C332C69652C77652C35302C31203231322E3138372E3137322E352C32333435362C342C69652C77652C35302C31203231322E3138372E3137322E32302C32333435362C342C69652C77652C35302C31203231322E3138372E3137322E33332C32333435362C342C69652C77652C35302C31203231322E382E3136332E38372C32333435362C362C6C752C77652C35302C31203231322E382E3136332E3132352C32333435362C362C6C752C77652C35302C31203231322E382E3136332E3132362C32333435362C362C6C752C77652C35302C31203133302E3131372E37322E3132362C32333435362C372C6E6C2C77652C35302C31203133302E3131372E37322E36362C32333435362C372C6E6C2C77652C35302C310004B2010B03A09C0125B3EA010B220104A5012A24A39C012102220025A19C010401F3C2011A142103030A220125B0EA0103051A2103030B2201030522010384012B39393030303131313A37382E3134312E3137372E39363A3233343536000086010C008701880E039101000493010CC2A5BC5C2774C32EFDD927740496010CD592BC1034504E8DB5F2345006C20105F801F901FA01FB01FC010395016272617465303D31206272617465313D31206272617465323D31206272617465333D31206272617465343D31206272617465353D31206272617465363D31206272617465373D31206272617465383D31207372617465303D31207372617465313D31207372617465323D31207372617465333D31207372617465343D31207372617465353D31207372617465363D31207372617465373D31207372617465383D310003B4013139342E3136352E3138382E37373A3132333530203231322E382E3136332E3130333A31323335300000C0010100C1010103CB012E6163636573732E736B7970652E6E65740000E1010F00F0010100F101A982CA950303D50137382E3134312E3137372E33383A3132333530203230342E392E3136332E3135313A31323335300003CF0137382E3134312E3137372E36393A3132333530203230342E392E3136332E3134393A31323335300000D6010103E4013139342E3136352E3138382E38303A3132333530203231322E382E3136362E353A31323335300003E5010000F8016403F7015B574845453A204F4646203130302C20563120302C20563220305D205B496E70757445513A204F46462035302C2056312035305D205B4945513A204F46462031362C2056312031322C2056322031322C2056332031322C2056342031322C2056352031322C2056362031322C2056372031325D205B53453A204453203130302C2057494F20305D205B5345323A2044532039302C2057494F2031305D205B414D504D3A204F4C442035302C20444147432035305D205B4B54523A204F46462035302C204F4E2035305D205B49414D323A204F46462039392C204D3120312C204D3220305D0003FA0152434F4E3D350003F901302F342E322E2A2E2A2C33322C3320302F352E302E2A2E2A2C31342C3320302F352E312E2A2E3130342C342C330003A80168747470733A2F2F7777775C2E70617970616C5C2E2E3F2E3F2E3F247C68747470733A2F2F696D616765735C2E70617970616C5C2E636F6D247C68747470733A2F2F7777775C2E70617970616C6F626A656374735C2E636F6D247C68747470733F3A2F2F2E2B5C2E666263646E5C2E6E6574247C68747470733F3A2F2F2E2B5C2E66616365626F6F6B5C2E636F6D247C68747470733F3A2F2F6368616E6E656C5C2E736B7970655C2E636F6D247C68747470733A2F2F617070735C2E736B7970655C2E636F6D247C68747470733F3A2F2F7161617070735C2E736B7970655C2E6E6574247C68747470733F3A2F2F636F6E6E6563745C2E66616365626F6F6B5C2E6E6574247C68747470733A2F2F2E2A5C2E736B7970656173736574735C2E636F6D247C68747470733A2F2F61645C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F61642D656D65615C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F61642D617061635C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F737461746963323F5C2E736B7970655C2E636F6D247C68747470733A2F2F7161737461746963323F5C2E736B7970655C2E6E6574247C68747470733A2F2F7072657374617469635C2E736B7970655C2E6E6574240003FF013078313030303230343030393136333231372D642D723230342E392E3136332E3231373A38313932203078313030303230343030393136333231392D642D723230342E392E3136332E3231393A38313932203078313030303230343030393136333232312D642D723230342E392E3136332E3232313A38313932203078313030303230343030393136333232332D642D723230342E392E3136332E3232333A38313932203078313030303230343030393136333232352D642D723230342E392E3136332E3232353A38313932203078313030303230343030393136333232372D642D723230342E392E3136332E3232373A38313932203078313030303230383038383138363030352D642D723230382E38382E3138362E353A38313932203078313030303230383038383138363030372D642D723230382E38382E3138362E373A38313932203078313030303230383038383138363030392D642D723230382E38382E3138362E393A38313932203078313030303230383038383138363031312D642D723230382E38382E3138362E31313A38313932203078313030303230383038383138363031332D642D723230382E38382E3138362E31333A38313932203078313030303230383038383138363031352D642D723230382E38382E3138362E31353A38313932203078313030303230383038383138363031372D642D723230382E38382E3138362E31373A38313932203078313030303230383038383138363031392D642D723230382E38382E3138362E31393A38313932203078313030303230383038383138363032312D642D723230382E38382E3138362E32313A38313932203078313030303230383038383138363032332D642D723230382E38382E3138362E32333A38313932203078313030303230383038383138363032352D642D723230382E38382E3138362E32353A38313932203078313030303230383038383138363032372D642D723230382E38382E3138362E32373A38313932203078313030303230383038383138363032392D642D723230382E38382E3138362E32393A38313932203078313030303230383038383138363033312D642D723230382E38382E3138362E33313A38313932203078313030303230383038383138363033332D642D723230382E38382E3138362E33333A38313932203078313030303230383038383138363033352D642D723230382E38382E3138362E33353A38313932203078313030303230383038383138363033372D642D723230382E38382E3138362E33373A38313932203078313030303230383038383138363033392D642D723230382E38382E3138362E33393A38313932203078313030303230383038383138363034372D642D723230382E38382E3138362E34373A38313932203078313030303230383038383138363034392D642D723230382E38382E3138362E34393A38313932203078313030303230383038383138363035312D642D723230382E38382E3138362E35313A38313932203078313030303230383038383138363035332D642D723230382E38382E3138362E35333A38313932203078313030303230383038383138363035352D642D723230382E38382E3138362E35353A38313932203078313030303230383038383138363035372D642D723230382E38382E3138362E35373A38313932203078313030303230383038383138363035392D642D723230382E38382E3138362E35393A38313932203078313030303230383038383138363036312D642D723230382E38382E3138362E36313A38313932203078313030303230383038383138363036332D642D723230382E38382E3138362E36333A38313932203078313030303230383038383138363035392D642D723230382E38382E3138362E36353A38313932203078313030303230383038383138363036312D642D723230382E38382E3138362E36373A38313932203078313030303230383038383138363036332D642D723230382E38382E3138362E36393A38313932203078313030303230383038383138363037312D642D723230382E38382E3138362E37313A38313932203078313030303230383038383138363037332D642D723230382E38382E3138362E37333A38313932203078313030303230383038383138363037352D642D723230382E38382E3138362E37353A38313932203078313030303230383038383138363037372D642D723230382E38382E3138362E37373A38313932203078313030303230383038383138363037392D642D723230382E38382E3138362E37393A38313932203078313030303230383038383138363038312D642D723230382E38382E3138362E38313A38313932203078313030303230383038383138363038332D642D723230382E38382E3138362E38333A38313932203078313030303230383038383138363038352D642D723230382E38382E3138362E38353A38313932203078313030303230383038383138363038372D642D723230382E38382E3138362E38373A38313932203078313030303230383038383138363038392D642D723230382E38382E3138362E38393A38313932203078313030303230383038383138363039312D642D723230382E38382E3138362E39313A38313932203078313030303230383038383138363039332D642D723230382E38382E3138362E39333A38313932203078313030303230383038383138363039352D642D723230382E38382E3138362E39353A38313932203078313030303230383038383138363039372D642D723230382E38382E3138362E39373A38313932203078313030303230383038383138363039392D642D723230382E38382E3138362E39393A38313932203078313030303230383038383138363130312D642D723230382E38382E3138362E3130313A38313932203078313030303230383038383138363130332D642D723230382E38382E3138362E3130333A38313932203078313030303230383038383138363130352D642D723230382E38382E3138362E3130353A38313932203078313030303230383038383138363130372D642D723230382E38382E3138362E3130373A38313932203078313030303230383038383138363130392D642D723230382E38382E3138362E3130393A38313932203078313030303230383038383138363131312D642D723230382E38382E3138362E3131313A38313932203078313030303230383038383138363131332D642D723230382E38382E3138362E3131333A38313932203078313030303230383038383138363131352D642D723230382E38382E3138362E3131353A38313932203078313030303230383038383138363131372D642D723230382E38382E3138362E3131373A38313932203078323030303134393030353034353031312D642D723134392E352E34352E31313A38313932203078323030303134393030353034353031332D642D723134392E352E34352E31333A38313932203078323030303134393030353034353031352D642D723134392E352E34352E31353A38313932203078323030303134393030353034353031372D642D723134392E352E34352E31373A38313932203078323030303134393030353034353031392D642D723134392E352E34352E31393A38313932203078323030303134393030353034353032312D642D723134392E352E34352E32313A38313932203078323030303134393030353034353032332D642D723134392E352E34352E32333A38313932203078323030303134393030353034353032352D642D723134392E352E34352E32353A38313932203078323030303134393030353034353032372D642D723134392E352E34352E32373A38313932203078323030303134393030353034353032392D642D723134392E352E34352E32393A38313932203078323030303134393030353034353033312D642D723134392E352E34352E33313A38313932203078323030303134393030353034353033332D642D723134392E352E34352E33333A38313932203078323030303134393030353034353033352D642D723134392E352E34352E33353A38313932203078323030303134393030353034353033372D642D723134392E352E34352E33373A38313932203078323030303134393030353034353033392D642D723134392E352E34352E33393A38313932203078323030303134393030353034353034312D642D723134392E352E34352E34313A38313932203078323030303134393030353034353034332D642D723134392E352E34352E34333A38313932203078323030303134393030353034353034352D642D723134392E352E34352E34353A38313932203078323030303134393030353034353034372D642D723134392E352E34352E34373A38313932203078323030303134393030353034353034392D642D723134392E352E34352E34393A38313932203078323030303134393030353034353035312D642D723134392E352E34352E35313A38313932203078323030303134393030353034353035332D642D723134392E352E34352E35333A38313932203078323030303134393030353034353035352D642D723134392E352E34352E35353A38313932203078323030303134393030353034353035372D642D723134392E352E34352E35373A38313932203078323030303134393030353034353035392D642D723134392E352E34352E35393A38313932203078323030303134393030353034353036312D642D723134392E352E34352E36313A38313932203078323030303134393030353034353036332D642D723134392E352E34352E36333A38313932203078323030303134393030353034353036352D642D723134392E352E34352E36353A38313932203078323030303134393030353034353036372D642D723134392E352E34352E36373A38313932203078323030303134393030353034353036392D642D723134392E352E34352E36393A38313932203078323030303134393030353034353037312D642D723134392E352E34352E37313A38313932203078323030303134393030353034353037332D642D723134392E352E34352E37333A38313932203078323030303134393030353034353037352D642D723134392E352E34352E37353A38313932203078323030303134393030353034353037372D642D723134392E352E34352E37373A38313932203078323030303134393030353034353037392D642D723134392E352E34352E37393A38313932203078323030303134393030353034353038312D642D723134392E352E34352E38313A38313932203078323030303134393030353034353038332D642D723134392E352E34352E38333A38313932203078323030303134393030353034353038352D642D723134392E352E34352E38353A38313932203078323030303134393030353034353038372D642D723134392E352E34352E38373A38313932203078323030303134393030353034353038392D642D723134392E352E34352E38393A38313932203078323030303134393030353034353039312D642D723134392E352E34352E39313A38313932203078323030303134393030353034353039332D642D723134392E352E34352E39333A38313932203078323030303134393030353034353039352D642D723134392E352E34352E39353A38313932203078323030303134393030353034353039372D642D723134392E352E34352E39373A38313932203078323030303134393030353034353039392D642D723134392E352E34352E39393A38313932203078323030303134393030353034353130312D642D723134392E352E34352E3130313A38313932203078323030303134393030353034353130332D642D723134392E352E34352E3130333A38313932203078323030303134393030353034353130352D642D723134392E352E34352E3130353A38313932203078323030303134393030353034353130372D642D723134392E352E34352E3130373A38313932203078323030303134393030353034353130392D642D723134392E352E34352E3130393A38313932203078323030303134393030353034353131312D642D723134392E352E34352E3131313A38313932203078323030303134393030353034353131332D642D723134392E352E34352E3131333A38313932203078323030303134393030353034353131352D642D723134392E352E34352E3131353A38313932203078323030303134393030353034353131372D642D723134392E352E34352E3131373A38313932203078323030303134393030353034353131392D642D723134392E352E34352E3131393A38313932203078323030303134393030353034353132312D642D723134392E352E34352E3132313A38313932203078323030303134393030353034353132332D642D723134392E352E34352E3132333A38313932203078323030303134393030353034353132352D642D723134392E352E34352E3132353A38313932203078323030303134393030353034353132372D642D723134392E352E34352E3132373A38313932203078323030303134393030353034353132392D642D723134392E352E34352E3132393A38313932000089020A062E19AEBFD5A40B80D4B6B30280D2AFF205808CFD910B80DEB9F1048FA486F4049CA486F404D5A486F404ACC686F404C2C686F404878F87F404CEB887F404ADC487F404BCC687F404D4D087F404F9EA87F4049CF587F404C8F487F404C9F487F404CAF487F404EACCBB9C05F7CCBB9C05E694D7BB058E96D7BB05A896D7BB050094023C0095021400930201039902536B79706520546563686E6F6C6F6769657320534100008E0200008F0280BAB70300910280A30503F2013231332E3134362E3138392E3230313A3132333530203231332E3134362E3138392E3230323A3132333530203231332E3134362E3138392E3230333A3132333530203231332E3134362E3138392E3230343A3132333530203231332E3134362E3138392E3230353A3132333530203231332E3134362E3138392E3230363A3132333530203231322E3136312E382E31303A3132333530203231322E3136312E382E323A3132333530203231322E3136312E382E333A3132333530203231322E3136312E382E343A3132333530203231322E3136312E382E353A3132333530203231322E3136312E382E363A31323335300000FC010106FD0106011E64AC02A403E807009002C20103C301687474703A2F2F37392E3132352E36332E3732247C68747470733F3A2F2F2E2B5C2E66616365626F6F6B5C2E636F6D240000DE0148 + <_256>000010011AC0AA3BA66DF7FB48228AE35F9BB4A032FE4A6A898DA7A1A5AE37DC59FB3D09607F1CACD46A5DBC008DABF8F09C797DF5A8903307D04C318825CEA7C481303C655A9EEE099E9A0AF1158373B458BB8FDACB336A6EC63C043E6782688E2350B417DDDDFF96B474DAEA7D1DF3742303B79111FC752BFB5D6887A5B822F945CC761FAF6E80DE5EC60868768CB8A9F9C876137806DCEA0DD1300181558ABFDBA26592078F5F84195C526D8C7F339EF82700FD93F8FB71ADA5ED3E977D27FA52D1F489EF5DA0A9E00B146BADCBDEBFB0DFEBCD61E5B8352A49893357E0DC3A736743929DA975782EA4D8184605FD064641986C47706D264281C876F926BF58003E9E + <_3>0000100498ECF8A7A4585F76C930739A1EAE590DE96D9EF3AA9B231E67965F3F08ECFC493E1DA23ECDE17A85C94CBE034E88F9414E9BBC82F32AAFCFFB2C09F6F57A478238BAEC9EEF2BB9C67F71257722E6786D88D6400F6B7D81450FB3B6CCCC3986E3782D2387E354EBA9099331AEF510D479C6601D2383D866E2B5B525DF0BA975D58C120EFAE88C89EE365FC696CC891B77F67CFA18FDE8E95DDAC25A7C7D70FA7A1414BAE593856A658888C622836006C1C131B4B2E805554DCFA52F3EFD34C1B759BF8A302E491835DCE701E84D37ED150C8ADD699AD3DCA9F515123C5B5AD94E253E173BA3465E64A0079D5EF4E6075E66D0F5FBC3D9BC25C4E80C4CB2FE9B87040003000004D00F0005D00F050041040400B80125C20003141B14230025D50003031B14230024E100142300250003191714230025EA0003141714230025EA00011724EA00140A14230025E400030F1C14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025E10025E10003A006100A0309031725000325180C0A25C20003140B0C03040D0A03882725C3000C0A03E43225C4000C0A0602050228038407DC08FA1E0601050102050203FA1E1C0603250028061D1E1F202122060105010205010503050141060300636F756E74206279207175616C697479000001CC080002040003000004010005010501410603006261647175616C69747920636F756E742062792076657273696F6E000001D6080002070003000004010005010501410603006261647175616C6974792073756D2062792076657273696F6E000001E0080002070003000004010005010500410304005424E400142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025E40025E40028043CB401D804901C060105010205014106030073756D206F66206C61737463616C6C206475726174696F6E73000001B009000201000300000480A3050005B054050141060300636F756E74206279206C61737463616C6C206475726174696F6E000001BA090002050003000004010005010500410204005025EB00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EB0028031E32D0000601050102050141060300636F756E742062792073797374656D20637075207573616765000001940A0002040003000004010005010500410204004F25EC00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EC0028030F1E320601050102050141060300636F756E742062792070726F63657373206370752075736167650000019E0A0002040003000004010005010500410304006824C20014230024E60014230025E600011A14230025EC00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EC0028030F1E320601050102050125C2000501410603006A6974746572636F756E742062792070726F6365737320637075207573616765000001F80A0002040003000004010005010501410603006A69747465722062792070726F6365737320637075207573616765000001820B0002040003000004D00F0005D00F0500410304004424E700142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A1423000225E700050141060300706F74656E7469616C207463702066616C6C6261636B73000001DC0B00020100030000040100050105014106030061637475616C207463702066616C6C6261636B73000001E60B00020100030000040100050105004103040056240C142300250C030A1814230025EA0003141714230025EA00011724EA00140A14230024E70014230025E700011A14230024E50014230025E500011C0602250C29050306070809280401020405060105010205010502050141060300636F756E74206279206E617474797065000001C00C0002050003000004010005010501410603007564706661696C75726573206279206E617474797065000001CA0C0002050003000004010005010500410204001B25D90014230025D90025DA000B0602050228030102040601050102050141060300636F756E74206279206E726F666D756C74696368617473000001A40D0002040003000004010005010500410304001425F700011C14230025000319171423000225F90005014106030075736572732077686F206861766520636F6D706C65746564204943000001880E0002010003000004010005010501410603006C617374204943207969656C6420676C6F62616C73756D000001920E0002010003000004E8070005500500410304001224F60014230025000319171423000225F60005014106030075736572732077686F206861766520494320737570706F7274000001EC0E0002010003000004010005010501410603004943207374617274757020636F756E7420676C6F62616C73756D000001F60E00020100030000046400051405004102040025240C142300250C030A18142300250C011C142300250C280802030405060708090601050102050141060300636F756E74206279206E617474797065000001D00F0002090003000004010005010500410404001A250003191714230025E20025E30025FC00280201020601050102050141060300766964656F2073656E642063617061626C650000019811000201000300000401000501050141060300766964656F20706172616C6C656C2063616C6C730000019911000201000300000414000502050141060300636F756E7420627920766964656F2063616C6C73206D616465000001A2110002030003000004010005010500410204003A250003191714230025EA0003141714230025EA00011724EA00140A14230024E50014230025E50003031914230025E50028030102030601050102050141060300636F756E742062792073747265616D7472616E73706F7274000001FC11000204000300000401000501050041090400E00125C20003141B25E400030F1C1514230024E100142300250003191714230025EA0003141725EA0001171514230025FF002580010A011A14230025E60003031A25E50003031A1514230024F5001423002412142300249F0114230025C30025E10025E10003A006100A03A0060B0309031725000325180C0A25C20003140B0C03040D0A2512030A0C251025F5001703CC080C0A1C160602020502250003231B241D150603050305020503150503251D03808080808080808080011D14150603050305020503150503251D038080808080808080C0011D1415060305030502050315050141060300706F74656E7469616C2052555F756E65787065637465645F62616471000001E01200020100030000040100050105014106030061637475616C2052555F756E65787065637465645F62616471000001EA1200020100030000040100050105014106030042435020706F74656E7469616C2052555F756E65787065637465645F62616471000001F4120002010003000004010005010501410603004243502061637475616C2052555F756E65787065637465645F62616471000001FE12000201000300000401000501050141060300424350203220706F74656E7469616C2052555F756E65787065637465645F62616471000001881300020100030000040100050105014106030042435020322061637475616C2052555F756E65787065637465645F626164710000019213000201000300000401000501050141060300424350203420706F74656E7469616C2052555F756E65787065637465645F626164710000019C130002010003000004010005010501410603004243502031362061637475616C2052555F756E65787065637465645F62616471000001A6130002010003000004010005010500410304000825B801011C25B701050141060300757365727320696E207075626C6963206368617473000001C4130002010003000004010005010501410603007075626C69632063686174206D6573736167657320696E206C617374206D696E757465000001CE1300020100030000046400050A0500410404005F248E0114230024D5001423002500032B1B1423002500032B1C250D03021C16250E03FFFFFFFF0F1D03B4E2C8F10217250E0380808080100D03B4E2C8F10217151614230025D500280219C80106010501020501258E010501258E0103880E1C050141060300636F756E742062792062756464696573000001A814000203000300000401000501050141060300617661696C6162696C697479206167652062792062756464696573000001B2140002030003000004C0FC150005A099020501410603006C6F6E6720617661696C6162696C697479206167652062792062756464696573000001BC140002030003000004010005010500410204003324C000142300250003191714230025F301290300E5C68583B7AEDE36F2CAB9A3A7AE983806020502280202030601050125C00005014106030073696D756C74616E656F75732063616C6C7320706572206E616D6573706163650000018C15000203000300000419000519050041020400C50125C00006020502142300250006030503031917142300050303231B06040504210302200225A1010605050421030502200225A2010606030606070505021A050503021A160506021A15210305072002010607050203021B050603021B152103050720020206070502021A050603021B15210305072002030206070502021A050503041A15210305072002030306070502021A050503031A15210305072002030406070502021A050503051A152103050720020305060705072806010203040506060105010205014106030063616C6C6572733A207332735F313120636F6E665F686F737420636F6E665F636C69656E7420736B7970656F757420736B797065696E20766F6963656D61696C20756E6B6E6F776E000001F015000207000300000401000501 + <_4>000010052A0B6759B71FBC1EF05BE97DFEA4EE6C1E15AF19ED70DEC1130B14C13CE41246D302B9662592907E3CA508A57702B5C00C2A05170857FA22012E0F235B425B4D919B23A541D3AD6E948FC634DE71A29493634884DFD5E9D89C5D951CBCD71B9B3ABFD3C4E2779BB1817D76E7C223CA36BD75A6A05B730AF138057E4048B2FFDD522BB588EC0B9D3E014BF9E354EB608150BC613C739D9E8C7465F05F047FAF7AFA3EE89B9B58BF0FC35F07B55CF3E4B59A7C4ED48B1C0C7F0305E6AC2E80AAEAD6064EB6ACDC1806FCE0B5CB66F0840DA7F0FE7B228E3898E3E42A9AFEFE13DDF019EF8D8F02A631AF2615BBC6E1EDB65C89A775F642C88109E6247EC4B463DC302E2A2E323000050541020006020307322E302E2A2E3100050541030006020307322E302E2A2E3200000AE4ED8009050541030006020307322E302E2A2E33000009B3E6CC990B050541040006020307322E302E2A2E3400000AE4ED8009000BA00B050541030006020308322E302E2A2E35000307322E302E2A2E3900050541040006020308322E302E2A2E39000307322E302E2A2E313100000AE4ED8009050541040006020308322E302E2A2E3131000307322E302E2A2E3135000009E6CC99B306050541050006020308322E302E2A2E3135000307322E302E2A2E323000000AE4ED8009000BA00B050041050303557067726164655465737433000301332E302E302E3130300003044E6963654272616E6400050541040006020307332E302E302E2A0003074E6963654272616E6400000AE4ED8009050541040006020307322E302E302E2A0003074E6963654272616E6400000AE4ED80090500410E0303557067726164655465737433000301332E302E302E31303000050541040006020307332E302E302E39390003074F746865724272616E6400000AE4ED8009050541040006020307322E302E302E39390003074F746865724272616E6400000AE4ED8009050541040006020307332E302E302E39380003074F746865724272616E64000009B3E6CC990B050541040006020307322E302E302E39380003074F746865724272616E64000009B3E6CC990B050541050006020307332E302E302E39370003074F746865724272616E6400000AE4ED8009000BA00B050541050006020307322E302E302E39370003074F746865724272616E6400000AE4ED8009000BA00B050541030006020307332E302E302E393900000AE4ED8009050541030006020307322E302E302E393900000AE4ED8009050541030006020307332E302E302E3938000009B3E6CC990B050541030006020307322E302E302E3938000009B3E6CC990B050541040006020307332E302E302E393700000AE4ED8009000BA00B050541040006020307322E302E302E393700000AE4ED8009000BA00B0500410303033130303031000301302E302E302E313000050541020006020307302E302E302E3900 + <_5>00001006739CA527EF827847E16F23CD52458C3EBA3460A42935EC6948BEFA626B49E3BDF279FC62486E2DDBCA19609ED23D31F4E5175920F282AD74A74A997C3909E67B622480C68A058E886C7D5F3C40954880D7798CD61CEA0FBAFB389BE5B2B8A887348F7AADB4DF642B194B814047CDA0E698EDDE61DFA731DCA5883A76F913D8C94066718054E85ADA7AE009F2B2A9AF762FDCB9B6CAF64C156911E3AB172CFD795F66FB6E8E15048A54E4AB17979D6C447DEBADE75CC6F606050D980061112AFF9AE7C7BF8065D711949E41FA4C8B6CBF0916BB395B3E186A7D617D353C6BFFC687FE79475DFA095D113D70B828FB597BC3665B7C9C3669CA9CBE5D308D3FC23803044E45544745415200050541020006040307302E392E302E2A000500410503033130303033000301312E302E302E3137000304534D4300050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E312E302E313000030442454C4B494E00050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E302E302E3137000304454447452D434F524500050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E302E302E31330003044C4F474954454300050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303035000301312E342E38382E31333636000304544F50434F4D00050541020006040307312E342E38382E3133353600050541020006020307312E342E38382E31333635000500410503033130303035000301312E342E38382E313336360003045043484F4D4500050541020006040307312E342E38382E3133353600050541020006020307312E342E38382E31333635000500410403033130303036000301302E302E302E313000050541020006040307302E302E302E3500050541020006020307302E302E302E39000500410503033130303037000301312E302E312E330003045445434F00050541020006040307312E302E302E3800050541020006020307312E302E312E31000500410503033130303038000301302E392E332E3339370003044C494E4B53595300050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410503033130303038000301302E392E332E3339370003044E45544745415200050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410503033130303038000301302E392E332E3339370003045048494C49505300050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410403033130303130000301302E392E302E31310003044C494E4B53595300050541020006040307302E392E302E3130000500410403033130303130000301302E392E302E313100030442554646414C4F00050541020006040307302E392E302E3130000500410503033130303132000301312E302E302E310003044353544E00050541020006040307302E302E302E3500050541020006020307302E302E302E39000500410503033130303133000301302E302E332E3234000304414B00050541020006040307302E302E312E323400050541020006020307302E302E322E3234000500410303033130303134000301312E372E34332E33382E3200050541020006040307312E372E32332E32372E34000500410503033130303135000301312E322E31372E30000304415A5445434800050541020006040307312E322E31312E3000050541020006020307312E322E31352E30000500410303033130303230000301312E302E302E343700050541030006020308312E302E302E3233000307312E302E302E3233000500410403033130303234000301332E322E302E323800050541030006040308332E302E302E35000307332E302E302E3500050541030006020308332E312E302E31000307332E322E302E38000500410503033130303232000301302E302E302E3900030450414E41534F4E494300050541020006040307302E302E302E3100050541020006020307302E302E302E38000500410503033130303232000301302E302E302E3900030450414E41534F4E4943434F4E53554D455200050541020006040307302E302E302E3100050541020006020307302E302E302E3800 + + 1 + + 400 + + + + 8118 + 39,64,8184 + 37,50,13164 + + 1 + + 1 + + + -1431699456 + -1431699456 + 1610612735 + + 41C801050041050200D9AF0D45D9E900010400028788BCED0400038788BCED04000400050041050200BB0AB3FDD1A40001040002B7DCBCED040003B7DCBCED040004000500410502005C3766C2DA6B00010400029FB2BCED0400039FB2BCED04000400050041050200D9F8DC20CA33000104000296DAAAED04000396DAAAED0400040005004105020063847B3765900001040002D794BDED040003D794BDED040004000500410502004E80142FD3C70001040002CF86BDED040003CF86BDED04000400050041050200C3B213EA24A50001040002BF89BBED040003BF89BBED040004000500410502006FFEF1BA804C0001040002CF86BDED040003CF86BDED0400040005004105020052ED923CB3A700010400028788BCED0400038788BCED040004000500410502005243330D305B000104000283FFB2ED04000383FFB2ED040004000500410502006FF9438E9E5D0001040002CF86BDED040003CF86BDED04000400050041050200585515F19D77000104000283FFB2ED04000383FFB2ED04000400050041050200729EE3A8DD460001040002CF86BDED040003CF86BDED040004000500410502004572795D3BB300010400029FB2BCED0400039FB2BCED040004000500410502009F94D72CABA40001040002CF86BDED040003CF86BDED0400040005004105020095052D9C81090001040002B7DCBCED040003B7DCBCED040004000500410502005859A15FD7FC0001040002DC8FB5ED040003DC8FB5ED0400040005004105020059D7AB3EBBFB0001020002F8FABCED040003CF86BDED04000400050041050200BB2481B9390E0001040002CF86BDED040003CF86BDED0400040005004105020059D7F395A7BA0001040002B7DCBCED040003B7DCBCED040004000500410502006DC4BEF5D52E0001040002B0DFBAED040003B0DFBAED040004000500410502004B6E709CF4290001040002B7DCBCED040003B7DCBCED040004000500410502007A7D5CEC2B8D0001040002CF86BDED040003CF86BDED040004000500410502006FFFA8AFB19D0001040002B7DCBCED040003B7DCBCED040004000500410502003E4475A07A6F0001040002B7DCBCED040003B7DCBCED040004000500410502003EDD8384A4F90001040002BF89BBED040003BF89BBED04000400050041050200560FBFA4E4900001040002B7DCBCED040003B7DCBCED04000400050041050200C24FAEEE43F10001040002B3CEB5ED040003B3CEB5ED040004000500410502004F378778C6F30001040002CF86BDED040003CF86BDED04000400050041050200C94418BB0EDF0001040002B7DCBCED040003B7DCBCED040004000500410502003B75A58BECB30001040002CF86BDED040003CF86BDED04000400050041050200772A7A0908890001040002CF86BDED040003CF86BDED0400040005004105020048BB63586DE100010400029088BCED0400039088BCED040004000500410502005544F881BEDA000104000283FFB2ED04000383FFB2ED040004000500410502005B4C1468EDF80001040002B7DCBCED040003B7DCBCED04000400050041050200538BAF3F934F0001040002B3CEB5ED040003B3CEB5ED0400040005004105020055D6F93A4FD70001040002D7B3BBED040003D7B3BBED04000400050041050200D5D64561E55F00010400028788BCED0400038788BCED0400040005004105020046ADF229B8570001040002CF86BDED040003CF86BDED04000400050041050200D5151C19FFD600010200029FB2BCED040003B7DCBCED04000400050041050200973CA35DB82400010400029FB2BCED0400039FB2BCED04000400050041050200C249E5B953700001040002CF86BDED040003CF86BDED04000400050041050200722C69D8C4F500010400029FB2BCED0400039FB2BCED0400040005004105020058CBB311F2400001040002DC8FB5ED040003DC8FB5ED040004000500410502004BB7A090766E0001040002CF86BDED040003CF86BDED040004000500410502007DEF80FBEBD90001040002EFDDBBED040003EFDDBBED0400040005004105020076A03698F87A0001040002CF86BDED040003CF86BDED0400040005004105020050E5DFDD0C700001040002CF86BDED040003CF86BDED040004000500410502004D4C85E0CEC80001040002CF86BDED040003CF86BDED040004000500410502006FEA6BCD92A10001020002F8FABCED040003CF86BDED0400040005004105020043BAA930F28600010400029FB2BCED0400039FB2BCED04000400050041050200722DB82DDB780001040002CF86BDED040003CF86BDED0400040005004105020052E995118B9F0001040002CF86BDED040003CF86BDED040004000500410502005403013B36D20001040002EFDDBBED040003EFDDBBED04000400050041050200B27C0C920B260001040002B7DCBCED040003B7DCBCED04000400050041050200D9AF0997A7450001040002BCD9AAED040003BCD9AAED04000400050041050200BC00130BB5F60001040002CF86BDED040003CF86BDED04000400050041050200591FF23B53830001040002CF86BDED040003CF86BDED04000400050041050200557EB01367590001040002CF86BDED040003CF86BDED04000400050041050200505F157093A2000102000297A4BCED04000397A4BCED040004000500410502003A036C495C670001040002CF86BDED040003CF86BDED0400040005004105020050D8CF0B7D480001040002B7DCBCED040003B7DCBCED040004000500410502004E34E4D0FF250001040002B7DCBCED040003B7DCBCED040004000500410502007A1E50A46E770001040002CF86BDED040003CF86BDED040004000500410502005F18C666CBB80001040002EFDDBBED040003EFDDBBED04000400050041050200C19335603A9E0001040002DC8FB5ED040003DC8FB5ED0400040005004105020097142BD7DF890001040002AFDFBAED040003AFDFBAED0400040005004105020052F3355FFED400010400029FB2BCED0400039FB2BCED04000400050041050200BCBA857EECDF0001040002D7B3BBED040003D7B3BBED04000400050041050200729259D605EF0001040002CF86BDED040003CF86BDED04000400050041050200BEC2F57655B300010400029FB2BCED0400039FB2BCED040004000500410502005BD905C8304B0001020002A8EEBBED0400038788BCED0400040005004105020055F2C0360F360001040002EFDDBBED040003EFDDBBED0400040005004105020082C01DB9605D00010400028788BCED0400038788BCED04000400050041050200BC73B8FB30360001040002CF86BDED040003CF86BDED0400040005004105020050390E32DF8B0001040002B0DFBAED040003B0DFBAED040004000500410502005BCE8A2D7B8000010400028788BCED0400038788BCED0400040005004105020042292BB45D2D0001040002CF86BDED040003CF86BDED040004000500410502004F1A354DCA9A00010400029FB2BCED0400039FB2BCED04000400050041050200591C1D7F0EC900010400028788BCED0400038788BCED04000400050041050200722E9D2CCB030001040002CF86BDED040003CF86BDED04000400050041050200443AB71D3F8A0001040002CF86BDED040003CF86BDED0400040005004105020018DEF34EB70600010400028788BCED0400038788BCED0400040005004105020097215860080F00010400029FB2BCED0400039FB2BCED040004000500410502007229C156A49E0001040002B7DCBCED040003B7DCBCED040004000500410502003A72EDECB0250001040002B3F7B4ED040003B3F7B4ED04000400050041050200D52F8CD18F640001040002E285B0ED040003E285B0ED040004000500410502006B0325208B4C0001040002EFDDBBED040003EFDDBBED040004000500410502005164424285660001040002938AB5ED040003938AB5ED04000400050041050200D4E9D6AB12F80001040002AFDFBAED040003AFDFBAED0400040005004105020059B3090F459C0001040002FCDDAAED040003FCDDAAED04000400050041050200BC10C41E7AAB0001040002CF86BDED040003CF86BDED040004000500410502009F9532B560C100010400028788BCED0400038788BCED0400040005004105020050EA7B4A63750001040002CF86BDED040003CF86BDED0400040005004105020045A658245E790001040002CF86BDED040003CF86BDED0400040005004105020047E3059299620001040002CF86BDED040003CF86BDED0400040005004105020081164AFC3B450001040002CF86BDED040003CF86BDED040004000500410502005703C3FC60FF00010400028788BCED0400038788BCED0400040005004105020063FAEB02F39300010400028788BCED0400038788BCED040004000500410502005714F2D9F6650001020002AFDFBAED040003ECE7BAED04000400050041050200505F1B22B00D0001040002CF86BDED040003CF86BDED0400040005004105020062C2F2A80C7900010400029FB2BCED0400039FB2BCED04000400050041050200425CA6CCD1FF0001040002CF86BDED040003CF86BDED0400040005004105020084C778D4AB110001040002CF86BDED040003CF86BDED040004000500410502005106437CD3B60001040002CF86BDED040003CF86BDED0400040005004105020058506B2B47D40001040002D7B3BBED040003D7B3BBED04000400050041050200DD70204563390001040002B7DCBCED040003B7DCBCED040004000500410502005CFFA5BE4A0000010200028888BCED040003F8FABCED0400040005004105020089BD8692E0400001040002B7DCBCED040003B7DCBCED040004000500410502004AC12BB2AB8D0001040002B7DCBCED040003B7DCBCED04000400050041050200DB555CBAEE6B0001040002CF86BDED040003CF86BDED0400040005004105020095052D8F81090001020002A7FDBCED040003CF86BDED04000400050041050200473AA0E1C9110001020002A7FDBCED040003CF86BDED040004000500410502004EFA971D2E4C0001040002B7DCBCED040003B7DCBCED04000400050041050200BCE6C5A829D900010400029E90B5ED0400039E90B5ED0400040005004105020051699F18DC540001040002D7B3BBED040003D7B3BBED040004000500410502005CFB85D7E6460001040002B3CEB5ED040003B3CEB5ED0400040005004105020052D17CE5A9840001040002BF89BBED040003BF89BBED0400040005004105020054DD54C818F20001040002CF86BDED040003CF86BDED040004000500410502005C3555EBDC670001040002B7DCBCED040003B7DCBCED0400040005004105020051D92EE554370001040002BF89BBED040003BF89BBED0400040005004105020095549556182D0001040002CF86BDED040003CF86BDED040004000500410502005419C1F7F52A0001040002B3CEB5ED040003B3CEB5ED040004000500410502008C7259638E1D0001040002B7DCBCED040003B7DCBCED04000400050041050200516745231C2200010400029FB2BCED0400039FB2BCED0400040005004105020055FB3DEAE2380001040002B7DCBCED040003B7DCBCED040004000500410502005D5470BCB83A00010400028788BCED0400038788BCED0400040005004105020054C6D511E6810001040002CF86BDED040003CF86BDED0400040005004105020062A7FAC0119000010200028788BCED0400038888BCED040004000500410502007225A1DCFB1A00010200028788BCED0400038888BCED04000400050041050200708B358CF15C00010400028788BCED0400038788BCED04000400050041050200D9A293C3FE550001040002AFDFBAED040003AFDFBAED04000400050041050200722119BAFCB600010400029FB2BCED0400039FB2BCED0400040005004105020054369C95EAC60001040002CF86BDED040003CF86BDED04000400050041050200AE74419813810001040002B7DCBCED040003B7DCBCED0400040005004105020048C613BC68510001040002EFDDBBED040003EFDDBBED04000400050041050200516E168D638B0001040002EFDDBBED040003EFDDBBED040004000500410502001819CFB484D20001040002CF86BDED040003CF86BDED04000400050041050200ADE013B3E9F10001040002CF86BDED040003CF86BDED040004000500410502005C708ABFAC890001040002B3CEB5ED040003B3CEB5ED04000400050041050200BC81882E891C0001040002B7DCBCED040003B7DCBCED0400040005004105020057785543EB480001040002CF86BDED040003CF86BDED040004000500410502006FF0CE6CB4500001040002CF86BDED040003CF86BDED040004000500410502005CE13B7199D4000102000283ADE7E304000383ADE7E30400040005004105020063F610137D170001040002B7DCBCED040003B7DCBCED04000400050041050200DC887BC89E210001040002CF86BDED040003CF86BDED040004000500410502005D9324151E7F0001020002A7FDBCED040003CF86BDED04000400050041050200BC02D363924D00010400029FB2BCED0400039FB2BCED040004000500410502004F28848E1AC50001040002CF86BDED040003CF86BDED0400040005004105020054C606DD0D260001040002D984B5ED040003D984B5ED04000400050041050200D5F586558C850001040002BF89BBED040003BF89BBED0400040005004105020082582B0468CF00010400028788BCED0400038788BCED040004000500410502005CE21BB9BD7C00010400029FB2BCED0400039FB2BCED0400040005004105020059A9ACE3BC02000104000296DAAAED04000396DAAAED040004000500410502005557DB28EDA300010400028788BCED0400038788BCED0400040005004105020076ABA00FF52C0001040002CF86BDED040003CF86BDED0400040005004105020052185C5CB8440001040002B7DCBCED040003B7DCBCED04000400050041050200441402A770A800010200028788BCED0400038888BCED04000400050041050200516623CC99760001040002CF86BDED040003CF86BDED040004000500410502005A3D6D867C2A0001040002BF89BBED040003BF89BBED04000400050041050200BC70864FCE530001040002B3F7B4ED040003B3F7B4ED040004000500410502005E9C9B4E7A740001040002CF86BDED040003CF86BDED0400040005004105020058ABF63F0EA70001040002FCDDAAED040003FCDDAAED040004000500410502005556BDBE86AC000104000286FFB2ED04000386FFB2ED0400040005004105020059D0D49C9B8000010400028788BCED0400038788BCED0400040005004105020059A934952E920001040002B3F7B4ED040003B3F7B4ED040004000500410502007220ABEC82C80001040002B7DCBCED040003B7DCBCED04000400050041050200807AB45544310001040002BF89BBED040003BF89BBED04000400050041050200187A8DFCCDCF0001040002BF89BBED040003BF89BBED04000400050041050200616B5C35801000010400028788BCED0400038788BCED040004000500410502005ABCE5EAE3790001040002938AB5ED040003938AB5ED0400040005004105020048DF5F3311D10001020002F8FABCED040003CF86BDED04000400050041050200D3146B24D6340001040002CF86BDED040003CF86BDED0400040005004105020059037023AC7D00010400029FB2BCED0400039FB2BCED040004000500410502003EDD92C929340001040002BF89BBED040003BF89BBED040004000500410502004C4EB0C1270D0001040002CF86BDED040003CF86BDED04000400050041050200BCA300CD17370001040002CF86BDED040003CF86BDED040004000500410502005BC42D9E789A0001040002D7B3BBED040003D7B3BBED04000400050041050200589755D3E75F0001020002D884B5ED040003B3CEB5ED040004000500410502007A7CC86B21530001040002CF86BDED040003CF86BDED040004000500410502005352A2DA24D300010400028788BCED0400038788BCED0400040005004105020058C9F9B6A86F0001040002B7DCBCED040003B7DCBCED040004000500410502005706A79DEAE60001020002AFDFBAED040003ECE7BAED0400040005004105020082D1B28F7A3A0001040002CF86BDED040003CF86BDED0400040005004105020052217343E79C0001040002CF86BDED040003CF86BDED0400040005004105020082CEA3A289FE000104000296DAAAED04000396DAAAED04000400050041050200D9E0FF79D1180001040002B7DCBCED040003B7DCBCED0400040005004105020052FD31513EE90001040002938AB5ED040003938AB5ED0400040005004105020052128CCDBA7C00010400029FB2BCED0400039FB2BCED040004000500410502006FB83DA167580001040002CF86BDED040003CF86BDED040004000500410502002E14B9387F540001020002B7DCBCED040003CF86BDED040004000500410502004F7E6F098A990001040002CF86BDED040003CF86BDED040004000500410502005D98B7099E1F0001040002B7DCBCED040003B7DCBCED04000400050041050200722A7476317600010400029FB2BCED0400039FB2BCED04000400050041050200BC18CE5EBDA10001020002AFDFBAED040003ECE7BAED040004000500410502005CF890CF3E270001040002B7DCBCED040003B7DCBCED040004000500410502008D72AE6DBEE30001040002CF86BDED040003CF86BDED0400040005004105020076A6D8E9EAAB0001040002CF86BDED040003CF86BDED04000400050041050200721B63925A140001040002CF86BDED040003CF86BDED040004000500410502007608B348A53A0001040002CF86BDED040003CF86BDED04000400 + + 0 + + -645574544 + 0 + 47500 + + 1 + + + 217.133.80.112:1076 217.133.80.112:47500 217.133.80.112:1083 217.133.80.112:1083 217.133.80.112:49734 + 7 + + <_1303289856>6C81442204F3D9855070B98CAE5879A505F3D9855070B98C4D4320134B66D9855070B98C5F4E60ED0D34D98550700434 + <_1303293952>4287274ED659D9855070B98C4287274ED74BD9855070B98C4287274EC15CD9855070B98C4287274ECE92D9855070B98C4287274EA75BD9855070B98C4287274E4B98D9855070B98C4287274EAA2DD9855070B98C4287274EA175D9855070B98C4287274ED735D9855070B98C4287274EAE25D9855070B98C4287274E1A2BD9855070B98C3D7D44372576D9855070B98CCF86DF304366D9855070B98C3D2E02A2259CD9855070B98C4287274EB98CD9855070B98C + <_1303298048>2E3363049108D9855070B98C2E3795FA3202D9855070B98C2E2F6F42E86DD9855070B98CB4B0620AA528D9855070B98C + <_1303306240>5F1894D8122BD9855070B98C2E40484969A3D9855070B98CD592A70A5566D9855070B98C2E26119F8DBED9855070B98C2E3754264E48D9855070B98C + <_1303314432>4D2BFFCAEC6CD9855070043B54BAD08D05E0D9855070B98C9D9D4DA11995D9855070B98C59584CCBB5CED9855070B98C972AC71733DDD9855070B98C + <_1303322624>5F3B0DCEB535D9855070043BD5150C1746D3D9855070B98C4D4B8646EF29D9855070B98CD5152F4D12BBD9855070B98C + <_1303326720>59D0D11D89DCD9855070C2462E755D8E1E97D9855070B98C2E492F875789D9855070B98C2E378784E9C6D9855070B98C2E2F6F6B48FCD9855070B98C + + + <_1303289856>9A4A56D31C619325C6601C71B23E13FDFAF5CA49F15C34A4E33F239B524D6BBC226021F010D2270A3B48DFA2E8CDB6FD37531B1118DB2D471CB980D0 + <_1303293952>D5A2186D0B45088ADDFA7B626C0904CED47E3DF13172672AED483E1EAD69DB781ABEC0D8812B1B5EFF91BC28C67FB5A3404D875A + <_1303298048>DB0EC5161D10171C7C6A4C7109DD + <_1303302144>5379BD98 + <_1303306240>88B19442A48D863ED54D712EEC36D53127BCE36653FE + <_1303310336>1908404B0F7BA3BE952CB1C533456D3CDA410BCB774AF93880FB8BD8C110 + <_1303314432>4B015AD444DD027FD3F61B2A51A53BA0 + <_1303322624>878BAF81A9F053B39E35081485E24B4EDA5F79D37E176C409B6E237A336451F42CFA7CEC013C98A18B51 + <_1303326720>CFB137906F6CCE77246BD5B6B434875570B1F9B9140C85D5114EE6953110B04F3557C0D1686D46A9F69106521979AE49E19F8622F93A + <_1303330816>BA4B81F735FDCDA4E4EF57ACF8A37051C66401E41CA4E562A5A49ACC2E246CCE + + + + 1 + + + 1 + + + 0 + + + 1 + + + + 9BF92EA4B417A7F6 + + + 4102030E322F322E302E302E37322F31373400000FF6EB9ADC04 + + + 0 + + + + 2 + en + + 357 + 258 + 0 + 0 + + 0 + + diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.xml new file mode 100644 index 0000000000..f7af8873ad --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.xml @@ -0,0 +1,74 @@ + + + + + 300 + 1800 + 63 + + + 41010300676D6172757A7A3400 + 1268962216 + + + 0 + 0 + 1303202372 + 0 + + + 35716ecf:2 + 98e6c103:0 + + + + + + 1 + 3 + 65535 + 1266110339 + + + 1 + + + 1 + + + 1000000166 + 1303166852 + 1303209779 + + + 1267114269 + + 2 + + 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 + + + 1267114267 + 11 + 4263C0064DD5ACF9A03594DAB928D2B81510 + + + noone + 1 + noone + + + <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 + + + + + skypopen + + + 0 + 2 + 2 + 2 + + diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/httpfe/cookies.dat new file mode 100644 index 0000000000..fc7f2b1150 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/httpfe/cookies.dat @@ -0,0 +1 @@ +B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/index2.dat new file mode 100644 index 0000000000..b8b96d8431 Binary files /dev/null and b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/index2.dat differ diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/main.lock new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.xml new file mode 100644 index 0000000000..f7af8873ad --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.xml @@ -0,0 +1,74 @@ + + + + + 300 + 1800 + 63 + + + 41010300676D6172757A7A3400 + 1268962216 + + + 0 + 0 + 1303202372 + 0 + + + 35716ecf:2 + 98e6c103:0 + + + + + + 1 + 3 + 65535 + 1266110339 + + + 1 + + + 1 + + + 1000000166 + 1303166852 + 1303209779 + + + 1267114269 + + 2 + + 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 + + + 1267114267 + 11 + 4263C0064DD5ACF9A03594DAB928D2B81510 + + + noone + 1 + noone + + + <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 + + + + + skypopen + + + 0 + 2 + 2 + 2 + + diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/httpfe/cookies.dat new file mode 100644 index 0000000000..fc7f2b1150 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/httpfe/cookies.dat @@ -0,0 +1 @@ +B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/index2.dat new file mode 100644 index 0000000000..b8b96d8431 Binary files /dev/null and b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/index2.dat differ diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/main.lock new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.xml new file mode 100644 index 0000000000..f7af8873ad --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.xml @@ -0,0 +1,74 @@ + + + + + 300 + 1800 + 63 + + + 41010300676D6172757A7A3400 + 1268962216 + + + 0 + 0 + 1303202372 + 0 + + + 35716ecf:2 + 98e6c103:0 + + + + + + 1 + 3 + 65535 + 1266110339 + + + 1 + + + 1 + + + 1000000166 + 1303166852 + 1303209779 + + + 1267114269 + + 2 + + 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 + + + 1267114267 + 11 + 4263C0064DD5ACF9A03594DAB928D2B81510 + + + noone + 1 + noone + + + <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 + + + + + skypopen + + + 0 + 2 + 2 + 2 + + diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/httpfe/cookies.dat new file mode 100644 index 0000000000..fc7f2b1150 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/httpfe/cookies.dat @@ -0,0 +1 @@ +B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/index2.dat new file mode 100644 index 0000000000..b8b96d8431 Binary files /dev/null and b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/index2.dat differ diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/main.lock new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skypopen.conf.xml b/src/mod/endpoints/mod_skypopen/configs/skypopen.conf.xml index f4e1c0ec5a..c03fd718e0 100644 --- a/src/mod/endpoints/mod_skypopen/configs/skypopen.conf.xml +++ b/src/mod/endpoints/mod_skypopen/configs/skypopen.conf.xml @@ -1,6 +1,5 @@ - @@ -8,6 +7,7 @@ + diff --git a/src/mod/endpoints/mod_skypopen/install/install.pl b/src/mod/endpoints/mod_skypopen/install/install.pl new file mode 100755 index 0000000000..f4c04f3aef --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/install/install.pl @@ -0,0 +1,373 @@ +#!/usr/bin/perl + +my $myname ; +my $skype_download_url = "http://mirrors.kernel.org/archlinux/community/os/i686/skype-oss-2.0.0.72-2-i686.pkg.tar.gz"; +my $skype_download_pkg = "skype-oss-2.0.0.72-2-i686.pkg.tar.gz"; +my $skype_binary_dir = "/usr/bin"; +my $skype_download_dir = "/tmp/skype_download"; +my $skype_share_dir = "/usr/share/skype"; +my $freeswitch_modules_config_dir = "/usr/local/freeswitch/conf/autoload_configs"; +my $skypopen_sound_driver_dir = "/usr/local/freeswitch/skypopen/skypopen-sound-driver-dir"; +my $skype_config_dir = "/usr/local/freeswitch/skypopen/skype-clients-configuration-dir"; +my $skype_startup_dir = "/usr/local/freeswitch/skypopen/skype-clients-startup-dir"; +my $skype_symlinks_dir = "/usr/local/freeswitch/skypopen/skype-clients-symlinks-dir"; +my $skype_clients_to_be_launched = "5"; +my $skype_clients_starting_number = "100"; +my $multi_skypeusername = "one"; +my $skype_username = "your_own_skype_username"; +my $skype_password = "your_own_skype_password"; +my @skype_username_array; +my @skype_password_array; +my $sure = "nope"; + +### PRESENTATION ### +system("clear"); +printf("\n"); +printf("This is the interactive installation helper for Skypopen\n"); +printf("(http://wiki.freeswitch.org/wiki/Mod_skypopen_Skype_Endpoint_and_Trunk)\n"); +printf("\n"); +printf("Especially designed for FreeSWITCH\n"); +printf("by Giovanni Maruzzelli\n"); +printf("\n"); +printf("Please direct all questions or issues to the FreeSWITCH mailing list or Jira\n"); +printf("(http://lists.freeswitch.org/mailman/listinfo or http://jira.freeswitch.org)\n"); +printf("\n"); +printf("\n"); +printf("I'll ask you questions, giving default answers in square brackets [] if any\n"); +printf("To accept the default, just press Enter\n"); +printf("You'll be prompted to confirm your answer at each step\n"); +printf("At the end of questions, before I do anything, I'll let you review it all\n"); +printf("To abort, press Ctrl-C\n"); +printf("\n"); +printf("\n"); +printf("Let's start asking your name, so you see how the question/answer works\n"); +printf("To accept the default, just press Enter\n"); +$myname = &promptUser("Enter your name ", "Giovanni"); +system("clear"); +printf("\n"); +printf("OK %s, GREAT! Let's start real questions! (At any time, Ctrl-C to abort)\n", $myname); +printf("\n"); +printf("At the end of questions, before I do anything, I'll let you review all your answers, don't worry! :)\n"); +printf("\n"); +printf("\n"); + +### ASKING QUESTIONS ### + +printf("I'm about to download the Skype client for Linux version 2.0.0.72 for OSS\n"); +printf("nicely repackaged by Arch Linux with official Skype permission.\n"); +printf("I need to create a directory to download and unpack the Skype client\n"); +printf("To accept the default, just press Enter\n"); +$skype_download_dir = &promptUser("Enter the full path of the Skype download directory ", "$skype_download_dir"); +system("clear"); +printf("\n"); +printf("I'm about to install the Skype client\n"); +printf("I would put the binary in $skype_binary_dir and the associated files in $skype_share_dir\n"); +printf("Location of associated files is mandatory ($skype_share_dir)\n"); +printf("Location of binary is recommended ($skype_binary_dir)\n"); +printf("To accept the default, just press Enter\n"); +$skype_binary_dir = &promptUser("Enter the directory full path for Skype client binary ", "$skype_binary_dir"); +system("clear"); +printf("\n"); +printf("I'm about to create the FreeSWITCH configuration file for mod_skypopen (skypopen.conf.xml)\n"); +printf("I need to know where to put it, eg: where is the FreeSWITCH modules' config dir\n"); +printf("To accept the default, just press Enter\n"); +$freeswitch_modules_config_dir = &promptUser("Enter the directory full path for FreeSWITCH modules' config files ", "$freeswitch_modules_config_dir"); +system("clear"); +printf("\n"); +printf("I'm about to create the directory where to put our fake sound driver\n"); +printf("Location of fake sound driver directory is where you like it more :)\n"); +printf("To accept the default, just press Enter\n"); +$skypopen_sound_driver_dir = &promptUser("Enter the directory full path for fake sound driver ", "$skypopen_sound_driver_dir"); +system("clear"); +printf("\n"); +printf("I'm about to create the configuration directory needed by the Skype clients\n"); +printf("Location of Skype clients configuration directory is where you like it more :)\n"); +printf("To accept the default, just press Enter\n"); +$skype_config_dir = &promptUser("Enter the directory full path for Skype clients config ", "$skype_config_dir"); +system("clear"); +printf("\n"); +printf("I'm about to create a directory where I'll put the Skype clients startup script\n"); +printf("Location of Skype clients startup script directory is where you like it more :)\n"); +printf("To accept the default, just press Enter\n"); +$skype_startup_dir = &promptUser("Enter the directory full path for Skype clients startup script ", "$skype_startup_dir"); +system("clear"); +printf("\n"); +printf("I'm about to create the directory for symlinks needed by the Skype clients startup script\n"); +printf("Location of symlinks directory is where you like it more :)\n"); +printf("To accept the default, just press Enter\n"); +$skype_symlinks_dir = &promptUser("Enter the directory full path for Skype clients symlinks ", "$skype_symlinks_dir"); +system("clear"); +printf("\n"); +printf("How many Skype clients (channels) do you want to launch?\n"); +printf("Each Skype client will be one channel to FreeSWITCH and use approx 70MB of ram\n"); +printf("A quad core CPU can very easily support 20 or more Skype clients\n"); +printf("Each Skype client allows one concurrent call\n"); +printf("Eg: if you plan to have a max of 10 concurrent (outbound and/or inbound) Skype calls then enter 10\n"); +printf("To accept the default, just press Enter\n"); +$skype_clients_to_be_launched = &promptUser("Enter how many Skype clients will be launched ", "$skype_clients_to_be_launched"); +system("clear"); +printf("\n"); + + +while(1){ + printf("You want all of the Skype clients to use the same Skype login (skypeusername)?\n"); + printf("eg: you want all of your skypopen channels to be Bob on the Skype network, or you want channel skype01 to be Bob, channel skype02 to be Alice, etc?\n"); + printf("Please answer 'one' for all channels using the same Skype login (you'll be asked just one time for Skype login and password) or 'multi' for being asked for each channel\n"); + printf("\n"); + $multi_skypeusername = &promptUser("Enter 'one' or 'multi' ", "$multi_skypeusername"); + system("clear"); + printf("\n"); + if($multi_skypeusername eq "one" or $multi_skypeusername eq "multi"){ + last; + } +} + + +if($multi_skypeusername eq "one"){ + printf("I need the Skype username which will be used by ALL the Skype clients to be launched\n"); + printf("(That's the one-word you registered as login to the Skype network)\n"); + printf("This installer will create the needed files to launch concurrently many (or one) instances of it\n"); + printf("\n"); + printf("NB: DON'T ACCEPT the DEFAULT, write YOUR OWN\n"); + $skype_username = &promptUser("Enter the Skype clients username ", "$skype_username"); + for($count=1; $count <= $skype_clients_to_be_launched ; $count++){ + $skype_username_array[$count] = $skype_username; + } + system("clear"); + printf("\n"); + printf("I need the Skype password which will be used by ALL the Skype clients to be launched\n"); + printf("(That's the one-word you registered as password to the Skype network)\n"); + printf("\n"); + printf("NB: DON'T ACCEPT the DEFAULT, write YOUR OWN\n"); + $skype_password = &promptUser("Enter the Skype clients password ", "$skype_password"); + for($count=1; $count <= $skype_clients_to_be_launched ; $count++){ + $skype_password_array[$count] = $skype_password; + } + system("clear"); +} else { + for($count=1; $count <= $skype_clients_to_be_launched ; $count++){ + $skype_client_extension = $skype_clients_starting_number + $count ; + printf("I need the Skype username which will be used by the Skype client for channel 'skype$skype_client_extension'\n"); + printf("(That's the one-word you registered as login to the Skype network)\n"); + printf("\n"); + printf("NB: DON'T ACCEPT the DEFAULT, write YOUR OWN\n"); + $skype_username = &promptUser("Enter the Skype username for channel 'skype$skype_client_extension'", "$skype_username"); + $skype_username_array[$count] = $skype_username; + system("clear"); + printf("\n"); + printf("I need the Skype password which will be used by the Skype client 'skype$skype_client_extension'\n"); + printf("(That's the one-word you registered as password to the Skype network)\n"); + printf("\n"); + printf("NB: DON'T ACCEPT the DEFAULT, write YOUR OWN\n"); + $skype_password = &promptUser("Enter the Skype password for '$skype_username'", "$skype_password"); + $skype_password_array[$count] = $skype_password; + system("clear"); + } + +} + +### GETTING FINAL APPROVAL ### +printf("\n"); +printf("Please check the following values:\n"); +printf("\n"); +printf("directory for downloading and unpacking Skype client:\n'$skype_download_dir'\n"); +printf("directory for Skype client binary:\n'$skype_binary_dir'\n"); +printf("directory for FreeSWITCH modules' configs:\n'$freeswitch_modules_config_dir'\n"); +printf("directory for fake sound driver:\n'$skypopen_sound_driver_dir'\n"); +printf("directory for Skype clients configs:\n'$skype_config_dir'\n"); +printf("directory for Skype clients startup script:\n'$skype_startup_dir'\n"); +printf("directory for Skype clients symlinks:\n'$skype_symlinks_dir'\n"); +printf("how many Skype clients to launch: '$skype_clients_to_be_launched'\n"); +if($multi_skypeusername eq "one"){ + printf("Skype login: '$skype_username'\n"); + printf("Skype password: '$skype_password'\n"); +}else { + for($count=1; $count <= $skype_clients_to_be_launched ; $count++){ + $skype_client_extension = $skype_clients_starting_number + $count ; + printf("channel='skype$skype_client_extension' Skype login='$skype_username_array[$count]' Skype password='$skype_password_array[$count]'\n"); + } +} + +$sure = &promptUser("Are you sure you like the values? Write 'sure' for yes ", "$sure"); +if($sure ne "sure"){ + printf("No problem, please relaunch the installer and begin again\n"); + exit 0; +} +system("clear"); + +printf("\n"); +printf("GREAT! Please stand back, I'm working...\n"); +printf("\n"); + +#### EXECUTION ### + +system("mkdir -p $skype_download_dir"); +system("cd $skype_download_dir ; wget -c $skype_download_url"); +system("cd $skype_download_dir ; tar -xzf $skype_download_pkg"); + +system("mkdir -p $skype_binary_dir"); +system("cd $skype_download_dir/usr/bin ; cp skype $skype_binary_dir/"); +system("mkdir -p $skype_share_dir"); +system("cd $skype_download_dir/usr/share/skype ; cp -a avatars $skype_share_dir/"); +system("cd $skype_download_dir/usr/share/skype ; cp -a sounds $skype_share_dir/"); +system("cd $skype_download_dir/usr/share/skype ; cp -a lang $skype_share_dir/"); + + +system("mkdir -p $skypopen_sound_driver_dir"); +system("cp ../oss/skypopen.ko $skypopen_sound_driver_dir/"); +system("mkdir -p $skype_config_dir"); +system("mkdir -p $skype_startup_dir"); +system("mkdir -p $skype_symlinks_dir"); + +system("echo \"\" > $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); + + +system("echo \"#!/bin/sh\" > $skype_startup_dir/start_skype_clients.sh"); +system("echo \"#Unload possible ALSA sound modules that would conflict with our OSS fake module\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"rmmod snd_pcm_oss\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"rmmod snd_mixer_oss\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"rmmod snd_seq_oss\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"sleep 1\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"#Create the inode our fake sound driver will use\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"mknod /dev/dsp c 14 3\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"#Load our OSS fake module\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"insmod $skypopen_sound_driver_dir/skypopen.ko\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo >> $skype_startup_dir/start_skype_clients.sh"); +system("echo >> $skype_startup_dir/start_skype_clients.sh"); + + +for ($count = 1; $count <= $skype_clients_to_be_launched; $count++) { + $skype_client_extension = $skype_clients_starting_number + $count ; + $skype_login=$skype_username_array[$count]; + $skype_passwd=$skype_password_array[$count]; + system("ln -s $skype_binary_dir/skype $skype_symlinks_dir/skype$skype_client_extension"); + system("mkdir -p $skype_config_dir/skype$skype_client_extension"); + system("cp -a ../configs/skype-client-configuration-dir-template/skypeclient01/shared.* $skype_config_dir/skype$skype_client_extension"); + system("cp -a ../configs/skype-client-configuration-dir-template/skypeclient01/skypenameA $skype_config_dir/skype$skype_client_extension/$skype_login"); + + system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); + if($multi_skypeusername ne "one"){ + system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); + } + system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); + system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); + + system("echo \"#start the fake X server on the given port\" >> $skype_startup_dir/start_skype_clients.sh"); + system("echo \"/usr/bin/Xvfb :$skype_client_extension -ac -nolisten tcp -screen 0 640x480x8 &\" >> $skype_startup_dir/start_skype_clients.sh"); + system("echo \"sleep 3\" >> $skype_startup_dir/start_skype_clients.sh"); + system("echo \"# start a Skype client instance that will connect to the X server above, and will login to the Skype network using the 'username password' you send to it on stdin.\" >> $skype_startup_dir/start_skype_clients.sh"); + system("echo \"su root -c \\\"/bin/echo '$skype_login $skype_passwd'| DISPLAY=:$skype_client_extension $skype_symlinks_dir/skype$skype_client_extension --dbpath=$skype_config_dir/skype$skype_client_extension --pipelogin &\\\"\" >> $skype_startup_dir/start_skype_clients.sh"); + system("echo \"sleep 7\" >> $skype_startup_dir/start_skype_clients.sh"); + system("echo >> $skype_startup_dir/start_skype_clients.sh"); +} + +system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); + +system("echo \"exit 0\" >> $skype_startup_dir/start_skype_clients.sh"); + + +printf("\n"); +printf("SUCCESS!!!\n"); +printf("\n"); + + +#=========================================================================# + + +#-------------------------------------------------------------------------# +# promptUser, a Perl subroutine to prompt a user for input. +# Copyright 2010 Alvin Alexander, devdaily.com. +# This code is shared here under the +# Creative Commons Attribution-ShareAlike Unported 3.0 license. +# See http://creativecommons.org/licenses/by-sa/3.0/ for more information. +#-------------------------------------------------------------------------# + +# Original at: http://www.devdaily.com/perl/edu/articles/pl010005 +# Modified to get confirmations by Giovanni Maruzzelli + +#----------------------------( promptUser )-----------------------------# +# # +# FUNCTION: promptUser # +# # +# PURPOSE: Prompt the user for some type of input, and return the # +# input back to the calling program. # +# # +# ARGS: $promptString - what you want to prompt the user with # +# $defaultValue - (optional) a default value for the prompt # +# # +#-------------------------------------------------------------------------# + +sub promptUser { + +#-------------------------------------------------------------------# +# two possible input arguments - $promptString, and $defaultValue # +# make the input arguments local variables. # +#-------------------------------------------------------------------# + + local($promptString,$defaultValue) = @_; + local $input; + local $confirm; + local $gave; + +#-------------------------------------------------------------------# +# if there is a default value, use the first print statement; if # +# no default is provided, print the second string. # +#-------------------------------------------------------------------# + + while(1){ + printf("\n"); + if ($defaultValue) { + print $promptString, "\n[", $defaultValue, "]: "; + } else { + print $promptString, ": "; + } + + $| = 1; # force a flush after our print + $input = ; # get the input from STDIN (presumably the keyboard) + + +#------------------------------------------------------------------# +# remove the newline character from the end of the input the user # +# gave us. # +#------------------------------------------------------------------# + + chomp($input); + + $gave = $input ? $input : $defaultValue; + print("You gave: '$gave'\nIt's OK? Please answer 'Y' for yes or 'N' for not [N]: "); + $| = 1; # force a flush after our print + $confirm = ; + chomp($confirm); + if($confirm eq "Y" or $confirm eq "y"){ + last; + } + } +#-----------------------------------------------------------------# +# if we had a $default value, and the user gave us input, then # +# return the input; if we had a default, and they gave us no # +# no input, return the $defaultValue. # +# # +# if we did not have a default value, then just return whatever # +# the user gave us. if they just hit the key, # +# the calling routine will have to deal with that. # +#-----------------------------------------------------------------# + + if ("$defaultValue") { + return $input ? $input : $defaultValue; # return $_ if it has a value + } else { + return $input; + } +} + diff --git a/src/mod/endpoints/mod_skypopen/asterisk/Makefile b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/Makefile similarity index 100% rename from src/mod/endpoints/mod_skypopen/asterisk/Makefile rename to src/mod/endpoints/mod_skypopen/old-stuff/asterisk/Makefile diff --git a/src/mod/endpoints/mod_skypopen/asterisk/README b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/README similarity index 100% rename from src/mod/endpoints/mod_skypopen/asterisk/README rename to src/mod/endpoints/mod_skypopen/old-stuff/asterisk/README diff --git a/src/mod/endpoints/mod_skypopen/asterisk/chan_skypiax.c b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/chan_skypiax.c similarity index 100% rename from src/mod/endpoints/mod_skypopen/asterisk/chan_skypiax.c rename to src/mod/endpoints/mod_skypopen/old-stuff/asterisk/chan_skypiax.c diff --git a/src/mod/endpoints/mod_skypopen/asterisk/cyg_no_pthread_kill.c b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/cyg_no_pthread_kill.c similarity index 100% rename from src/mod/endpoints/mod_skypopen/asterisk/cyg_no_pthread_kill.c rename to src/mod/endpoints/mod_skypopen/old-stuff/asterisk/cyg_no_pthread_kill.c diff --git a/src/mod/endpoints/mod_skypopen/asterisk/skypiax.conf b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/skypiax.conf similarity index 100% rename from src/mod/endpoints/mod_skypopen/asterisk/skypiax.conf rename to src/mod/endpoints/mod_skypopen/old-stuff/asterisk/skypiax.conf diff --git a/src/mod/endpoints/mod_skypopen/asterisk/skypiax.h b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/skypiax.h similarity index 100% rename from src/mod/endpoints/mod_skypopen/asterisk/skypiax.h rename to src/mod/endpoints/mod_skypopen/old-stuff/asterisk/skypiax.h diff --git a/src/mod/endpoints/mod_skypopen/alsa/dummy.c b/src/mod/endpoints/mod_skypopen/old-stuff/dummy.c similarity index 100% rename from src/mod/endpoints/mod_skypopen/alsa/dummy.c rename to src/mod/endpoints/mod_skypopen/old-stuff/dummy.c diff --git a/src/mod/endpoints/mod_skypopen/alsa/pcm_lib.c b/src/mod/endpoints/mod_skypopen/old-stuff/pcm_lib.c similarity index 100% rename from src/mod/endpoints/mod_skypopen/alsa/pcm_lib.c rename to src/mod/endpoints/mod_skypopen/old-stuff/pcm_lib.c diff --git a/src/mod/endpoints/mod_skypopen/alsa/pcm_native.c b/src/mod/endpoints/mod_skypopen/old-stuff/pcm_native.c similarity index 100% rename from src/mod/endpoints/mod_skypopen/alsa/pcm_native.c rename to src/mod/endpoints/mod_skypopen/old-stuff/pcm_native.c diff --git a/src/mod/endpoints/mod_skypopen/oss/Makefile b/src/mod/endpoints/mod_skypopen/oss/Makefile index 8df20f68c5..40b25f0e25 100644 --- a/src/mod/endpoints/mod_skypopen/oss/Makefile +++ b/src/mod/endpoints/mod_skypopen/oss/Makefile @@ -1,6 +1,6 @@ # Comment/uncomment the following line to disable/enable debugging #DEBUG = y -#LDDINC=/usr/src/linux-headers-2.6.32-26-server/include +#LDDINC= # Add your debugging flag (or not) to CFLAGS ifeq ($(DEBUG),y) diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c index 10a210a574..465480e055 100644 --- a/src/mod/endpoints/mod_skypopen/oss/main.c +++ b/src/mod/endpoints/mod_skypopen/oss/main.c @@ -43,12 +43,13 @@ #include "skypopen.h" /* local definitions */ + /* * Our parameters which can be set at load time. */ int skypopen_major = SKYPOPEN_MAJOR; -int skypopen_minor = 3; +int skypopen_minor = SKYPOPEN_MINOR; int skypopen_nr_devs = SKYPOPEN_NR_DEVS; /* number of bare skypopen devices */ module_param(skypopen_major, int, S_IRUGO); @@ -61,9 +62,6 @@ MODULE_LICENSE("Dual BSD/GPL"); static struct skypopen_dev *skypopen_devices; /* allocated in skypopen_init_module */ static int unload = 0; -#ifdef CENTOS -#define HRTIMER_MODE_REL HRTIMER_REL -#endif// CENTOS #ifndef WANT_HRTIMER void my_timer_callback_inq( unsigned long data ) @@ -84,7 +82,7 @@ void my_timer_callback_outq( unsigned long data ) } #else// WANT_HRTIMER -#ifndef CENTOS +#ifndef CENTOS_5 static enum hrtimer_restart my_hrtimer_callback_inq( struct hrtimer *timer_inq ) { struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq); @@ -113,7 +111,7 @@ static enum hrtimer_restart my_hrtimer_callback_outq( struct hrtimer *timer_outq return HRTIMER_RESTART; } -#else// CENTOS +#else// CENTOS_5 static int my_hrtimer_callback_inq( struct hrtimer *timer_inq ) { struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq); @@ -138,7 +136,7 @@ static int my_hrtimer_callback_outq( struct hrtimer *timer_outq ) return HRTIMER_RESTART; } -#endif// CENTOS +#endif// CENTOS_5 #endif// WANT_HRTIMER /* The clone-specific data structure includes a key field */ @@ -159,10 +157,6 @@ static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key) { struct skypopen_listitem *lptr; #ifdef WANT_HRTIMER -#if 0 - ktime_t ktime_inq; - ktime_t ktime_outq; -#endif //0 #endif// WANT_HRTIMER list_for_each_entry(lptr, &skypopen_c_list, list) { @@ -181,6 +175,7 @@ static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key) init_waitqueue_head(&lptr->device.inq); init_waitqueue_head(&lptr->device.outq); + #ifndef WANT_HRTIMER setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr ); setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr ); @@ -188,19 +183,6 @@ static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key) mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); printk( "Starting skypopen OSS driver write timer (%dms) skype client:(%d)\n", SKYPOPEN_SLEEP, current->tgid ); mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); -#else// WANT_HRTIMER -#if 0 - ktime_inq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000); - hrtimer_init( &lptr->device.timer_inq, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); - lptr->device.timer_inq.function = &my_hrtimer_callback_inq; - hrtimer_start( &lptr->device.timer_inq, ktime_inq, HRTIMER_MODE_REL ); - - ktime_outq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000); - hrtimer_init( &lptr->device.timer_outq, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); - lptr->device.timer_outq.function = &my_hrtimer_callback_outq; - hrtimer_start( &lptr->device.timer_outq, ktime_outq, HRTIMER_MODE_REL ); -#endif - #endif// WANT_HRTIMER /* place it in the list */ @@ -249,14 +231,12 @@ static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { DEFINE_WAIT(wait); - size_t written; struct skypopen_dev *dev = filp->private_data; if(unload) return -1; #ifdef WANT_HRTIMER -#if 1 if(dev->timer_inq_started == 0){ ktime_t ktime_inq; @@ -266,39 +246,13 @@ static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, hrtimer_start( &dev->timer_inq, ktime_inq, HRTIMER_MODE_REL ); dev->timer_inq_started = 1; } -#endif #endif// WANT_HRTIMER - //printk("READ\n"); prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); schedule(); finish_wait(&dev->inq, &wait); - - if (!count) - return 0; - - if (!access_ok(VERIFY_WRITE, buf, count)) - return -EFAULT; - - written = 0; - while (count) { - unsigned long unwritten; - size_t chunk = count; - - if (chunk > PAGE_SIZE) - chunk = PAGE_SIZE; /* Just for latency reasons */ - unwritten = __clear_user(buf, chunk); - written += chunk - unwritten; - if (unwritten) - break; - if (signal_pending(current)) - return written ? written : -ERESTARTSYS; - buf += chunk; - count -= chunk; - cond_resched(); - } - return written ? written : -EFAULT; + return count; } static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, @@ -311,7 +265,6 @@ static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t return -1; #ifdef WANT_HRTIMER -#if 1 if(dev->timer_outq_started == 0){ ktime_t ktime_outq; @@ -321,10 +274,8 @@ static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t hrtimer_start( &dev->timer_outq, ktime_outq, HRTIMER_MODE_REL ); dev->timer_outq_started = 1; } -#endif #endif// WANT_HRTIMER - //printk("WRITE\n"); prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE); schedule(); @@ -448,6 +399,7 @@ int skypopen_init_module(void) dev_t dev = 0; printk("skypopen OSS driver loading (www.freeswitch.org)\n"); + /* * Get a range of minor numbers to work with, asking for a dynamic * major unless directed otherwise at load time. diff --git a/src/mod/endpoints/mod_skypopen/oss/skypopen.h b/src/mod/endpoints/mod_skypopen/oss/skypopen.h index 2324e448cb..de38c791c9 100644 --- a/src/mod/endpoints/mod_skypopen/oss/skypopen.h +++ b/src/mod/endpoints/mod_skypopen/oss/skypopen.h @@ -1,6 +1,7 @@ /* * skypopen.h -- definitions for the char module * + * Copyright (C) 2010 Giovanni Maruzzelli * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet * Copyright (C) 2001 O'Reilly & Associates * @@ -18,22 +19,30 @@ #ifndef _SKYPOPEN_H_ #define _SKYPOPEN_H_ +#include #include /* needed for the _IOW etc stuff used later */ -#define SKYPOPEN_BLK 960 -#define SKYPOPEN_SLEEP 10 - -#define CENTOS - -#ifndef SKYPOPEN_MAJOR -#define SKYPOPEN_MAJOR 14 /* dynamic major by default */ -#endif - -#ifndef SKYPOPEN_NR_DEVS -#define SKYPOPEN_NR_DEVS 1 /* skypopen0 through skypopen3 */ -#endif +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18) +#define CENTOS_5 +#define WANT_HRTIMER /* undef this only if you don't want to use High Resolution Timers (why?) */ +#endif /* CentOS 5.x */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) #define WANT_HRTIMER +#endif /* HRTIMER */ + +#define SKYPOPEN_BLK 1920 +#define SKYPOPEN_SLEEP 20 + + +#define SKYPOPEN_MAJOR 14 /* dynamic major by default */ +#define SKYPOPEN_MINOR 3 /* dynamic major by default */ +#define SKYPOPEN_NR_DEVS 1 /* not useful, I'm too lazy to remove it */ + +#ifdef CENTOS_5 +#define HRTIMER_MODE_REL HRTIMER_REL +#endif// CENTOS_5 + struct skypopen_dev { struct cdev cdev; /* Char device structure */ wait_queue_head_t inq; /* read and write queues */ @@ -56,16 +65,4 @@ struct skypopen_dev { extern int skypopen_major; /* main.c */ extern int skypopen_nr_devs; - -/* - * Prototypes for shared functions - */ - -//ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, - //loff_t *f_pos); -//ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, - //loff_t *f_pos); -//int skypopen_ioctl(struct inode *inode, struct file *filp, - //unsigned int cmd, unsigned long arg); - #endif /* _SKYPOPEN_H_ */ diff --git a/src/mod/endpoints/mod_skypopen/osscuse/98-osscuse.rules b/src/mod/endpoints/mod_skypopen/osscuse/98-osscuse.rules deleted file mode 100644 index c1430fd5c0..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/98-osscuse.rules +++ /dev/null @@ -1,7 +0,0 @@ -# Since these devices are not part of 'sound' subsystem the group is forced -# to audio by name -# /dev/cuse can stay mode 0660 root:root since osspd is run as root -# and drops privileges to user level when opened by user -KERNEL=="dsp", GROUP="audio" -KERNEL=="mixer", GROUP="audio" -KERNEL=="adsp", GROUP="audio" diff --git a/src/mod/endpoints/mod_skypopen/osscuse/LICENSE b/src/mod/endpoints/mod_skypopen/osscuse/LICENSE deleted file mode 100644 index d511905c16..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/LICENSE +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/src/mod/endpoints/mod_skypopen/osscuse/Makefile b/src/mod/endpoints/mod_skypopen/osscuse/Makefile deleted file mode 100644 index a42d37a8a3..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -# These can be overridden if needed -# DESTDIR is completely respected -CC := gcc -AR := ar -CFLAGS := -Wall $(CFLAGS) -XLDFLAGS := $(LDFLAGS) -LDFLAGS := -L. -lossp $(LDFLAGS) -prefix := /usr/local -DESTDIR := -UDEVDIR := /etc/udev/rules.d - -ifeq "$(origin OSSPD_CFLAGS)" "undefined" -OSSPD_CFLAGS := $(shell pkg-config --cflags fuse) -endif - -ifeq "$(origin OSSPD_LDFLAGS)" "undefined" -OSSPD_LDFLAGS := $(shell pkg-config --libs fuse) -endif - -ifeq "$(origin OSSP_PADSP_CFLAGS)" "undefined" -OSSP_PADSP_CFLAGS := $(shell pkg-config --cflags libpulse) -endif - -ifeq "$(origin OSSP_PADSP_LDFLAGS)" "undefined" -OSSP_PADSP_LDFLAGS := $(shell pkg-config --libs libpulse) -endif - -ifeq "$(origin OSSP_ALSAP_CFLAGS)" "undefined" -OSSP_ALSAP_CFLAGS := $(shell pkg-config --libs alsa) -endif - -ifeq "$(origin OSSP_ALSAP_LDFLAGS)" "undefined" -OSSP_ALSAP_LDFLAGS := $(shell pkg-config --libs alsa) -endif - -headers := ossp.h ossp-util.h ossp-slave.h - -#all: osspd ossp-padsp ossp-alsap -all: osspd ossp-alsap - -install: - mkdir -p $(DESTDIR)$(prefix)/sbin - install -m755 osspd ossp-padsp ossp-alsap $(DESTDIR)$(prefix)/sbin - mkdir -p $(DESTDIR)$(UDEVDIR) - install -m644 98-osscuse.rules $(DESTDIR)$(UDEVDIR) - -libossp.a: ossp.c ossp.h ossp-util.c ossp-util.h ossp-slave.c ossp-slave.h - $(CC) $(CFLAGS) -c -o ossp.o ossp.c - $(CC) $(CFLAGS) -c -o ossp-util.o ossp-util.c - $(CC) $(CFLAGS) -c -o ossp-slave.o ossp-slave.c - $(AR) rc $@ ossp.o ossp-util.o ossp-slave.o - -osspd: osspd.c libossp.a $(headers) - $(CC) $(CFLAGS) $(OSSPD_CFLAGS) -o $@ $< $(OSSPD_LDFLAGS) $(LDFLAGS) - -ossp-padsp: ossp-padsp.c libossp.a $(headers) - $(CC) $(CFLAGS) $(OSSP_PADSP_CFLAGS) -o $@ $< $(OSSP_PADSP_LDFLAGS) $(LDFLAGS) - -ossp-alsap: ossp-alsap.c libossp.a $(headers) - $(CC) $(CFLAGS) $(OSSP_ALSAP_CFLAGS) -o $@ $< $(OSSP_ALSAP_LDFLAGS) $(LDFLAGS) - -osstest: osstest.c - $(CC) $(CFLAGS) -o $@ $< $(XLDFLAGS) - -test: osstest - @./osstest - -clean: - rm -f *.o *.a osspd ossp-padsp ossp-alsap osstest diff --git a/src/mod/endpoints/mod_skypopen/osscuse/README b/src/mod/endpoints/mod_skypopen/osscuse/README deleted file mode 100644 index 6b716c76e4..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/README +++ /dev/null @@ -1,119 +0,0 @@ - - OSS Proxy - emulate OSS device using CUSE - - Copyright (C) 2008-2009 SUSE Linux Products GmbH - Copyright (C) 2008-2009 Tejun Heo - -1. What is it? --------------- - -Well, first, OSS refers to Open Sound System. If it still doesn't -ring a bell, think /dev/dsp, /dev/adsp and /dev/mixer. - -Currently, Linux supports two audio programming interface - ALSA and -OSS. The latter one is deprecated and has been that way for a long -time but there still are applications which still use them including -UML (usermode Linux) host sound support. - -ALSA contains OSS emulation but sadly the emulation is behind -multiplexing layer (which is in userland) which means that if your -sound card doesn't support multiple audio streams, only either one of -ALSA or OSS interface would be usable at any given moment. - -There have been also attempts to emulate OSS in userland using dynamic -library preloading - aoss and more recently padsp. This works for -many applications but it's just not easy to emulate everything using -the technique. Things like polling, signals, forking, privilege -changes make it very difficult to emulate things reliably. - -OSS Proxy uses CUSE (extension of FUSE allowing character devices to -be implemented in userspace) to implement OSS interface - /dev/dsp, -/dev/adsp and /dev/mixer. From the POV of the applications, these -devices are proper character devices and behave exactly the same way -so it can be made quite versatile. - - -2. Hmmm... So, how does the whole thing work? ---------------------------------------------- - -The OSS Proxy daemon - osspd - should be started first. Note that -osspd will fail to start if sound device number regions are already -occupied. You'll need to turn off OSS or its emulation[1]. - -On startup, osspd creates /dev/dsp, /dev/adsp and /dev/mixer using -CUSE. When an application access one of the devices, all IOs are -redirected to osspd via CUSE. Upon receiving a new DSP open request, -osspd creates a slave process which drops the root privilege and -assumes the opening process's credentials. After handshaking, osspd -forwards all relevant IOs to the slave which is responsible for -actually playing the sound. - -Currently there's only one slave implemented - ossp-padsp, which as -the name suggests forwards (again) the sound to pulseaudio. To sum -up, the whole pipe looks like the following. - - App <-> /dev/dsp <-> CUSE <-> osspd <-> ossp-padsp <-> pulseaudio - -Which is a lot of forwarding, but on modern machines, it won't be too -noticeable. - - -3. What works? --------------- - -Well, MIDI part isn't implemented and I doubt it will be in any near -future but except that everything should work. Playing, recording, -5.1ch, A-V syncing, all should work. If not, it's a bug, so please -report. - -The mixer behaves a bit differently tho. In the original OSS, -/dev/mixer is the hardware mixer, so adjusting volumes there affects -all audio streams. When using ossp, each process group gets its own -mixer and the mixer always contains only two knobs - PCM and IGAIN. -Combined with per-stream volume control of pulseaudio, this scheme -works quite well for applications with embedded volume control -although it makes standalone OSS mixer programs virtually useless[2]. - - -4. How do I use it? -------------------- - -First you need CUSE support in kernel which might land on 2.6.28 with -sufficient luck[3] and then you also need libfuse which supports -CUSE[4]. Once you have both, it should be easy. First build it by -running `make'. You can set OSSPD_CFLAGS, OSSPD_LDFLAGS, -OSSP_PADSP_CFLAGS and OSSP_PADSP_LDFLAGS if you have stuff at -non-default locations. - -After build completes, there will be two executables - `osspd' and -`ossp-padsp'. Just copy them to where other system executables live. -Specific location doesn't matter as long as both files end up in the -same directory. - -Execute `osspd'. It will create the device files and you're all set. -`osspd' uses syslog with LOG_DAEMON facility, so if something doesn't -work take a look at what osspd complains about. - - -[1] As of this writing, turning on any sound support makes the - soundcore module claim OSS device regions. Patch to make it claim - OSS device regions only when OSS support or emulation is enabled - is scheduled for 2.6.28. Even with the patch, soundcore will - claim OSS device regions if OSS support or ALSA OSS emulation is - enabled. Make sure they're turned off. - -[2] If you have a strong reason to use standalone OSS mixer program, - you can play some shell tricks to put it into the same process - group as the target audio application. e.g. To use aumix with - mpg123 - `(mpg123 asdf.mp3 > /dev/null 2>&1 & aumix)', but - seriously, just use PA or ALSA one. - -[3] For the time being, here's the git tree with all the necessary - changes. This tree is base on top of 2.6.27-rc3. - - http://git.kernel.org/?p=linux/kernel/git/tj/misc.git;a=shortlog;h=cuse - git://git.kernel.org/pub/scm/linux/kernel/git/tj/misc.git cuse - -[4] And libfuse with the modifications can be found at... - - http://userweb.kernel.org/~tj/ossp/fuse-cuse.tar.gz diff --git a/src/mod/endpoints/mod_skypopen/osscuse/ossp-alsap.c b/src/mod/endpoints/mod_skypopen/osscuse/ossp-alsap.c deleted file mode 100644 index 607e05ca84..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/ossp-alsap.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * ossp-alsap - ossp DSP slave which forwards to alsa - * - * Copyright (C) 2009 Maarten Lankhorst - * - * This file is released under the GPLv2. - * - * Why an alsa plugin as well? Just to show how much - * the alsa userspace api sucks ;-) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "ossp-slave.h" - -enum { - AFMT_FLOAT = 0x00004000, - AFMT_S32_LE = 0x00001000, - AFMT_S32_BE = 0x00002000, -}; - -static size_t page_size; - -/* alsa structures */ -static snd_pcm_t *pcm[2]; -static snd_pcm_hw_params_t *hw_params; -static snd_pcm_sw_params_t *sw_params; -static int block; - -static unsigned int byte_counter[2]; -static snd_pcm_uframes_t mmap_pos[2]; -static int stream_corked[2]; -static int stream_notify; - -static struct format { - snd_pcm_format_t format; - snd_pcm_sframes_t rate; - int channels; -} hw_format = { SND_PCM_FORMAT_U8, 8000, 1 }; - -#if 0 -/* future mmap stuff */ -static size_t mmap_raw_size, mmap_size; -static int mmap_fd[2] = { -1, -1 }; -static void *mmap_map[2]; -static uint64_t mmap_idx[2]; /* mmap pointer */ -static uint64_t mmap_last_idx[2]; /* last idx for get_ptr */ -static struct ring_buf mmap_stg[2]; /* staging ring buffer */ -static size_t mmap_lead[2]; /* lead bytes */ -static int mmap_sync[2]; /* sync with backend stream */ -#endif - -static snd_pcm_format_t fmt_oss_to_alsa(int fmt) -{ - switch (fmt) { - case AFMT_U8: return SND_PCM_FORMAT_U8; - case AFMT_A_LAW: return SND_PCM_FORMAT_A_LAW; - case AFMT_MU_LAW: return SND_PCM_FORMAT_MU_LAW; - case AFMT_S16_LE: return SND_PCM_FORMAT_S16_LE; - case AFMT_S16_BE: return SND_PCM_FORMAT_S16_BE; - case AFMT_FLOAT: return SND_PCM_FORMAT_FLOAT; - case AFMT_S32_LE: return SND_PCM_FORMAT_S32_LE; - case AFMT_S32_BE: return SND_PCM_FORMAT_S32_BE; - default: return SND_PCM_FORMAT_U8; - } -} - -static int fmt_alsa_to_oss(snd_pcm_format_t fmt) -{ - switch (fmt) { - case SND_PCM_FORMAT_U8: return AFMT_U8; - case SND_PCM_FORMAT_A_LAW: return AFMT_A_LAW; - case SND_PCM_FORMAT_MU_LAW: return AFMT_MU_LAW; - case SND_PCM_FORMAT_S16_LE: return AFMT_S16_LE; - case SND_PCM_FORMAT_S16_BE: return AFMT_S16_BE; - case SND_PCM_FORMAT_FLOAT: return AFMT_FLOAT; - case SND_PCM_FORMAT_S32_LE: return AFMT_S32_LE; - case SND_PCM_FORMAT_S32_BE: return AFMT_S32_BE; - default: return AFMT_U8; - } -} - -static void flush_streams(int drain) -{ - /* FIXME: snd_pcm_drain appears to be able to deadlock, - * always drop or check state? */ - if (drain) { - if (pcm[PLAY]) - snd_pcm_drain(pcm[PLAY]); - if (pcm[REC]) - snd_pcm_drain(pcm[REC]); - } else { - if (pcm[PLAY]) - snd_pcm_drop(pcm[PLAY]); - if (pcm[REC]) - snd_pcm_drop(pcm[REC]); - } - - /* XXX: Really needed? */ -#if 0 - if (pcm[PLAY]) { - snd_pcm_close(pcm[PLAY]); - snd_pcm_open(&pcm[PLAY], "default", - SND_PCM_STREAM_PLAYBACK, block); - } - if (pcm[REC]) { - snd_pcm_close(pcm[REC]); - snd_pcm_open(&pcm[REC], "default", - SND_PCM_STREAM_CAPTURE, block); - } -#endif -} - -static void kill_streams(void) -{ - flush_streams(0); -} - -static int trigger_streams(int play, int rec) -{ - int ret = 0; - - if (pcm[PLAY] && play >= 0) { - ret = snd_pcm_sw_params_set_start_threshold(pcm[PLAY], sw_params, - play ? 1 : -1); - if (ret >= 0) - snd_pcm_sw_params(pcm[PLAY], sw_params); - } - if (ret >= 0 && pcm[REC] && rec >= 0) { - ret = snd_pcm_sw_params_set_start_threshold(pcm[REC], sw_params, - rec ? 1 : -1); - if (ret >= 0) - snd_pcm_sw_params(pcm[REC], sw_params); - } - - return ret; -} - -static ssize_t alsap_mixer(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ -return -EBUSY; -} - -static int set_hw_params(snd_pcm_t *pcm) -{ - int ret; - unsigned rate; - - ret = snd_pcm_hw_params_any(pcm, hw_params); - if (ret >= 0) - ret = snd_pcm_hw_params_set_access(pcm, hw_params, - SND_PCM_ACCESS_RW_INTERLEAVED); - rate = hw_format.rate; - if (ret >= 0) - ret = snd_pcm_hw_params_set_rate_minmax(pcm, hw_params, - &rate, NULL, - &rate, NULL); - if (ret >= 0) - ret = snd_pcm_hw_params_set_format(pcm, hw_params, hw_format.format); - if (ret >= 0) - ret = snd_pcm_hw_params_set_channels(pcm, hw_params, - hw_format.channels); - if (ret >= 0) - ret = snd_pcm_hw_params(pcm, hw_params); - if (ret >= 0) - ret = snd_pcm_sw_params_current(pcm, sw_params); - if (ret >= 0) - ret = snd_pcm_sw_params(pcm, sw_params); - return ret; -} - -static ssize_t alsap_open(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - struct ossp_dsp_open_arg *arg = carg; - int ret; - block = arg->flags & O_NONBLOCK ? SND_PCM_NONBLOCK : 0; - int access; -// block |= SND_PCM_ASYNC; - /* Woop dee dooo.. I love handling things in SIGIO (PAIN!!) - * Probably needed for MMAP - */ - - if (!hw_params) - ret = snd_pcm_hw_params_malloc(&hw_params); - if (ret < 0) - return ret; - - if (!sw_params) - ret = snd_pcm_sw_params_malloc(&sw_params); - if (ret < 0) - return ret; - - if (pcm[PLAY]) - snd_pcm_close(pcm[PLAY]); - if (pcm[REC]) - snd_pcm_close(pcm[REC]); - pcm[REC] = pcm[PLAY] = NULL; - - access = arg->flags & O_ACCMODE; - if (access == O_WRONLY || access == O_RDWR) { - ret = snd_pcm_open(&pcm[PLAY], "default", - SND_PCM_STREAM_PLAYBACK, block); - if (ret >= 0) - ret = set_hw_params(pcm[PLAY]); - } - - if (ret >= 0 && (access == O_RDONLY || access == O_RDWR)) { - ret = snd_pcm_open(&pcm[REC], "default", - SND_PCM_STREAM_CAPTURE, block); - if (ret >= 0) - ret = set_hw_params(pcm[REC]); - } - - if (ret < 0) { - if (pcm[PLAY]) - snd_pcm_close(pcm[PLAY]); - if (pcm[REC]) - snd_pcm_close(pcm[REC]); - pcm[REC] = pcm[PLAY] = NULL; - return ret; - } - return 0; -} - -#define GIOVANNI -#ifdef GIOVANNI - -#define GIOVA_SLEEP 40000 -#define GIOVA_BLK 3840 -static ssize_t alsap_write(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - usleep((GIOVA_SLEEP/GIOVA_BLK)* din_sz); - return din_sz; -} -static ssize_t alsap_read(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - usleep((GIOVA_SLEEP/GIOVA_BLK)* *dout_szp); - return *dout_szp; -} -#else// GIOVANNI -static ssize_t alsap_write(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ -// struct ossp_dsp_rw_arg *arg = carg; - int ret, insize; - - insize = snd_pcm_bytes_to_frames(pcm[PLAY], din_sz); - - if (snd_pcm_state(pcm[PLAY]) == SND_PCM_STATE_SETUP) - snd_pcm_prepare(pcm[PLAY]); - -// snd_pcm_start(pcm[PLAY]); - ret = snd_pcm_writei(pcm[PLAY], din, insize); - if (ret < 0) - ret = snd_pcm_recover(pcm[PLAY], ret, 1); - - if (ret >= 0) - return snd_pcm_frames_to_bytes(pcm[PLAY], ret); - else - return ret; -} - -static ssize_t alsap_read(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ -// struct ossp_dsp_rw_arg *arg = carg; - int ret, outsize; - - outsize = snd_pcm_bytes_to_frames(pcm[REC], *dout_szp); - - if (snd_pcm_state(pcm[REC]) == SND_PCM_STATE_SETUP) - snd_pcm_prepare(pcm[REC]); - - ret = snd_pcm_readi(pcm[REC], dout, outsize); - if (ret < 0) - ret = snd_pcm_recover(pcm[REC], ret, 1); - if (ret >= 0) - *dout_szp = ret = snd_pcm_frames_to_bytes(pcm[REC], ret); - else - *dout_szp = 0; - - return ret; -} -#endif// GIOVANNI - -static ssize_t alsap_poll(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - unsigned revents = 0; - - stream_notify |= *(int *)carg; - - if (pcm[PLAY]) - revents |= POLLOUT; - if (pcm[REC]) - revents |= POLLIN; - - *(unsigned *)rarg = revents; - return 0; -} - - -static ssize_t alsap_flush(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - flush_streams(opcode == OSSP_DSP_SYNC); - return 0; -} - -static ssize_t alsap_post(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - int ret; - - ret = trigger_streams(1, 1); - if (ret >= 0 && pcm[PLAY]) - ret = snd_pcm_start(pcm[PLAY]); - if (pcm[REC]) - ret = snd_pcm_start(pcm[REC]); - return ret; -} - -static ssize_t alsap_get_param(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, - int tfd) -{ - int v = 0; - - switch (opcode) { - case OSSP_DSP_GET_RATE: - return hw_format.rate; - - case OSSP_DSP_GET_CHANNELS: - return hw_format.channels; - - case OSSP_DSP_GET_FORMAT: { - v = fmt_alsa_to_oss(hw_format.format); - break; - } - - case OSSP_DSP_GET_BLKSIZE: { - snd_pcm_uframes_t psize; - snd_pcm_hw_params_get_period_size(hw_params, &psize, NULL); - v = psize; - break; - } - - case OSSP_DSP_GET_FORMATS: - v = AFMT_U8 | AFMT_A_LAW | AFMT_MU_LAW | AFMT_S16_LE | - AFMT_S16_BE | AFMT_FLOAT | AFMT_S32_LE | AFMT_S32_BE; - break; - - case OSSP_DSP_GET_TRIGGER: - if (!stream_corked[PLAY]) - v |= PCM_ENABLE_OUTPUT; - if (!stream_corked[REC]) - v |= PCM_ENABLE_INPUT; - break; - - default: - assert(0); - } - - *(int *)rarg = v; - - return 0; -} - -static ssize_t alsap_set_param(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, - int tfd) -{ - int v = *(int *)carg; - int ret = 0; - - /* kill the streams before changing parameters */ - kill_streams(); - - switch (opcode) { - case OSSP_DSP_SET_RATE: { - hw_format.rate = v; - break; - } - - case OSSP_DSP_SET_CHANNELS: { - hw_format.channels = v; - break; - } - - case OSSP_DSP_SET_FORMAT: { - snd_pcm_format_t format = fmt_oss_to_alsa(v); - hw_format.format = format; - break; - } - - case OSSP_DSP_SET_SUBDIVISION: - if (!v) - v = 1; -#if 0 - if (!v) { - v = user_subdivision ?: 1; - break; - } - user_frag_size = 0; - user_subdivision = v; - break; - - case OSSP_DSP_SET_FRAGMENT: - user_subdivision = 0; - user_frag_size = 1 << (v & 0xffff); - user_max_frags = (v >> 16) & 0xffff; - if (user_frag_size < 4) - user_frag_size = 4; - if (user_max_frags < 2) - user_max_frags = 2; -#else - case OSSP_DSP_SET_FRAGMENT: -#endif - break; - default: - assert(0); - } - - if (pcm[PLAY]) - ret = set_hw_params(pcm[PLAY]); - if (ret >= 0 && pcm[REC]) - ret = set_hw_params(pcm[REC]); - - if (rarg) - *(int *)rarg = v; - return 0; -} - -static ssize_t alsap_set_trigger(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, - int fd) -{ - int enable = *(int *)carg; - - stream_corked[PLAY] = !!(enable & PCM_ENABLE_OUTPUT); - stream_corked[REC] = !!(enable & PCM_ENABLE_INPUT); - - return trigger_streams(enable & PCM_ENABLE_OUTPUT, - enable & PCM_ENABLE_INPUT); -} - -static ssize_t alsap_get_space(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - int dir = (opcode == OSSP_DSP_GET_OSPACE) ? PLAY : REC; - int underrun = 0; - struct audio_buf_info info = { }; - unsigned long bufsize; - snd_pcm_uframes_t avail, fragsize; - snd_pcm_state_t state; - - if (!pcm[dir]) - return -EINVAL; - - state = snd_pcm_state(pcm[dir]); - if (state == SND_PCM_STATE_XRUN) { - snd_pcm_recover(pcm[dir], -EPIPE, 0); - underrun = 1; - } else if (state == SND_PCM_STATE_SUSPENDED) { - snd_pcm_recover(pcm[dir], -ESTRPIPE, 0); - underrun = 1; - } - - snd_pcm_hw_params_current(pcm[dir], hw_params); - snd_pcm_hw_params_get_period_size(hw_params, &fragsize, NULL); - snd_pcm_hw_params_get_buffer_size(hw_params, &bufsize); - info.fragsize = snd_pcm_frames_to_bytes(pcm[dir], fragsize); - info.fragstotal = bufsize / fragsize; - if (!underrun) { - avail = snd_pcm_avail_update(pcm[dir]); - info.fragments = avail / fragsize; - } else - info.fragments = info.fragstotal; - - info.bytes = info.fragsize * info.fragments; - - *(struct audio_buf_info *)rarg = info; - return 0; -} - -static ssize_t alsap_get_ptr(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - int dir = (opcode == OSSP_DSP_GET_OPTR) ? PLAY : REC; - struct count_info info = { }; - - if (!pcm[dir]) - return -EIO; - - snd_pcm_hw_params_current(pcm[dir], hw_params); - info.bytes = byte_counter[dir]; - snd_pcm_hw_params_get_periods(hw_params, (unsigned int *)&info.blocks, NULL); - info.ptr = mmap_pos[dir]; - - *(struct count_info *)rarg = info; - return 0; -} - -static ssize_t alsap_get_odelay(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, - int fd) -{ - snd_pcm_sframes_t delay; - - if (!pcm[PLAY]) - return -EIO; - - if (snd_pcm_delay(pcm[PLAY], &delay) < 0) - return -EIO; - - *(int *)rarg = snd_pcm_frames_to_bytes(pcm[PLAY], delay); - return 0; -} - -static ossp_action_fn_t action_fn_tbl[OSSP_NR_OPCODES] = { - [OSSP_MIXER] = alsap_mixer, - [OSSP_DSP_OPEN] = alsap_open, - [OSSP_DSP_READ] = alsap_read, - [OSSP_DSP_WRITE] = alsap_write, - [OSSP_DSP_POLL] = alsap_poll, -#if 0 - [OSSP_DSP_MMAP] = alsap_mmap, - [OSSP_DSP_MUNMAP] = alsap_munmap, -#endif - [OSSP_DSP_RESET] = alsap_flush, - [OSSP_DSP_SYNC] = alsap_flush, - [OSSP_DSP_POST] = alsap_post, - [OSSP_DSP_GET_RATE] = alsap_get_param, - [OSSP_DSP_GET_CHANNELS] = alsap_get_param, - [OSSP_DSP_GET_FORMAT] = alsap_get_param, - [OSSP_DSP_GET_BLKSIZE] = alsap_get_param, - [OSSP_DSP_GET_FORMATS] = alsap_get_param, - [OSSP_DSP_SET_RATE] = alsap_set_param, - [OSSP_DSP_SET_CHANNELS] = alsap_set_param, - [OSSP_DSP_SET_FORMAT] = alsap_set_param, - [OSSP_DSP_SET_SUBDIVISION] = alsap_set_param, - [OSSP_DSP_SET_FRAGMENT] = alsap_set_param, - [OSSP_DSP_GET_TRIGGER] = alsap_get_param, - [OSSP_DSP_SET_TRIGGER] = alsap_set_trigger, - [OSSP_DSP_GET_OSPACE] = alsap_get_space, - [OSSP_DSP_GET_ISPACE] = alsap_get_space, - [OSSP_DSP_GET_OPTR] = alsap_get_ptr, - [OSSP_DSP_GET_IPTR] = alsap_get_ptr, - [OSSP_DSP_GET_ODELAY] = alsap_get_odelay, -}; - -static int action_pre(void) -{ - return 0; -} - -static void action_post(void) -{ -} - -int main(int argc, char **argv) -{ - int rc; - - ossp_slave_init(argc, argv); - - page_size = sysconf(_SC_PAGE_SIZE); - - /* Okay, now we're open for business */ - rc = 0; - do { - rc = ossp_slave_process_command(ossp_cmd_fd, action_fn_tbl, - action_pre, action_post); - } while (rc > 0); - - return rc ? 1 : 0; -} diff --git a/src/mod/endpoints/mod_skypopen/osscuse/ossp-slave.c b/src/mod/endpoints/mod_skypopen/osscuse/ossp-slave.c deleted file mode 100644 index 4c5cb2d129..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/ossp-slave.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * ossp-slave - OSS Proxy: Common codes for slaves - * - * Copyright (C) 2008-2010 SUSE Linux Products GmbH - * Copyright (C) 2008-2010 Tejun Heo - * - * This file is released under the GPLv2. - */ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ossp-slave.h" - -static const char *usage = -"usage: ossp-SLAVE [options]\n" -"\n" -"proxies commands from osspd to pulseaudio\n" -"\n" -"options:\n" -" -u UID uid to use\n" -" -g GID gid to use\n" -" -c CMD_FD fd to receive commands from osspd\n" -" -n NOTIFY_FD fd to send async notifications to osspd\n" -" -m MMAP_FD fd to use for mmap\n" -" -o MMAP_OFFSET mmap offset\n" -" -s MMAP_SIZE mmap size\n" -" -l LOG_LEVEL set log level\n" -" -t enable log timestamps\n"; - -char ossp_user_name[OSSP_USER_NAME_LEN]; -int ossp_cmd_fd = -1, ossp_notify_fd = -1; -void *ossp_mmap_addr[2]; - -void ossp_slave_init(int argc, char **argv) -{ - int have_uid = 0, have_gid = 0; - uid_t uid; - gid_t gid; - int mmap_fd = -1; - off_t mmap_off = 0; - size_t mmap_size = 0; - int opt; - struct passwd *pw, pw_buf; - struct sigaction sa; - char pw_sbuf[sysconf(_SC_GETPW_R_SIZE_MAX)]; - - while ((opt = getopt(argc, argv, "u:g:c:n:m:o:s:l:t")) != -1) { - switch (opt) { - case 'u': - have_uid = 1; - uid = strtol(optarg, NULL, 0); - break; - case 'g': - have_gid = 1; - gid = strtol(optarg, NULL, 0); - break; - case 'c': - ossp_cmd_fd = strtol(optarg, NULL, 0); - break; - case 'n': - ossp_notify_fd = strtol(optarg, NULL, 0); - break; - case 'm': - mmap_fd = strtol(optarg, NULL, 0); - break; - case 'o': - mmap_off = strtoull(optarg, NULL, 0); - break; - case 's': - mmap_size = strtoul(optarg, NULL, 0); - break; - case 'l': - ossp_log_level = strtol(optarg, NULL, 0); - break; - case 't': - ossp_log_timestamp = 1; - break; - } - } - - if (!have_uid || !have_gid || ossp_cmd_fd < 0 || ossp_notify_fd < 0) { - fprintf(stderr, usage); - _exit(1); - } - - snprintf(ossp_user_name, sizeof(ossp_user_name), "uid%d", uid); - if (getpwuid_r(uid, &pw_buf, pw_sbuf, sizeof(pw_sbuf), &pw) == 0) - snprintf(ossp_user_name, sizeof(ossp_user_name), "%s", - pw->pw_name); - - snprintf(ossp_log_name, sizeof(ossp_log_name), "ossp-padsp[%s:%d]", - ossp_user_name, getpid()); - - if (mmap_fd >= 0) { - void *p; - - if (!mmap_off || !mmap_size) { - fprintf(stderr, usage); - _exit(1); - } - - p = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, - mmap_fd, mmap_off); - if (p == MAP_FAILED) - fatal_e(-errno, "mmap failed"); - - ossp_mmap_addr[PLAY] = p; - ossp_mmap_addr[REC] = p + mmap_size / 2; - close(mmap_fd); - } - - /* mmap done, drop privileges */ - if (setresgid(gid, gid, gid) || setresuid(uid, uid, uid)) - fatal_e(-errno, "failed to drop privileges"); - - /* block SIGPIPE */ - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_IGN; - if (sigaction(SIGPIPE, &sa, NULL)) - fatal_e(-errno, "failed to ignore SIGPIPE"); -} - -int ossp_slave_process_command(int cmd_fd, - ossp_action_fn_t const *action_fn_tbl, - int (*action_pre_fn)(void), - void (*action_post_fn)(void)) -{ - static struct sized_buf carg_sbuf = { }, rarg_sbuf = { }; - static struct sized_buf din_sbuf = { }, dout_sbuf = { }; - struct ossp_cmd cmd; - int fd = -1; - char cmsg_buf[CMSG_SPACE(sizeof(fd))]; - struct iovec iov = { &cmd, sizeof(cmd) }; - struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1, - .msg_control = cmsg_buf, - .msg_controllen = sizeof(cmsg_buf) }; - struct cmsghdr *cmsg; - size_t carg_size, din_size, rarg_size, dout_size; - char *carg = NULL, *din = NULL, *rarg = NULL, *dout = NULL; - struct ossp_reply reply = { .magic = OSSP_REPLY_MAGIC }; - ssize_t ret; - - ret = recvmsg(cmd_fd, &msg, 0); - if (ret == 0) - return 0; - if (ret < 0) { - ret = -errno; - err_e(ret, "failed to read command channel"); - return ret; - } - - if (ret != sizeof(cmd)) { - err("command struct size mismatch (%zu, should be %zu)", - ret, sizeof(cmd)); - return -EINVAL; - } - - if (cmd.magic != OSSP_CMD_MAGIC) { - err("illegal command magic 0x%x", cmd.magic); - return -EINVAL; - } - - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == SOL_SOCKET && - cmsg->cmsg_type == SCM_RIGHTS) - fd = *(int *)CMSG_DATA(cmsg); - else { - err("unknown cmsg %d:%d received (opcode %d)", - cmsg->cmsg_level, cmsg->cmsg_type, cmd.opcode); - return -EINVAL; - } - } - - if (cmd.opcode >= OSSP_NR_OPCODES) { - err("unknown opcode %d", cmd.opcode); - return -EINVAL; - } - - carg_size = ossp_arg_sizes[cmd.opcode].carg_size; - din_size = cmd.din_size; - rarg_size = ossp_arg_sizes[cmd.opcode].rarg_size; - dout_size = cmd.dout_size; - - if ((fd >= 0) != ossp_arg_sizes[cmd.opcode].has_fd) { - err("fd=%d unexpected for opcode %d", fd, cmd.opcode); - return -EINVAL; - } - - if (ensure_sbuf_size(&carg_sbuf, carg_size) || - ensure_sbuf_size(&din_sbuf, din_size) || - ensure_sbuf_size(&rarg_sbuf, rarg_size) || - ensure_sbuf_size(&dout_sbuf, dout_size)) { - err("failed to allocate command buffers"); - return -ENOMEM; - } - - if (carg_size) { - carg = carg_sbuf.buf; - ret = read_fill(cmd_fd, carg, carg_size); - if (ret < 0) - return ret; - } - if (din_size) { - din = din_sbuf.buf; - ret = read_fill(cmd_fd, din, din_size); - if (ret < 0) - return ret; - } - if (rarg_size) - rarg = rarg_sbuf.buf; - if (dout_size) - dout = dout_sbuf.buf; - - ret = -EINVAL; - if (action_fn_tbl[cmd.opcode]) { - ret = action_pre_fn(); - if (ret == 0) { - ret = action_fn_tbl[cmd.opcode](cmd.opcode, carg, - din, din_size, rarg, - dout, &dout_size, fd); - action_post_fn(); - } - } - - reply.result = ret; - if (ret >= 0) - reply.dout_size = dout_size; - else { - rarg_size = 0; - dout_size = 0; - } - - if (write_fill(cmd_fd, &reply, sizeof(reply)) < 0 || - write_fill(cmd_fd, rarg, rarg_size) < 0 || - write_fill(cmd_fd, dout, dout_size) < 0) - return -EIO; - - return 1; -} diff --git a/src/mod/endpoints/mod_skypopen/osscuse/ossp-slave.h b/src/mod/endpoints/mod_skypopen/osscuse/ossp-slave.h deleted file mode 100644 index 10c22cdb02..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/ossp-slave.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * ossp-slave - OSS Proxy: Common codes for slaves - * - * Copyright (C) 2008-2010 SUSE Linux Products GmbH - * Copyright (C) 2008-2010 Tejun Heo - * - * This file is released under the GPLv2. - */ - -#ifndef _OSSP_SLAVE_H -#define _OSSP_SLAVE_H - -#include "ossp.h" -#include "ossp-util.h" - -#define OSSP_USER_NAME_LEN 128 - -extern char ossp_user_name[OSSP_USER_NAME_LEN]; -extern int ossp_cmd_fd, ossp_notify_fd; -extern void *ossp_mmap_addr[2]; - -void ossp_slave_init(int argc, char **argv); -int ossp_slave_process_command(int cmd_fd, - ossp_action_fn_t const *action_fn_tbl, - int (*action_pre_fn)(void), - void (*action_post_fn)(void)); - -#endif /* _OSSP_SLAVE_H */ diff --git a/src/mod/endpoints/mod_skypopen/osscuse/ossp-util.c b/src/mod/endpoints/mod_skypopen/osscuse/ossp-util.c deleted file mode 100644 index 325cefd5fd..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/ossp-util.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * ossp-util - OSS Proxy: Common utilities - * - * Copyright (C) 2008-2010 SUSE Linux Products GmbH - * Copyright (C) 2008-2010 Tejun Heo - * - * This file is released under the GPLv2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ossp-util.h" - -#define BIT(nr) (1UL << (nr)) -#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) -#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) -#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) -#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) - -char ossp_log_name[OSSP_LOG_NAME_LEN]; -int ossp_log_level = OSSP_LOG_DFL; -int ossp_log_timestamp; - -static const char *severity_strs[] = { - [OSSP_LOG_CRIT] = "CRIT", - [OSSP_LOG_ERR] = " ERR", - [OSSP_LOG_WARN] = "WARN", - [OSSP_LOG_INFO] = NULL, - [OSSP_LOG_DBG0] = "DBG0", - [OSSP_LOG_DBG1] = "DBG1", -}; - -static int severity_map[] = { - [OSSP_LOG_CRIT] = LOG_ERR, - [OSSP_LOG_ERR] = LOG_ERR, - [OSSP_LOG_WARN] = LOG_WARNING, - [OSSP_LOG_INFO] = LOG_INFO, - [OSSP_LOG_DBG0] = LOG_DEBUG, - [OSSP_LOG_DBG1] = LOG_DEBUG, -}; - -void log_msg(int severity, const char *fmt, ...) -{ - static int syslog_opened = 0; - char buf[1024]; - size_t len = sizeof(buf), off = 0; - va_list ap; - - if (severity > abs(ossp_log_level)) - return; - - if (ossp_log_level < 0 && !syslog_opened) - openlog(ossp_log_name, 0, LOG_DAEMON); - - assert(severity >= 0 && severity < ARRAY_SIZE(severity_strs)); - - if (ossp_log_timestamp) { - static uint64_t start; - uint64_t now; - struct timeval tv; - gettimeofday(&tv, NULL); - now = tv.tv_sec * 1000 + tv.tv_usec / 1000; - if (!start) - start = now; - - off += snprintf(buf + off, len - off, "<%08"PRIu64"> ", - now - start); - } - - if (ossp_log_level > 0) { - char sev_buf[16] = ""; - if (severity_strs[severity]) - snprintf(sev_buf, sizeof(sev_buf), " %s", - severity_strs[severity]); - off += snprintf(buf + off, len - off, "%s%s: ", - ossp_log_name, sev_buf); - } else if (severity_strs[severity]) - off += snprintf(buf + off, len - off, "%s ", - severity_strs[severity]); - - va_start(ap, fmt); - off += vsnprintf(buf + off, len - off, fmt, ap); - va_end(ap); - - off += snprintf(buf + off, len - off, "\n"); - - if (ossp_log_level > 0) - fputs(buf, stderr); - else - syslog(severity_map[severity], "%s", buf); -} - -int read_fill(int fd, void *buf, size_t size) -{ - while (size) { - ssize_t ret; - int rc; - - ret = read(fd, buf, size); - if (ret <= 0) { - if (ret == 0) - rc = -EIO; - else - rc = -errno; - err_e(rc, "failed to read_fill %zu bytes from fd %d", - size, fd); - return rc; - } - buf += ret; - size -= ret; - } - return 0; -} - -int write_fill(int fd, const void *buf, size_t size) -{ - while (size) { - ssize_t ret; - int rc; - - ret = write(fd, buf, size); - if (ret <= 0) { - if (ret == 0) - rc = -EIO; - else - rc = -errno; - err_e(rc, "failed to write_fill %zu bytes to fd %d", - size, fd); - return rc; - } - buf += ret; - size -= ret; - } - return 0; -} - -void ring_fill(struct ring_buf *ring, const void *buf, size_t size) -{ - size_t tail; - - assert(ring_space(ring) >= size); - - tail = (ring->head + ring->size - ring->bytes) % ring->size; - - if (ring->head >= tail) { - size_t todo = min(size, ring->size - ring->head); - - memcpy(ring->buf + ring->head, buf, todo); - ring->head = (ring->head + todo) % ring->size; - ring->bytes += todo; - buf += todo; - size -= todo; - } - - assert(ring->size - ring->head >= size); - memcpy(ring->buf + ring->head, buf, size); - ring->head += size; - ring->bytes += size; -} - -void *ring_data(struct ring_buf *ring, size_t *sizep) -{ - size_t tail; - - if (!ring->bytes) - return NULL; - - tail = (ring->head + ring->size - ring->bytes) % ring->size; - - *sizep = min(ring->bytes, ring->size - tail); - return ring->buf + tail; -} - -int ring_resize(struct ring_buf *ring, size_t new_size) -{ - struct ring_buf new_ring = { .size = new_size }; - void *p; - size_t size; - - if (ring_bytes(ring) > new_size) - return -ENOSPC; - - new_ring.buf = calloc(1, new_size); - if (new_size && !new_ring.buf) - return -ENOMEM; - - while ((p = ring_data(ring, &size))) { - ring_fill(&new_ring, p, size); - ring_consume(ring, size); - } - - free(ring->buf); - *ring = new_ring; - return 0; -} - -int ensure_sbuf_size(struct sized_buf *sbuf, size_t size) -{ - char *new_buf; - - if (sbuf->size >= size) - return 0; - - new_buf = realloc(sbuf->buf, size); - if (size && !new_buf) - return -ENOMEM; - - sbuf->buf = new_buf; - sbuf->size = size; - return 0; -} - -static unsigned long __ffs(unsigned long word) -{ - int num = 0; - - if (BITS_PER_LONG == 64) { - if ((word & 0xffffffff) == 0) { - num += 32; - word >>= 32; - } - } - - if ((word & 0xffff) == 0) { - num += 16; - word >>= 16; - } - if ((word & 0xff) == 0) { - num += 8; - word >>= 8; - } - if ((word & 0xf) == 0) { - num += 4; - word >>= 4; - } - if ((word & 0x3) == 0) { - num += 2; - word >>= 2; - } - if ((word & 0x1) == 0) - num += 1; - return num; -} - -#define ffz(x) __ffs(~(x)) - -unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, - unsigned long offset) -{ - const unsigned long *p = addr + BITOP_WORD(offset); - unsigned long result = offset & ~(BITS_PER_LONG-1); - unsigned long tmp; - - if (offset >= size) - return size; - size -= result; - offset %= BITS_PER_LONG; - if (offset) { - tmp = *(p++); - tmp |= ~0UL >> (BITS_PER_LONG - offset); - if (size < BITS_PER_LONG) - goto found_first; - if (~tmp) - goto found_middle; - size -= BITS_PER_LONG; - result += BITS_PER_LONG; - } - while (size & ~(BITS_PER_LONG-1)) { - if (~(tmp = *(p++))) - goto found_middle; - result += BITS_PER_LONG; - size -= BITS_PER_LONG; - } - if (!size) - return result; - tmp = *p; - -found_first: - tmp |= ~0UL << size; - if (tmp == ~0UL) /* Are any bits zero? */ - return result + size; /* Nope. */ -found_middle: - return result + ffz(tmp); -} - -void __set_bit(int nr, volatile unsigned long *addr) -{ - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); - - *p |= mask; -} - -void __clear_bit(int nr, volatile unsigned long *addr) -{ - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); - - *p &= ~mask; -} - -int get_proc_self_info(pid_t pid, pid_t *ppid_r, - char *cmd_buf, size_t cmd_buf_sz) - -{ - char path[64], buf[4096]; - int fd = -1; - char *cmd_start, *cmd_end, *ppid_start, *end; - ssize_t ret; - pid_t ppid; - int i, rc; - - snprintf(path, sizeof(path), "/proc/%ld/stat", (long)pid); - fd = open(path, O_RDONLY); - if (fd < 0) { - rc = -errno; - goto out; - } - - ret = read(fd, buf, sizeof(buf)); - if (ret < 0) - goto out; - if (ret == sizeof(buf)) { - rc = -EOVERFLOW; - goto out; - } - buf[ret] = '\0'; - - rc = -EINVAL; - cmd_start = strchr(buf, '('); - cmd_end = strrchr(buf, ')'); - if (!cmd_start || !cmd_end) - goto out; - cmd_start++; - - ppid_start = cmd_end; - for (i = 0; i < 3; i++) { - ppid_start = strchr(ppid_start, ' '); - if (!ppid_start) - goto out; - ppid_start++; - } - - ppid = strtoul(ppid_start, &end, 10); - if (end == ppid_start || *end != ' ') - goto out; - - if (ppid_r) - *ppid_r = ppid; - if (cmd_buf) { - size_t len = min_t(size_t, cmd_end - cmd_start, cmd_buf_sz - 1); - memcpy(cmd_buf, cmd_start, len); - cmd_buf[len] = '\0'; - } - - rc = 0; - out: - close(fd); - - return rc; -} diff --git a/src/mod/endpoints/mod_skypopen/osscuse/ossp-util.h b/src/mod/endpoints/mod_skypopen/osscuse/ossp-util.h deleted file mode 100644 index f48d02257a..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/ossp-util.h +++ /dev/null @@ -1,609 +0,0 @@ -/* - * ossp-util - OSS Proxy: Common utilities - * - * Copyright (C) 2008-2010 SUSE Linux Products GmbH - * Copyright (C) 2008-2010 Tejun Heo - * - * This file is released under the GPLv2. - */ - -#ifndef _OSSP_UTIL_H -#define _OSSP_UTIL_H - -#include -#include -#include -#include -#include -#include -#include "ossp.h" - -#define OSSP_LOG_NAME_LEN 128 - -enum { - OSSP_LOG_CRIT = 1, - OSSP_LOG_ERR, - OSSP_LOG_WARN, - OSSP_LOG_INFO, - OSSP_LOG_DFL = OSSP_LOG_INFO, /* default log level */ - OSSP_LOG_DBG0, - OSSP_LOG_DBG1, - OSSP_LOG_MAX = OSSP_LOG_DBG1, -}; - -extern char ossp_log_name[OSSP_LOG_NAME_LEN]; -extern int ossp_log_level; -extern int ossp_log_timestamp; - -#define BITS_PER_BYTE 8 -#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long)) -#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) -#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) - -/* ARRAY_SIZE and min/max macros stolen from linux/kernel.h */ -#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) - -#define min(x, y) ({ \ - typeof(x) _min1 = (x); \ - typeof(y) _min2 = (y); \ - (void) (&_min1 == &_min2); \ - _min1 < _min2 ? _min1 : _min2; }) - -#define max(x, y) ({ \ - typeof(x) _max1 = (x); \ - typeof(y) _max2 = (y); \ - (void) (&_max1 == &_max2); \ - _max1 > _max2 ? _max1 : _max2; }) - -#define min_t(type, x, y) ({ \ - type __min1 = (x); \ - type __min2 = (y); \ - __min1 < __min2 ? __min1: __min2; }) - -#define max_t(type, x, y) ({ \ - type __max1 = (x); \ - type __max2 = (y); \ - __max1 > __max2 ? __max1: __max2; }) - -void log_msg(int severity, const char *fmt, ...) - __attribute__ ((format (printf, 2, 3))); - -#define fatal(fmt, args...) do { \ - log_msg(OSSP_LOG_CRIT, fmt , ##args); \ - _exit(1); \ -} while (0) -#define err(fmt, args...) log_msg(OSSP_LOG_ERR, fmt , ##args) -#define warn(fmt, args...) log_msg(OSSP_LOG_WARN, fmt , ##args) -#define info(fmt, args...) log_msg(OSSP_LOG_INFO, fmt , ##args) -#define dbg0(fmt, args...) log_msg(OSSP_LOG_DBG0, fmt , ##args) -#define dbg1(fmt, args...) log_msg(OSSP_LOG_DBG1, fmt , ##args) - -#define fatal_e(e, fmt, args...) \ - fatal(fmt" (%s)" , ##args, strerror(-(e))) -#define err_e(e, fmt, args...) \ - err(fmt" (%s)" , ##args, strerror(-(e))) -#define warn_e(e, fmt, args...) \ - warn(fmt" (%s)" , ##args, strerror(-(e))) -#define info_e(e, fmt, args...) \ - info(fmt" (%s)" , ##args, strerror(-(e))) -#define dbg0_e(e, fmt, args...) \ - dbg0(fmt" (%s)" , ##args, strerror(-(e))) -#define dbg1_e(e, fmt, args...) \ - dbg1(fmt" (%s)" , ##args, strerror(-(e))) - -struct ring_buf { - char *buf; - size_t size; - size_t head; - size_t bytes; -}; - -static inline size_t ring_size(struct ring_buf *ring) -{ - return ring->size; -} - -static inline size_t ring_bytes(struct ring_buf *ring) -{ - return ring->bytes; -} - -static inline size_t ring_space(struct ring_buf *ring) -{ - return ring->size - ring->bytes; -} - -static inline void ring_consume(struct ring_buf *ring, size_t size) -{ - assert(ring->bytes >= size); - ring->bytes -= size; -} - -static inline void ring_manual_init(struct ring_buf *ring, void *buf, - size_t size, size_t head, size_t bytes) -{ - ring->buf = buf; - ring->size = size; - ring->head = head; - ring->bytes = bytes; -} - -void ring_fill(struct ring_buf *ring, const void *buf, size_t size); -void *ring_data(struct ring_buf *ring, size_t *sizep); -int ring_resize(struct ring_buf *ring, size_t new_size); - -struct sized_buf { - char *buf; - size_t size; -}; - -int ensure_sbuf_size(struct sized_buf *sbuf, size_t size); - -int read_fill(int fd, void *buf, size_t size); -int write_fill(int fd, const void *buf, size_t size); - -/* - * Bitops lifted from linux asm-generic implementation. - */ -unsigned long find_next_zero_bit(const unsigned long *addr, unsigned - long size, unsigned long offset); -#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0) -extern void __set_bit(int nr, volatile unsigned long *addr); -extern void __clear_bit(int nr, volatile unsigned long *addr); - -typedef ssize_t (*ossp_action_fn_t)(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, - int fd); - -int get_proc_self_info(pid_t tid, pid_t *pgrp, - char *cmd_buf, size_t cmd_buf_sz); - -/* - * Doubly linked list handling code shamelessly stolen from the Linux - * kernel 2.6.26 include/linux/list.h. - */ - -/** - * container_of - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - -#define LIST_POISON1 ((void *) 0x00100100) -#define LIST_POISON2 ((void *) 0x00200200) - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct list_head { - struct list_head *next, *prev; -}; - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -static inline void INIT_LIST_HEAD(struct list_head *list) -{ - list->next = list; - list->prev = list; -} - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static inline void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_del(struct list_head * prev, struct list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty() on entry does not return true after this, the entry is - * in an undefined state. - */ -static inline void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->next = LIST_POISON1; - entry->prev = LIST_POISON2; -} - -/** - * list_replace - replace old entry by new one - * @old : the element to be replaced - * @new : the new element to insert - * - * If @old was empty, it will be overwritten. - */ -static inline void list_replace(struct list_head *old, - struct list_head *new) -{ - new->next = old->next; - new->next->prev = new; - new->prev = old->prev; - new->prev->next = new; -} - -static inline void list_replace_init(struct list_head *old, - struct list_head *new) -{ - list_replace(old, new); - INIT_LIST_HEAD(old); -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static inline void list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -/** - * list_move - delete from one list and add as another's head - * @list: the entry to move - * @head: the head that will precede our entry - */ -static inline void list_move(struct list_head *list, struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add(list, head); -} - -/** - * list_move_tail - delete from one list and add as another's tail - * @list: the entry to move - * @head: the head that will follow our entry - */ -static inline void list_move_tail(struct list_head *list, - struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add_tail(list, head); -} - -/** - * list_is_last - tests whether @list is the last entry in list @head - * @list: the entry to test - * @head: the head of the list - */ -static inline int list_is_last(const struct list_head *list, - const struct list_head *head) -{ - return list->next == head; -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(const struct list_head *head) -{ - return head->next == head; -} - -/** - * list_empty_careful - tests whether a list is empty and not being modified - * @head: the list to test - * - * Description: - * tests whether a list is empty _and_ checks that no other CPU might be - * in the process of modifying either member (next or prev) - * - * NOTE: using list_empty_careful() without synchronization - * can only be safe if the only activity that can happen - * to the list entry is list_del_init(). Eg. it cannot be used - * if another CPU could re-list_add() it. - */ -static inline int list_empty_careful(const struct list_head *head) -{ - struct list_head *next = head->next; - return (next == head) && (next == head->prev); -} - -/** - * list_is_singular - tests whether a list has just one entry. - * @head: the list to test. - */ -static inline int list_is_singular(const struct list_head *head) -{ - return !list_empty(head) && (head->next == head->prev); -} - -static inline void __list_splice(const struct list_head *list, - struct list_head *head) -{ - struct list_head *first = list->next; - struct list_head *last = list->prev; - struct list_head *at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; -} - -/** - * list_splice - join two lists - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static inline void list_splice(const struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) - __list_splice(list, head); -} - -/** - * list_splice_init - join two lists and reinitialise the emptied list. - * @list: the new list to add. - * @head: the place to add it in the first list. - * - * The list at @list is reinitialised - */ -static inline void list_splice_init(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) { - __list_splice(list, head); - INIT_LIST_HEAD(list); - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * list_first_entry - get the first element from a list - * @ptr: the list head to take the element from. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - * - * Note, that list is expected to be not empty. - */ -#define list_first_entry(ptr, type, member) \ - list_entry((ptr)->next, type, member) - -/** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * list_for_each_prev - iterate over a list backwards - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - */ -#define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; pos != (head); pos = pos->prev) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -/** - * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_prev_safe(pos, n, head) \ - for (pos = (head)->prev, n = pos->prev; \ - pos != (head); pos = n, n = pos->prev) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_reverse - iterate backwards over list of given type. - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_reverse(pos, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() - * @pos: the type * to use as a start point - * @head: the head of the list - * @member: the name of the list_struct within the struct. - * - * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). - */ -#define list_prepare_entry(pos, head, member) \ - ((pos) ? : list_entry(head, typeof(*pos), member)) - -/** - * list_for_each_entry_continue - continue iteration over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Continue to iterate over list of given type, continuing after - * the current position. - */ -#define list_for_each_entry_continue(pos, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_continue_reverse - iterate backwards from the given point - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Start to iterate over list of given type backwards, continuing after - * the current position. - */ -#define list_for_each_entry_continue_reverse(pos, head, member) \ - for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_for_each_entry_from - iterate over list of given type from the current point - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type, continuing from current position. - */ -#define list_for_each_entry_from(pos, head, member) \ - for (; &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_continue - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type, continuing after current point, - * safe against removal of list entry. - */ -#define list_for_each_entry_safe_continue(pos, n, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_from - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type from current point, safe against - * removal of list entry. - */ -#define list_for_each_entry_safe_from(pos, n, head, member) \ - for (n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_reverse - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate backwards over list of given type, safe against removal - * of list entry. - */ -#define list_for_each_entry_safe_reverse(pos, n, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member), \ - n = list_entry(pos->member.prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.prev, typeof(*n), member)) - -#endif /*_OSSP_UTIL_H*/ diff --git a/src/mod/endpoints/mod_skypopen/osscuse/ossp.c b/src/mod/endpoints/mod_skypopen/osscuse/ossp.c deleted file mode 100644 index 96f98fa37a..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/ossp.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * ossp - OSS Proxy: emulate OSS device using CUSE - * - * Copyright (C) 2008-2010 SUSE Linux Products GmbH - * Copyright (C) 2008-2010 Tejun Heo - * - * This file is released under the GPLv2. - */ - -#include "ossp.h" - -const struct ossp_arg_size ossp_arg_sizes[OSSP_NR_OPCODES] = { - [OSSP_MIXER] = { sizeof(struct ossp_mixer_arg), - sizeof(struct ossp_mixer_arg), 0 }, - - [OSSP_DSP_OPEN] = { sizeof(struct ossp_dsp_open_arg), 0, 0 }, - [OSSP_DSP_READ] = { sizeof(struct ossp_dsp_rw_arg), 0, 0 }, - [OSSP_DSP_WRITE] = { sizeof(struct ossp_dsp_rw_arg), 0, 0 }, - [OSSP_DSP_POLL] = { sizeof(int), sizeof(unsigned), 0 }, - [OSSP_DSP_MMAP] = { sizeof(struct ossp_dsp_mmap_arg), 0, 0 }, - [OSSP_DSP_MUNMAP] = { sizeof(int), 0, 0 }, - - [OSSP_DSP_RESET] = { 0, 0, 0 }, - [OSSP_DSP_SYNC] = { 0, 0, 0 }, - [OSSP_DSP_POST] = { 0, 0, 0 }, - [OSSP_DSP_GET_RATE] = { 0, sizeof(int), 0 }, - [OSSP_DSP_GET_CHANNELS] = { 0, sizeof(int), 0 }, - [OSSP_DSP_GET_FORMAT] = { 0, sizeof(int), 0 }, - [OSSP_DSP_GET_BLKSIZE] = { 0, sizeof(int), 0 }, - [OSSP_DSP_GET_FORMATS] = { 0, sizeof(int), 0 }, - [OSSP_DSP_SET_RATE] = { sizeof(int), sizeof(int), 0 }, - [OSSP_DSP_SET_CHANNELS] = { sizeof(int), sizeof(int), 0 }, - [OSSP_DSP_SET_FORMAT] = { sizeof(int), sizeof(int), 0 }, - [OSSP_DSP_SET_SUBDIVISION] = { sizeof(int), sizeof(int), 0 }, - [OSSP_DSP_SET_FRAGMENT] = { sizeof(int), 0, 0 }, - [OSSP_DSP_GET_TRIGGER] = { 0, sizeof(int), 0 }, - [OSSP_DSP_SET_TRIGGER] = { sizeof(int), 0, 0 }, - [OSSP_DSP_GET_OSPACE] = { 0, sizeof(struct audio_buf_info), 0 }, - [OSSP_DSP_GET_ISPACE] = { 0, sizeof(struct audio_buf_info), 0 }, - [OSSP_DSP_GET_OPTR] = { 0, sizeof(struct count_info), 0 }, - [OSSP_DSP_GET_IPTR] = { 0, sizeof(struct count_info), 0 }, - [OSSP_DSP_GET_ODELAY] = { 0, sizeof(int), 0 }, -}; - -const char *ossp_cmd_str[OSSP_NR_OPCODES] = { - [OSSP_MIXER] = "MIXER", - - [OSSP_DSP_OPEN] = "OPEN", - [OSSP_DSP_READ] = "READ", - [OSSP_DSP_WRITE] = "WRITE", - [OSSP_DSP_POLL] = "POLL", - [OSSP_DSP_MMAP] = "MMAP", - [OSSP_DSP_MUNMAP] = "MUNMAP", - - [OSSP_DSP_RESET] = "RESET", - [OSSP_DSP_SYNC] = "SYNC", - [OSSP_DSP_POST] = "POST", - - [OSSP_DSP_GET_RATE] = "GET_RATE", - [OSSP_DSP_GET_CHANNELS] = "GET_CHANNELS", - [OSSP_DSP_GET_FORMAT] = "GET_FORMAT", - [OSSP_DSP_GET_BLKSIZE] = "GET_BLKSIZE", - [OSSP_DSP_GET_FORMATS] = "GET_FORMATS", - [OSSP_DSP_SET_RATE] = "SET_RATE", - [OSSP_DSP_SET_CHANNELS] = "SET_CHANNELS", - [OSSP_DSP_SET_FORMAT] = "SET_FORMAT", - [OSSP_DSP_SET_SUBDIVISION] = "SET_BUSDIVISION", - - [OSSP_DSP_SET_FRAGMENT] = "SET_FRAGMENT", - [OSSP_DSP_GET_TRIGGER] = "GET_TRIGGER", - [OSSP_DSP_SET_TRIGGER] = "SET_TRIGGER", - [OSSP_DSP_GET_OSPACE] = "GET_OSPACE", - [OSSP_DSP_GET_ISPACE] = "GET_ISPACE", - [OSSP_DSP_GET_OPTR] = "GET_OPTR", - [OSSP_DSP_GET_IPTR] = "GET_IPTR", - [OSSP_DSP_GET_ODELAY] = "GET_ODELAY", -}; - -const char *ossp_notify_str[OSSP_NR_NOTIFY_OPCODES] = { - [OSSP_NOTIFY_POLL] = "POLL", - [OSSP_NOTIFY_OBITUARY] = "OBITUARY", - [OSSP_NOTIFY_VOLCHG] = "VOLCHG", -}; diff --git a/src/mod/endpoints/mod_skypopen/osscuse/ossp.h b/src/mod/endpoints/mod_skypopen/osscuse/ossp.h deleted file mode 100644 index 9d03e63adf..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/ossp.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * ossp - OSS Proxy: emulate OSS device using CUSE - * - * Copyright (C) 2008-2010 SUSE Linux Products GmbH - * Copyright (C) 2008-2010 Tejun Heo - * - * This file is released under the GPLv2. - */ - -#ifndef _OSSP_H -#define _OSSP_H - -#include -#include -#include - -#define OSSP_VERSION "1.3.2" -#define OSSP_CMD_MAGIC 0xdeadbeef -#define OSSP_REPLY_MAGIC 0xbeefdead -#define OSSP_NOTIFY_MAGIC 0xbebebebe - -#define PLAY 0 -#define REC 1 -#define LEFT 0 -#define RIGHT 1 - -enum ossp_opcode { - OSSP_MIXER, - - OSSP_DSP_OPEN, - OSSP_DSP_READ, - OSSP_DSP_WRITE, - OSSP_DSP_POLL, - OSSP_DSP_MMAP, - OSSP_DSP_MUNMAP, - - OSSP_DSP_RESET, - OSSP_DSP_SYNC, - OSSP_DSP_POST, - - OSSP_DSP_GET_RATE, - OSSP_DSP_GET_CHANNELS, - OSSP_DSP_GET_FORMAT, - OSSP_DSP_GET_BLKSIZE, - OSSP_DSP_GET_FORMATS, - OSSP_DSP_SET_RATE, - OSSP_DSP_SET_CHANNELS, - OSSP_DSP_SET_FORMAT, - OSSP_DSP_SET_SUBDIVISION, - - OSSP_DSP_SET_FRAGMENT, - OSSP_DSP_GET_TRIGGER, - OSSP_DSP_SET_TRIGGER, - OSSP_DSP_GET_OSPACE, - OSSP_DSP_GET_ISPACE, - OSSP_DSP_GET_OPTR, - OSSP_DSP_GET_IPTR, - OSSP_DSP_GET_ODELAY, - - OSSP_NR_OPCODES, -}; - -enum ossp_notify_opcode { - OSSP_NOTIFY_POLL, - OSSP_NOTIFY_OBITUARY, - OSSP_NOTIFY_VOLCHG, - - OSSP_NR_NOTIFY_OPCODES, -}; - -struct ossp_mixer_arg { - int vol[2][2]; -}; - -struct ossp_dsp_open_arg { - int flags; - pid_t opener_pid; -}; - -struct ossp_dsp_rw_arg { - unsigned nonblock:1; -}; - -struct ossp_dsp_mmap_arg { - int dir; - size_t size; -}; - -struct ossp_cmd { - unsigned magic; - enum ossp_opcode opcode; - size_t din_size; - size_t dout_size; -}; - -struct ossp_reply { - unsigned magic; - int result; - size_t dout_size; /* <= cmd.data_in_size */ -}; - -struct ossp_notify { - unsigned magic; - enum ossp_notify_opcode opcode; -}; - -struct ossp_arg_size { - ssize_t carg_size; - ssize_t rarg_size; - unsigned has_fd:1; -}; - -extern const struct ossp_arg_size ossp_arg_sizes[OSSP_NR_OPCODES]; -extern const char *ossp_cmd_str[OSSP_NR_OPCODES]; -extern const char *ossp_notify_str[OSSP_NR_NOTIFY_OPCODES]; - -#endif /* _OSSP_H */ diff --git a/src/mod/endpoints/mod_skypopen/osscuse/osspd.c b/src/mod/endpoints/mod_skypopen/osscuse/osspd.c deleted file mode 100644 index dc9f36a09b..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/osspd.c +++ /dev/null @@ -1,2374 +0,0 @@ -/* - * osspd - OSS Proxy Daemon: emulate OSS device using CUSE - * - * Copyright (C) 2008-2010 SUSE Linux Products GmbH - * Copyright (C) 2008-2010 Tejun Heo - * - * This file is released under the GPLv2. - */ -#undef GIOVANNI - -#define FUSE_USE_VERSION 28 -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ossp.h" -#include "ossp-util.h" - -/* - * MMAP support needs to be updated to the new fuse MMAP API. Disable - * it for the time being. - */ -#warning mmap support disabled for now -/* #define OSSP_MMAP */ - -#define DFL_MIXER_NAME "mixer" -#define DFL_DSP_NAME "dsp" -#define DFL_ADSP_NAME "adsp" -#define STRFMT "S[%u/%d]" -#define STRID(os) os->id, os->pid - -#define dbg1_os(os, fmt, args...) dbg1(STRFMT" "fmt, STRID(os) , ##args) -#define dbg0_os(os, fmt, args...) dbg0(STRFMT" "fmt, STRID(os) , ##args) -#define warn_os(os, fmt, args...) warn(STRFMT" "fmt, STRID(os) , ##args) -#define err_os(os, fmt, args...) err(STRFMT" "fmt, STRID(os) , ##args) -#define warn_ose(os, err, fmt, args...) \ - warn_e(err, STRFMT" "fmt, STRID(os) , ##args) -#define err_ose(os, err, fmt, args...) \ - err_e(err, STRFMT" "fmt, STRID(os) , ##args) - -enum { - SNDRV_OSS_VERSION = ((3<<16)|(8<<8)|(1<<4)|(0)), /* 3.8.1a */ - DFL_MIXER_MAJOR = 14, - DFL_MIXER_MINOR = 0, - DFL_DSP_MAJOR = 14, - DFL_DSP_MINOR = 3, - DFL_ADSP_MAJOR = 14, - DFL_ADSP_MINOR = 12, - DFL_MAX_STREAMS = 128, - MIXER_PUT_DELAY = 600, /* 10 mins */ - /* DSPS_MMAP_SIZE / 2 must be multiple of SHMLBA */ - DSPS_MMAP_SIZE = 2 * (512 << 10), /* 512k for each dir */ -}; - -struct ossp_uid_cnt { - struct list_head link; - uid_t uid; - unsigned nr_os; -}; - -struct ossp_mixer { - pid_t pgrp; - struct list_head link; - struct list_head delayed_put_link; - unsigned refcnt; - /* the following two fields are protected by mixer_mutex */ - int vol[2][2]; - int modify_counter; - time_t put_expires; -}; - -struct ossp_mixer_cmd { - struct ossp_mixer *mixer; - struct ossp_mixer_arg set; - int out_dir; - int rvol; -}; - -#define for_each_vol(i, j) \ - for (i = 0, j = 0; i < 2; j += i << 1, j++, i = j >> 1, j &= 1) - -struct ossp_stream { - unsigned id; /* stream ID */ - struct list_head link; - struct list_head pgrp_link; - struct list_head notify_link; - unsigned refcnt; - pthread_mutex_t cmd_mutex; - pthread_mutex_t mmap_mutex; - struct fuse_pollhandle *ph; - - /* stream owner info */ - pid_t pid; - pid_t pgrp; - uid_t uid; - gid_t gid; - - /* slave info */ - pid_t slave_pid; - int cmd_fd; - int notify_tx; - int notify_rx; - - /* the following dead flag is set asynchronously, keep it separate. */ - int dead; - - /* stream mixer state, protected by mixer_mutex */ - int mixer_pending; - int vol[2][2]; - int vol_set[2][2]; - - off_t mmap_off; - size_t mmap_size; - - struct ossp_uid_cnt *ucnt; - struct fuse_session *se; /* associated fuse session */ - struct ossp_mixer *mixer; -}; - -struct ossp_dsp_stream { - struct ossp_stream os; - unsigned rw; - unsigned mmapped; - int nonblock; -}; - -#define os_to_dsps(_os) container_of(_os, struct ossp_dsp_stream, os) - -static unsigned max_streams; -static unsigned umax_streams; -static unsigned hashtbl_size; -static char dsp_slave_path[PATH_MAX]; - -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t mixer_mutex = PTHREAD_MUTEX_INITIALIZER; -static unsigned long *os_id_bitmap; -static unsigned nr_mixers; -static struct list_head *mixer_tbl; /* indexed by PGRP */ -static struct list_head *os_tbl; /* indexed by ID */ -static struct list_head *os_pgrp_tbl; /* indexed by PGRP */ -static struct list_head *os_notify_tbl; /* indexed by notify fd */ -static LIST_HEAD(uid_cnt_list); -static int notify_epfd; /* epoll used to monitor notify fds */ -static pthread_t notify_poller_thread; -static pthread_t slave_reaper_thread; -static pthread_t mixer_delayed_put_thread; -static pthread_t cuse_mixer_thread; -static pthread_t cuse_adsp_thread; -static pthread_cond_t notify_poller_kill_wait = PTHREAD_COND_INITIALIZER; -static pthread_cond_t slave_reaper_wait = PTHREAD_COND_INITIALIZER; -static LIST_HEAD(slave_corpse_list); -static LIST_HEAD(mixer_delayed_put_head); /* delayed reference */ -static pthread_cond_t mixer_delayed_put_cond = PTHREAD_COND_INITIALIZER; - -static int init_wait_fd = -1; -static int exit_on_idle; -static struct fuse_session *mixer_se; -static struct fuse_session *dsp_se; -static struct fuse_session *adsp_se; - -static void put_os(struct ossp_stream *os); - - -/*************************************************************************** - * Accessors - */ - -static struct list_head *mixer_tbl_head(pid_t pid) -{ - return &mixer_tbl[pid % hashtbl_size]; -} - -static struct list_head *os_tbl_head(uint64_t id) -{ - return &os_tbl[id % hashtbl_size]; -} - -static struct list_head *os_pgrp_tbl_head(pid_t pgrp) -{ - return &os_pgrp_tbl[pgrp % hashtbl_size]; -} - -static struct list_head *os_notify_tbl_head(int notify_rx) -{ - return &os_notify_tbl[notify_rx % hashtbl_size]; -} - -static struct ossp_mixer *find_mixer_locked(pid_t pgrp) -{ - struct ossp_mixer *mixer; - - list_for_each_entry(mixer, mixer_tbl_head(pgrp), link) - if (mixer->pgrp == pgrp) - return mixer; - return NULL; -} - -static struct ossp_mixer *find_mixer(pid_t pgrp) -{ - struct ossp_mixer *mixer; - - pthread_mutex_lock(&mutex); - mixer = find_mixer_locked(pgrp); - pthread_mutex_unlock(&mutex); - return mixer; -} - -static struct ossp_stream *find_os(unsigned id) -{ - struct ossp_stream *os, *found = NULL; - - pthread_mutex_lock(&mutex); - list_for_each_entry(os, os_tbl_head(id), link) - if (os->id == id) { - found = os; - break; - } - pthread_mutex_unlock(&mutex); - return found; -} - -static struct ossp_stream *find_os_by_notify_rx(int notify_rx) -{ - struct ossp_stream *os, *found = NULL; - - pthread_mutex_lock(&mutex); - list_for_each_entry(os, os_notify_tbl_head(notify_rx), notify_link) - if (os->notify_rx == notify_rx) { - found = os; - break; - } - pthread_mutex_unlock(&mutex); - return found; -} - - -/*************************************************************************** - * Command and ioctl helpers - */ - -static ssize_t exec_cmd_intern(struct ossp_stream *os, enum ossp_opcode opcode, - const void *carg, size_t carg_size, const void *din, size_t din_size, - void *rarg, size_t rarg_size, void *dout, size_t *dout_sizep, int fd) -{ - size_t dout_size = dout_sizep ? *dout_sizep : 0; - struct ossp_cmd cmd = { .magic = OSSP_CMD_MAGIC, .opcode = opcode, - .din_size = din_size, - .dout_size = dout_size }; - struct iovec iov = { &cmd, sizeof(cmd) }; - struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1 }; - struct ossp_reply reply = { }; - char cmsg_buf[CMSG_SPACE(sizeof(fd))]; - char reason[512]; - int rc; - - if (os->dead) - return -EIO; - - //dbg1_os(os, "opcode %s=%d carg=%zu din=%zu rarg=%zu dout=%zu", - //ossp_cmd_str[opcode], opcode, carg_size, din_size, rarg_size, - //dout_size); -#ifndef GIOVANNI -memset(dout, 255, dout_size); -memset(din, 255, din_size); - -#define GIOVA_BLK 3840 -#define GIOVA_SLEEP 40000 -switch(opcode){ - - case 1: //OPEN - reply.result = 0; - break; - case 2: //READ - usleep((GIOVA_SLEEP/GIOVA_BLK)* *dout_sizep); - reply.result = *dout_sizep; - break; - case 3: //WRITE - usleep((GIOVA_SLEEP/GIOVA_BLK)* din_size); - reply.result = din_size; - break; - case 9: //POST - reply.result = -32; - break; - case 13: //GET_BLKSIZE - reply.result = 0; - *(int *)rarg = GIOVA_BLK; - break; - case 14: //GET_FORMATS - reply.result = 0; - *(int *)rarg = 28731; - break; - case 15: //SET_RATE - reply.result = 0; - *(int *)rarg = *(int *) carg; - break; - case 16: //SET_CHANNELS - reply.result = 0; - *(int *)rarg = *(int *) carg; - break; - case 17: //SET_FORMAT - reply.result = 0; - *(int *)rarg = *(int *) carg; - break; - case 19: //SET_FRAGMENT - reply.result = 0; - break; - default: - reply.result = 0; - break; -} -#endif // GIOVANNI - -#ifdef GIOVANNI - if (fd >= 0) { - struct cmsghdr *cmsg; - - msg.msg_control = cmsg_buf; - msg.msg_controllen = sizeof(cmsg_buf); - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); - *(int *)CMSG_DATA(cmsg) = fd; - msg.msg_controllen = cmsg->cmsg_len; - } - - if (sendmsg(os->cmd_fd, &msg, 0) <= 0) { - rc = -errno; - snprintf(reason, sizeof(reason), "command sendmsg failed: %s", - strerror(-rc)); - goto fail; - } - - if ((rc = write_fill(os->cmd_fd, carg, carg_size)) < 0 || - (rc = write_fill(os->cmd_fd, din, din_size)) < 0) { - snprintf(reason, sizeof(reason), - "can't tranfer command argument and/or data: %s", - strerror(-rc)); - goto fail; - } - if ((rc = read_fill(os->cmd_fd, &reply, sizeof(reply))) < 0) { - snprintf(reason, sizeof(reason), "can't read reply: %s", - strerror(-rc)); - goto fail; - } - - if (reply.magic != OSSP_REPLY_MAGIC) { - snprintf(reason, sizeof(reason), - "reply magic mismatch %x != %x", - reply.magic, OSSP_REPLY_MAGIC); - rc = -EINVAL; - goto fail; - } - - if (reply.result < 0) - goto out_unlock; - - if (reply.dout_size > dout_size) { - snprintf(reason, sizeof(reason), - "data out size overflow %zu > %zu", - reply.dout_size, dout_size); - rc = -EINVAL; - goto fail; - } - - dout_size = reply.dout_size; - if (dout_sizep) - *dout_sizep = dout_size; - - if ((rc = read_fill(os->cmd_fd, rarg, rarg_size)) < 0 || - (rc = read_fill(os->cmd_fd, dout, dout_size)) < 0) { - snprintf(reason, sizeof(reason), "can't read data out: %s", - strerror(-rc)); - goto fail; - } - -#endif // GIOVANNI - -out_unlock: - //dbg1_os(os, " completed, result=%d dout=%zu", - //reply.result, dout_size); - -//if(rarg) - //dbg1_os(os, " 2 %s=%d completed, result=%d dout=%zu carg=%d rarg=%d", ossp_cmd_str[opcode], opcode, - //reply.result, dout_size, carg ? *(int *) carg : 666, *(int *)rarg); - return reply.result; - -fail: - warn_os(os, "communication with slave failed (%s)", reason); - os->dead = 1; - return rc; -} - -static ssize_t exec_cmd(struct ossp_stream *os, enum ossp_opcode opcode, - const void *carg, size_t carg_size, const void *din, size_t din_size, - void *rarg, size_t rarg_size, void *dout, size_t *dout_sizep, int fd) -{ - int is_mixer; - int i, j; - ssize_t ret, mret; - - /* mixer command is handled exlicitly below */ - is_mixer = opcode == OSSP_MIXER; - if (is_mixer) { - ret = -pthread_mutex_trylock(&os->cmd_mutex); - if (ret) - return ret; - } else { - pthread_mutex_lock(&os->cmd_mutex); - - ret = exec_cmd_intern(os, opcode, carg, carg_size, - din, din_size, rarg, rarg_size, - dout, dout_sizep, fd); - } - - /* lazy mixer handling */ - pthread_mutex_lock(&mixer_mutex); - - if (os->mixer_pending) { - struct ossp_mixer_arg marg; - repeat_mixer: - /* we have mixer command pending */ - memcpy(marg.vol, os->vol_set, sizeof(os->vol_set)); - memset(os->vol_set, -1, sizeof(os->vol_set)); - - pthread_mutex_unlock(&mixer_mutex); - mret = exec_cmd_intern(os, OSSP_MIXER, &marg, sizeof(marg), - NULL, 0, &marg, sizeof(marg), NULL, NULL, - -1); - pthread_mutex_lock(&mixer_mutex); - - /* was there mixer set request while executing mixer command? */ - for_each_vol(i, j) - if (os->vol_set[i][j] >= 0) - goto repeat_mixer; - - /* update internal mixer state */ - if (mret == 0) { - for_each_vol(i, j) { - if (marg.vol[i][j] >= 0) { - if (os->vol[i][j] != marg.vol[i][j]) - os->mixer->modify_counter++; - os->vol[i][j] = marg.vol[i][j]; - } - } - } - os->mixer_pending = 0; - } - - pthread_mutex_unlock(&os->cmd_mutex); - - /* - * mixer mutex must be released after cmd_mutex so that - * exec_mixer_cmd() can guarantee that mixer_pending flags - * will be handled immediately or when the currently - * in-progress command completes. - */ - pthread_mutex_unlock(&mixer_mutex); - - return is_mixer ? mret : ret; -} - -static ssize_t exec_simple_cmd(struct ossp_stream *os, - enum ossp_opcode opcode, void *carg, void *rarg) -{ - return exec_cmd(os, opcode, - carg, ossp_arg_sizes[opcode].carg_size, NULL, 0, - rarg, ossp_arg_sizes[opcode].rarg_size, NULL, NULL, -1); -} - -static int ioctl_prep_uarg(fuse_req_t req, void *in, size_t in_sz, void *out, - size_t out_sz, void *uarg, const void *in_buf, - size_t in_bufsz, size_t out_bufsz) -{ - struct iovec in_iov = { }, out_iov = { }; - int retry = 0; - - if (in) { - if (!in_bufsz) { - in_iov.iov_base = uarg; - in_iov.iov_len = in_sz; - retry = 1; - } else { - assert(in_bufsz == in_sz); - memcpy(in, in_buf, in_sz); - } - } - - if (out) { - if (!out_bufsz) { - out_iov.iov_base = uarg; - out_iov.iov_len = out_sz; - retry = 1; - } else - assert(out_bufsz == out_sz); - } - - if (retry) - fuse_reply_ioctl_retry(req, &in_iov, 1, &out_iov, 1); - - return retry; -} - -#define PREP_UARG(inp, outp) do { \ - if (ioctl_prep_uarg(req, (inp), sizeof(*(inp)), \ - (outp), sizeof(*(outp)), uarg, \ - in_buf, in_bufsz, out_bufsz)) \ - return; \ -} while (0) - -#define IOCTL_RETURN(result, outp) do { \ - if ((outp) != NULL) \ - fuse_reply_ioctl(req, result, (outp), sizeof(*(outp))); \ - else \ - fuse_reply_ioctl(req, result, NULL, 0); \ - return; \ -} while (0) - - -/*************************************************************************** - * Mixer implementation - */ - -static void put_mixer_real(struct ossp_mixer *mixer) -{ - if (!--mixer->refcnt) { - dbg0("DESTROY mixer(%d)", mixer->pgrp); - list_del_init(&mixer->link); - list_del_init(&mixer->delayed_put_link); - free(mixer); - nr_mixers--; - - /* - * If exit_on_idle, mixer for pgrp0 is touched during - * init and each stream has mixer attached. As mixers - * are destroyed after they have been idle for - * MIXER_PUT_DELAY seconds, we can use it for idle - * detection. Note that this might race with - * concurrent open. The race is inherent. - */ - if (exit_on_idle && !nr_mixers) { - info("idle, exiting"); - exit(0); - } - } -} - -static struct ossp_mixer *get_mixer(pid_t pgrp) -{ - struct ossp_mixer *mixer; - - pthread_mutex_lock(&mutex); - - /* is there a matching one? */ - mixer = find_mixer_locked(pgrp); - if (mixer) { - if (list_empty(&mixer->delayed_put_link)) - mixer->refcnt++; - else - list_del_init(&mixer->delayed_put_link); - goto out_unlock; - } - - /* reap delayed put list if there are too many mixers */ - while (nr_mixers > 2 * max_streams && - !list_empty(&mixer_delayed_put_head)) { - struct ossp_mixer *mixer = - list_first_entry(&mixer_delayed_put_head, - struct ossp_mixer, delayed_put_link); - - assert(mixer->refcnt == 1); - put_mixer_real(mixer); - } - - /* create a new one */ - mixer = calloc(1, sizeof(*mixer)); - if (!mixer) { - warn("failed to allocate mixer for %d", pgrp); - mixer = NULL; - goto out_unlock; - } - - mixer->pgrp = pgrp; - INIT_LIST_HEAD(&mixer->link); - INIT_LIST_HEAD(&mixer->delayed_put_link); - mixer->refcnt = 1; - memset(mixer->vol, -1, sizeof(mixer->vol)); - - list_add(&mixer->link, mixer_tbl_head(pgrp)); - nr_mixers++; - dbg0("CREATE mixer(%d)", pgrp); - -out_unlock: - pthread_mutex_unlock(&mutex); - return mixer; -} - -static void put_mixer(struct ossp_mixer *mixer) -{ - pthread_mutex_lock(&mutex); - - if (mixer) { - if (mixer->refcnt == 1) { - struct timespec ts; - - clock_gettime(CLOCK_REALTIME, &ts); - mixer->put_expires = ts.tv_sec + MIXER_PUT_DELAY; - list_add_tail(&mixer->delayed_put_link, - &mixer_delayed_put_head); - pthread_cond_signal(&mixer_delayed_put_cond); - } else - put_mixer_real(mixer); - } - - pthread_mutex_unlock(&mutex); -} - -static void *mixer_delayed_put_worker(void *arg) -{ - struct ossp_mixer *mixer; - struct timespec ts; - time_t now; - - pthread_mutex_lock(&mutex); -again: - clock_gettime(CLOCK_REALTIME, &ts); - now = ts.tv_sec; - - mixer = NULL; - while (!list_empty(&mixer_delayed_put_head)) { - mixer = list_first_entry(&mixer_delayed_put_head, - struct ossp_mixer, delayed_put_link); - - if (now <= mixer->put_expires) - break; - - assert(mixer->refcnt == 1); - put_mixer_real(mixer); - mixer = NULL; - } - - if (mixer) { - ts.tv_sec = mixer->put_expires + 1; - pthread_cond_timedwait(&mixer_delayed_put_cond, &mutex, &ts); - } else - pthread_cond_wait(&mixer_delayed_put_cond, &mutex); - - goto again; -} - -static void init_mixer_cmd(struct ossp_mixer_cmd *mxcmd, - struct ossp_mixer *mixer) -{ - memset(mxcmd, 0, sizeof(*mxcmd)); - memset(&mxcmd->set.vol, -1, sizeof(mxcmd->set.vol)); - mxcmd->mixer = mixer; - mxcmd->out_dir = -1; -} - -static int exec_mixer_cmd(struct ossp_mixer_cmd *mxcmd, struct ossp_stream *os) -{ - int i, j, rc; - - /* - * Set pending flags before trying to execute mixer command. - * Combined with lock release order in exec_cmd(), this - * guarantees that the mixer command will be executed - * immediately or when the current command completes. - */ - pthread_mutex_lock(&mixer_mutex); - os->mixer_pending = 1; - for_each_vol(i, j) - if (mxcmd->set.vol[i][j] >= 0) - os->vol_set[i][j] = mxcmd->set.vol[i][j]; - pthread_mutex_unlock(&mixer_mutex); - - rc = exec_simple_cmd(os, OSSP_MIXER, NULL, NULL); - if (rc >= 0) { - dbg0_os(os, "volume set=%d/%d:%d/%d get=%d/%d:%d/%d", - mxcmd->set.vol[PLAY][LEFT], mxcmd->set.vol[PLAY][RIGHT], - mxcmd->set.vol[REC][LEFT], mxcmd->set.vol[REC][RIGHT], - os->vol[PLAY][LEFT], os->vol[PLAY][RIGHT], - os->vol[REC][LEFT], os->vol[REC][RIGHT]); - } else if (rc != -EBUSY) - warn_ose(os, rc, "mixer command failed"); - - return rc; -} - -static void finish_mixer_cmd(struct ossp_mixer_cmd *mxcmd) -{ - struct ossp_mixer *mixer = mxcmd->mixer; - struct ossp_stream *os; - int dir = mxcmd->out_dir; - int vol[2][2] = { }; - int cnt[2][2] = { }; - int i, j; - - pthread_mutex_lock(&mixer_mutex); - - /* get volume of all streams attached to this mixer */ - pthread_mutex_lock(&mutex); - list_for_each_entry(os, os_pgrp_tbl_head(mixer->pgrp), pgrp_link) { - if (os->pgrp != mixer->pgrp) - continue; - for_each_vol(i, j) { - if (os->vol[i][j] < 0) - continue; - vol[i][j] += os->vol[i][j]; - cnt[i][j]++; - } - } - pthread_mutex_unlock(&mutex); - - /* calculate the summary volume values */ - for_each_vol(i, j) { - if (mxcmd->set.vol[i][j] >= 0) - vol[i][j] = mxcmd->set.vol[i][j]; - else if (cnt[i][j]) - vol[i][j] = vol[i][j] / cnt[i][j]; - else if (mixer->vol[i][j] >= 0) - vol[i][j] = mixer->vol[i][j]; - else - vol[i][j] = 100; - - vol[i][j] = min(max(0, vol[i][j]), 100); - } - - if (dir >= 0) - mxcmd->rvol = vol[dir][LEFT] | (vol[dir][RIGHT] << 8); - - pthread_mutex_unlock(&mixer_mutex); -} - -static void mixer_simple_ioctl(fuse_req_t req, struct ossp_mixer *mixer, - unsigned cmd, void *uarg, const void *in_buf, - size_t in_bufsz, size_t out_bufsz, - int *not_minep) -{ - const char *id = "OSS Proxy", *name = "Mixer"; - int i; - - switch (cmd) { - case SOUND_MIXER_INFO: { - struct mixer_info info = { }; - - PREP_UARG(NULL, &info); - strncpy(info.id, id, sizeof(info.id) - 1); - strncpy(info.name, name, sizeof(info.name) - 1); - info.modify_counter = mixer->modify_counter; - IOCTL_RETURN(0, &info); - } - - case SOUND_OLD_MIXER_INFO: { - struct _old_mixer_info info = { }; - - PREP_UARG(NULL, &info); - strncpy(info.id, id, sizeof(info.id) - 1); - strncpy(info.name, name, sizeof(info.name) - 1); - IOCTL_RETURN(0, &info); - } - - case OSS_GETVERSION: - i = SNDRV_OSS_VERSION; - goto puti; - case SOUND_MIXER_READ_DEVMASK: - case SOUND_MIXER_READ_STEREODEVS: - i = SOUND_MASK_PCM | SOUND_MASK_IGAIN; - goto puti; - case SOUND_MIXER_READ_CAPS: - i = SOUND_CAP_EXCL_INPUT; - goto puti; - case SOUND_MIXER_READ_RECMASK: - case SOUND_MIXER_READ_RECSRC: - i = SOUND_MASK_IGAIN; - goto puti; - puti: - PREP_UARG(NULL, &i); - IOCTL_RETURN(0, &i); - - case SOUND_MIXER_WRITE_RECSRC: - IOCTL_RETURN(0, NULL); - - default: - *not_minep = 1; - return; - } - assert(0); -} - -static void mixer_do_ioctl(fuse_req_t req, struct ossp_mixer *mixer, - unsigned cmd, void *uarg, const void *in_buf, - size_t in_bufsz, size_t out_bufsz) -{ - struct ossp_mixer_cmd mxcmd; - struct ossp_stream *os, **osa; - int not_mine = 0; - int slot = cmd & 0xff, dir; - int nr_os; - int i, rc; - - mixer_simple_ioctl(req, mixer, cmd, uarg, in_buf, in_bufsz, out_bufsz, - ¬_mine); - if (!not_mine) - return; - - rc = -ENXIO; - if (!(cmd & (SIOC_IN | SIOC_OUT))) - goto err; - - /* - * Okay, it's not one of the easy ones. Build mxcmd for - * actual volume control. - */ - if (cmd & SIOC_IN) - PREP_UARG(&i, &i); - else - PREP_UARG(NULL, &i); - - switch (slot) { - case SOUND_MIXER_PCM: - dir = PLAY; - break; - case SOUND_MIXER_IGAIN: - dir = REC; - break; - default: - i = 0; - IOCTL_RETURN(0, &i); - } - - init_mixer_cmd(&mxcmd, mixer); - - if (cmd & SIOC_IN) { - unsigned l, r; - - rc = -EINVAL; - l = i & 0xff; - r = (i >> 8) & 0xff; - if (l > 100 || r > 100) - goto err; - - mixer->vol[dir][LEFT] = mxcmd.set.vol[dir][LEFT] = l; - mixer->vol[dir][RIGHT] = mxcmd.set.vol[dir][RIGHT] = r; - } - mxcmd.out_dir = dir; - - /* - * Apply volume conrol - */ - /* acquire target streams */ - pthread_mutex_lock(&mutex); - osa = calloc(max_streams, sizeof(osa[0])); - if (!osa) { - pthread_mutex_unlock(&mutex); - rc = -ENOMEM; - goto err; - } - - nr_os = 0; - list_for_each_entry(os, os_pgrp_tbl_head(mixer->pgrp), pgrp_link) { - if (os->pgrp == mixer->pgrp) { - osa[nr_os++] = os; - os->refcnt++; - } - } - - pthread_mutex_unlock(&mutex); - - /* execute mxcmd for each stream and put it */ - for (i = 0; i < nr_os; i++) { - exec_mixer_cmd(&mxcmd, osa[i]); - put_os(osa[i]); - } - - finish_mixer_cmd(&mxcmd); - free(osa); - - IOCTL_RETURN(0, out_bufsz ? &mxcmd.rvol : NULL); - -err: - fuse_reply_err(req, -rc); -} - -static void mixer_open(fuse_req_t req, struct fuse_file_info *fi) -{ - pid_t pid = fuse_req_ctx(req)->pid, pgrp; - struct ossp_mixer *mixer; - int rc; - - rc = get_proc_self_info(pid, &pgrp, NULL, 0); - if (rc) { - err_e(rc, "get_proc_self_info(%d) failed", pid); - fuse_reply_err(req, -rc); - return; - } - - mixer = get_mixer(pgrp); - fi->fh = pgrp; - - if (mixer) - fuse_reply_open(req, fi); - else - fuse_reply_err(req, ENOMEM); -} - -static void mixer_ioctl(fuse_req_t req, int signed_cmd, void *uarg, - struct fuse_file_info *fi, unsigned int flags, - const void *in_buf, size_t in_bufsz, size_t out_bufsz) -{ - struct ossp_mixer *mixer; - - mixer = find_mixer(fi->fh); - if (!mixer) { - fuse_reply_err(req, EBADF); - return; - } - - mixer_do_ioctl(req, mixer, signed_cmd, uarg, in_buf, in_bufsz, - out_bufsz); -} - -static void mixer_release(fuse_req_t req, struct fuse_file_info *fi) -{ - struct ossp_mixer *mixer; - - mixer = find_mixer(fi->fh); - if (mixer) { - put_mixer(mixer); - fuse_reply_err(req, 0); - } else - fuse_reply_err(req, EBADF); -} - - -/*************************************************************************** - * Stream implementation - */ - -static int alloc_os(size_t stream_size, size_t mmap_size, pid_t pid, uid_t pgrp, - uid_t uid, gid_t gid, int cmd_sock, - const int *notify, struct fuse_session *se, - struct ossp_stream **osp) -{ - struct ossp_uid_cnt *tmp_ucnt, *ucnt = NULL; - struct ossp_stream *os; - int rc; - - assert(stream_size >= sizeof(struct ossp_stream)); - os = calloc(1, stream_size); - if (!os) - return -ENOMEM; - - INIT_LIST_HEAD(&os->link); - INIT_LIST_HEAD(&os->pgrp_link); - INIT_LIST_HEAD(&os->notify_link); - os->refcnt = 1; - - rc = -pthread_mutex_init(&os->cmd_mutex, NULL); - if (rc) - goto err_free; - - rc = -pthread_mutex_init(&os->mmap_mutex, NULL); - if (rc) - goto err_destroy_cmd_mutex; - - pthread_mutex_lock(&mutex); - - list_for_each_entry(tmp_ucnt, &uid_cnt_list, link) - if (tmp_ucnt->uid == uid) { - ucnt = tmp_ucnt; - break; - } - if (!ucnt) { - rc = -ENOMEM; - ucnt = calloc(1, sizeof(*ucnt)); - if (!ucnt) - goto err_unlock; - ucnt->uid = uid; - list_add(&ucnt->link, &uid_cnt_list); - } - - rc = -EBUSY; - if (ucnt->nr_os + 1 > umax_streams) - goto err_unlock; - - /* everything looks fine, allocate id and init stream */ - rc = -EBUSY; - os->id = find_next_zero_bit(os_id_bitmap, max_streams, 0); - if (os->id >= max_streams) - goto err_unlock; - __set_bit(os->id, os_id_bitmap); - - os->cmd_fd = cmd_sock; - os->notify_tx = notify[1]; - os->notify_rx = notify[0]; - os->pid = pid; - os->pgrp = pgrp; - os->uid = uid; - os->gid = gid; - if (mmap_size) { - os->mmap_off = os->id * mmap_size; - os->mmap_size = mmap_size; - } - os->ucnt = ucnt; - os->se = se; - - memset(os->vol, -1, sizeof(os->vol)); - memset(os->vol_set, -1, sizeof(os->vol)); - - list_add(&os->link, os_tbl_head(os->id)); - list_add(&os->pgrp_link, os_pgrp_tbl_head(os->pgrp)); - - ucnt->nr_os++; - *osp = os; - pthread_mutex_unlock(&mutex); - return 0; - -err_unlock: - pthread_mutex_unlock(&mutex); - pthread_mutex_destroy(&os->mmap_mutex); -err_destroy_cmd_mutex: - pthread_mutex_destroy(&os->cmd_mutex); -err_free: - free(os); - return rc; -} - -static void shutdown_notification(struct ossp_stream *os) -{ - struct ossp_notify obituary = { .magic = OSSP_NOTIFY_MAGIC, - .opcode = OSSP_NOTIFY_OBITUARY }; - ssize_t ret; - - /* - * Shutdown notification for this stream. We politely ask - * notify_poller to shut the receive side down to avoid racing - * with it. - */ - while (os->notify_rx >= 0) { - ret = write(os->notify_tx, &obituary, sizeof(obituary)); - if (ret <= 0) { - if (ret == 0) - warn_os(os, "unexpected EOF on notify_tx"); - else if (errno != EPIPE) - warn_ose(os, -errno, - "unexpected error on notify_tx"); - close(os->notify_rx); - os->notify_rx = -1; - break; - } - - if (ret != sizeof(obituary)) - warn_os(os, "short transfer on notify_tx"); - pthread_cond_wait(¬ify_poller_kill_wait, &mutex); - } -} - -static void put_os(struct ossp_stream *os) -{ - if (!os) - return; - - pthread_mutex_lock(&mutex); - - assert(os->refcnt); - if (--os->refcnt) { - pthread_mutex_unlock(&mutex); - return; - } - - os->dead = 1; - shutdown_notification(os); - - dbg0_os(os, "DESTROY"); - - list_del_init(&os->link); - list_del_init(&os->pgrp_link); - list_del_init(&os->notify_link); - os->ucnt->nr_os--; - - pthread_mutex_unlock(&mutex); - - close(os->cmd_fd); - close(os->notify_tx); - put_mixer(os->mixer); - pthread_mutex_destroy(&os->cmd_mutex); - pthread_mutex_destroy(&os->mmap_mutex); - - pthread_mutex_lock(&mutex); - dbg1_os(os, "stream dead, requesting reaping"); - list_add_tail(&os->link, &slave_corpse_list); - pthread_cond_signal(&slave_reaper_wait); - pthread_mutex_unlock(&mutex); -} - -static void set_extra_env(pid_t pid) -{ - char procenviron[32]; - const int step = 1024; - char *data = malloc(step + 1); - int ofs = 0; - int fd; - int ret; - - if (!data) - return; - - sprintf(procenviron, "/proc/%d/environ", pid); - fd = open(procenviron, O_RDONLY); - if (fd < 0) - return; - - /* - * There should really be a 'read whole file to a newly allocated - * buffer' function. - */ - while ((ret = read(fd, data + ofs, step)) > 0) { - char *newdata; - ofs += ret; - newdata = realloc(data, ofs + step + 1); - if (!newdata) { - ret = -1; - break; - } - data = newdata; - } - if (ret == 0) { - char *ptr = data; - /* Append the extra 0 for end condition */ - data[ofs] = 0; - - while ((ret = strlen(ptr)) > 0) { - /* - * Copy all PULSE variables and DISPLAY so that - * ssh -X remotehost 'mplayer -ao oss' will work - */ - if (!strncmp(ptr, "DISPLAY=", 8) || - !strncmp(ptr, "PULSE_", 6)) - putenv(ptr); - ptr += ret + 1; - } - } - - free(data); - close(fd); -} - -#ifndef GIOVANNI -int contapid = 13000; -#endif// GIOVANNI - -static int create_os(const char *slave_path, - size_t stream_size, size_t mmap_size, - pid_t pid, pid_t pgrp, uid_t uid, gid_t gid, - struct fuse_session *se, struct ossp_stream **osp) -{ - static pthread_mutex_t create_mutex = PTHREAD_MUTEX_INITIALIZER; - int cmd_sock[2] = { -1, -1 }; - int notify_sock[2] = { -1, -1 }; - struct ossp_stream *os = NULL; - struct epoll_event ev = { }; - int i, rc; - - /* - * Only one thread can be creating a stream. This is to avoid - * leaking unwanted fds into slaves. - */ - pthread_mutex_lock(&create_mutex); - - /* prepare communication channels */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, cmd_sock) || - socketpair(AF_UNIX, SOCK_STREAM, 0, notify_sock)) { - rc = -errno; - warn_e(rc, "failed to create slave command channel"); - goto close_all; - } - - if (fcntl(notify_sock[0], F_SETFL, O_NONBLOCK) < 0) { - rc = -errno; - warn_e(rc, "failed to set NONBLOCK on notify sock"); - goto close_all; - } - - /* - * Alloc stream which will be responsible for all server side - * resources from now on. - */ - rc = alloc_os(stream_size, mmap_size, pid, pgrp, uid, gid, cmd_sock[0], - notify_sock, se, &os); - if (rc) { - warn_e(rc, "failed to allocate stream for %d", pid); - goto close_all; - } - - rc = -ENOMEM; - os->mixer = get_mixer(pgrp); - if (!os->mixer) - goto put_os; - - /* - * Register notification. If successful, notify_poller has - * custody of notify_rx fd. - */ - pthread_mutex_lock(&mutex); - list_add(&os->notify_link, os_notify_tbl_head(os->notify_rx)); - pthread_mutex_unlock(&mutex); - -#ifndef GIOVANNI - os->slave_pid = contapid; - contapid++; - if(contapid > 30000) - contapid=13000; -#endif //GIOVANNI - -//#ifdef GIOVANNI - ev.events = EPOLLIN; - ev.data.fd = notify_sock[0]; - if (epoll_ctl(notify_epfd, EPOLL_CTL_ADD, notify_sock[0], &ev)) { - /* - * Without poller watching this notify sock, poller - * shutdown sequence in shutdown_notification() can't - * be used. Kill notification rx manually. - */ - rc = -errno; - warn_ose(os, rc, "failed to add notify epoll"); - close(os->notify_rx); - os->notify_rx = -1; - goto put_os; - } - - /* start slave */ - os->slave_pid = fork(); - if (os->slave_pid < 0) { - rc = -errno; - warn_ose(os, rc, "failed to fork slave"); - goto put_os; - } - - if (os->slave_pid == 0) { - /* child */ - char id_str[2][16], fd_str[3][16]; - char mmap_off_str[32], mmap_size_str[32]; - char log_str[16], slave_path_copy[PATH_MAX]; - char *argv[] = { slave_path_copy, "-u", id_str[0], - "-g", id_str[1], "-c", fd_str[0], - "-n", fd_str[1], "-m", fd_str[2], - "-o", mmap_off_str, "-s", mmap_size_str, - "-l", log_str, NULL, NULL }; - struct passwd *pwd; - - /* drop stuff we don't need */ - if (close(cmd_sock[0]) || close(notify_sock[0])) - fatal_e(-errno, "failed to close server pipe fds"); - -#ifdef OSSP_MMAP - if (!mmap_size) - close(fuse_mmap_fd(se)); -#endif - - clearenv(); - pwd = getpwuid(os->uid); - if (pwd) { - setenv("LOGNAME", pwd->pw_name, 1); - setenv("USER", pwd->pw_name, 1); - setenv("HOME", pwd->pw_dir, 1); - } - /* Set extra environment variables from the caller */ - set_extra_env(pid); - - /* prep and exec */ - slave_path_copy[sizeof(slave_path_copy) - 1] = '\0'; - strncpy(slave_path_copy, slave_path, sizeof(slave_path_copy) - 1); - if (slave_path_copy[sizeof(slave_path_copy) - 1] != '\0') { - rc = -errno; - err_ose(os, rc, "slave path too long"); - goto child_fail; - } - - snprintf(id_str[0], sizeof(id_str[0]), "%d", os->uid); - snprintf(id_str[1], sizeof(id_str[0]), "%d", os->gid); - snprintf(fd_str[0], sizeof(fd_str[0]), "%d", cmd_sock[1]); - snprintf(fd_str[1], sizeof(fd_str[1]), "%d", notify_sock[1]); - snprintf(fd_str[2], sizeof(fd_str[2]), "%d", -#ifdef OSSP_MMAP - mmap_size ? fuse_mmap_fd(se) : -#endif - -1); - snprintf(mmap_off_str, sizeof(mmap_off_str), "0x%llx", - (unsigned long long)os->mmap_off); - snprintf(mmap_size_str, sizeof(mmap_size_str), "0x%zx", - mmap_size); - snprintf(log_str, sizeof(log_str), "%d", ossp_log_level); - if (ossp_log_timestamp) - argv[ARRAY_SIZE(argv) - 2] = "-t"; - - execv(slave_path, argv); - rc = -errno; - err_ose(os, rc, "execv failed for <%d>", pid); - child_fail: - _exit(1); - } -//#endif //GIOVANNI - - /* turn on CLOEXEC on all server side fds */ - if (fcntl(os->cmd_fd, F_SETFD, FD_CLOEXEC) < 0 || - fcntl(os->notify_tx, F_SETFD, FD_CLOEXEC) < 0 || - fcntl(os->notify_rx, F_SETFD, FD_CLOEXEC) < 0) { - rc = -errno; - err_ose(os, rc, "failed to set CLOEXEC on server side fds"); - goto put_os; - } - - dbg0_os(os, "CREATE slave=%d %s", os->slave_pid, slave_path); - dbg0_os(os, " client=%d cmd=%d:%d notify=%d:%d mmap=%d:0x%llx:%zu", - pid, cmd_sock[0], cmd_sock[1], notify_sock[0], notify_sock[1], -#ifdef OSSP_MMAP - os->mmap_size ? fuse_mmap_fd(se) : -#endif - -1, - (unsigned long long)os->mmap_off, os->mmap_size); - - *osp = os; - rc = 0; - goto close_client_fds; - -put_os: - put_os(os); -close_client_fds: - close(cmd_sock[1]); - pthread_mutex_unlock(&create_mutex); - return rc; - -close_all: - for (i = 0; i < 2; i++) { - close(cmd_sock[i]); - close(notify_sock[i]); - } - pthread_mutex_unlock(&create_mutex); - return rc; -} - -static void dsp_open_common(fuse_req_t req, struct fuse_file_info *fi, - struct fuse_session *se) -{ - const struct fuse_ctx *fuse_ctx = fuse_req_ctx(req); - struct ossp_dsp_open_arg arg = { }; - struct ossp_stream *os = NULL; - struct ossp_mixer *mixer; - struct ossp_dsp_stream *dsps; - struct ossp_mixer_cmd mxcmd; - pid_t pgrp; - ssize_t ret; - - ret = get_proc_self_info(fuse_ctx->pid, &pgrp, NULL, 0); - if (ret) { - err_e(ret, "get_proc_self_info(%d) failed", fuse_ctx->pid); - goto err; - } - - ret = create_os(dsp_slave_path, sizeof(*dsps), DSPS_MMAP_SIZE, - fuse_ctx->pid, pgrp, fuse_ctx->uid, fuse_ctx->gid, - se, &os); - if (ret) - goto err; - dsps = os_to_dsps(os); - mixer = os->mixer; - - switch (fi->flags & O_ACCMODE) { - case O_WRONLY: - dsps->rw |= 1 << PLAY; - break; - case O_RDONLY: - dsps->rw |= 1 << REC; - break; - case O_RDWR: - dsps->rw |= (1 << PLAY) | (1 << REC); - break; - default: - assert(0); - } - - arg.flags = fi->flags; - arg.opener_pid = os->pid; - ret = exec_simple_cmd(&dsps->os, OSSP_DSP_OPEN, &arg, NULL); - if (ret < 0) { - put_os(os); - goto err; - } - - memcpy(os->vol, mixer->vol, sizeof(os->vol)); - if (os->vol[PLAY][0] >= 0 || os->vol[REC][0] >= 0) { - init_mixer_cmd(&mxcmd, mixer); - memcpy(mxcmd.set.vol, os->vol, sizeof(os->vol)); - exec_mixer_cmd(&mxcmd, os); - finish_mixer_cmd(&mxcmd); - } - - fi->direct_io = 1; - fi->nonseekable = 1; - fi->fh = os->id; - - fuse_reply_open(req, fi); - return; - -err: - fuse_reply_err(req, -ret); -} - -static void dsp_open(fuse_req_t req, struct fuse_file_info *fi) -{ - dsp_open_common(req, fi, dsp_se); -} - -static void adsp_open(fuse_req_t req, struct fuse_file_info *fi) -{ - dsp_open_common(req, fi, adsp_se); -} - -static void dsp_release(fuse_req_t req, struct fuse_file_info *fi) -{ - struct ossp_stream *os; - - os = find_os(fi->fh); - if (os) { - put_os(os); - fuse_reply_err(req, 0); - } else - fuse_reply_err(req, EBADF); -} - -static void dsp_read(fuse_req_t req, size_t size, off_t off, - struct fuse_file_info *fi) -{ - struct ossp_dsp_rw_arg arg = { }; - struct ossp_stream *os; - struct ossp_dsp_stream *dsps; - void *buf = NULL; - ssize_t ret; - - ret = -EBADF; - os = find_os(fi->fh); - if (!os) - goto out; - dsps = os_to_dsps(os); - - ret = -EINVAL; - if (!(dsps->rw & (1 << REC))) - goto out; - - ret = -ENXIO; - if (dsps->mmapped) - goto out; - - ret = -ENOMEM; - buf = malloc(size); - if (!buf) - goto out; - - arg.nonblock = (fi->flags & O_NONBLOCK) || dsps->nonblock; - - ret = exec_cmd(os, OSSP_DSP_READ, &arg, sizeof(arg), - NULL, 0, NULL, 0, buf, &size, -1); -out: - if (ret >= 0) - fuse_reply_buf(req, buf, size); - else - fuse_reply_err(req, -ret); - - free(buf); -} - -static void dsp_write(fuse_req_t req, const char *buf, size_t size, off_t off, - struct fuse_file_info *fi) -{ - struct ossp_dsp_rw_arg arg = { }; - struct ossp_stream *os; - struct ossp_dsp_stream *dsps; - ssize_t ret; - - ret = -EBADF; - os = find_os(fi->fh); - if (!os) - goto out; - dsps = os_to_dsps(os); - - ret = -EINVAL; - if (!(dsps->rw & (1 << PLAY))) - goto out; - - ret = -ENXIO; - if (dsps->mmapped) - goto out; - - arg.nonblock = (fi->flags & O_NONBLOCK) || dsps->nonblock; - - ret = exec_cmd(os, OSSP_DSP_WRITE, &arg, sizeof(arg), - buf, size, NULL, 0, NULL, NULL, -1); -out: - if (ret >= 0) - fuse_reply_write(req, ret); - else - fuse_reply_err(req, -ret); -} - -static void dsp_poll(fuse_req_t req, struct fuse_file_info *fi, - struct fuse_pollhandle *ph) -{ - int notify = ph != NULL; - unsigned revents = 0; - struct ossp_stream *os; - ssize_t ret; - - ret = -EBADF; - os = find_os(fi->fh); - if (!os) - goto out; - - if (ph) { - pthread_mutex_lock(&mutex); - if (os->ph) - fuse_pollhandle_destroy(os->ph); - os->ph = ph; - pthread_mutex_unlock(&mutex); - } - - ret = exec_simple_cmd(os, OSSP_DSP_POLL, ¬ify, &revents); -out: - if (ret >= 0) - fuse_reply_poll(req, revents); - else - fuse_reply_err(req, -ret); -} - -static void dsp_ioctl(fuse_req_t req, int signed_cmd, void *uarg, - struct fuse_file_info *fi, unsigned int flags, - const void *in_buf, size_t in_bufsz, size_t out_bufsz) -{ - /* some ioctl constants are long and has the highest bit set */ - unsigned cmd = signed_cmd; - struct ossp_stream *os; - struct ossp_dsp_stream *dsps; - enum ossp_opcode op; - ssize_t ret; - int i; - - ret = -EBADF; - os = find_os(fi->fh); - if (!os) - goto err; - dsps = os_to_dsps(os); - - /* mixer commands are allowed on DSP devices */ - if (((cmd >> 8) & 0xff) == 'M') { - mixer_do_ioctl(req, os->mixer, cmd, uarg, in_buf, in_bufsz, - out_bufsz); - return; - } - - /* and the rest */ - switch (cmd) { - case OSS_GETVERSION: - i = SNDRV_OSS_VERSION; - PREP_UARG(NULL, &i); - IOCTL_RETURN(0, &i); - - case SNDCTL_DSP_GETCAPS: - i = DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | -#ifdef OSSP_MMAP - DSP_CAP_MMAP | -#endif - DSP_CAP_MULTI; - PREP_UARG(NULL, &i); - IOCTL_RETURN(0, &i); - - case SNDCTL_DSP_NONBLOCK: - dsps->nonblock = 1; - ret = 0; - IOCTL_RETURN(0, NULL); - - case SNDCTL_DSP_RESET: op = OSSP_DSP_RESET; goto nd; - case SNDCTL_DSP_SYNC: op = OSSP_DSP_SYNC; goto nd; - case SNDCTL_DSP_POST: op = OSSP_DSP_POST; goto nd; - nd: - ret = exec_simple_cmd(&dsps->os, op, NULL, NULL); - if (ret) - goto err; - IOCTL_RETURN(0, NULL); - - case SOUND_PCM_READ_RATE: op = OSSP_DSP_GET_RATE; goto ri; - case SOUND_PCM_READ_BITS: op = OSSP_DSP_GET_FORMAT; goto ri; - case SOUND_PCM_READ_CHANNELS: op = OSSP_DSP_GET_CHANNELS; goto ri; - case SNDCTL_DSP_GETBLKSIZE: op = OSSP_DSP_GET_BLKSIZE; goto ri; - case SNDCTL_DSP_GETFMTS: op = OSSP_DSP_GET_FORMATS; goto ri; - case SNDCTL_DSP_GETTRIGGER: op = OSSP_DSP_GET_TRIGGER; goto ri; - ri: - PREP_UARG(NULL, &i); - ret = exec_simple_cmd(&dsps->os, op, NULL, &i); - if (ret) - goto err; - IOCTL_RETURN(0, &i); - - case SNDCTL_DSP_SPEED: op = OSSP_DSP_SET_RATE; goto wi; - case SNDCTL_DSP_SETFMT: op = OSSP_DSP_SET_FORMAT; goto wi; - case SNDCTL_DSP_CHANNELS: op = OSSP_DSP_SET_CHANNELS; goto wi; - case SNDCTL_DSP_SUBDIVIDE: op = OSSP_DSP_SET_SUBDIVISION; goto wi; - wi: - PREP_UARG(&i, &i); - ret = exec_simple_cmd(&dsps->os, op, &i, &i); - if (ret) - goto err; - IOCTL_RETURN(0, &i); - - case SNDCTL_DSP_STEREO: - PREP_UARG(NULL, &i); - i = 2; - ret = exec_simple_cmd(&dsps->os, OSSP_DSP_SET_CHANNELS, &i, &i); - i--; - if (ret) - goto err; - IOCTL_RETURN(0, &i); - - case SNDCTL_DSP_SETFRAGMENT: - PREP_UARG(&i, NULL); - ret = exec_simple_cmd(&dsps->os, - OSSP_DSP_SET_FRAGMENT, &i, NULL); - if (ret) - goto err; - IOCTL_RETURN(0, NULL); - - case SNDCTL_DSP_SETTRIGGER: - PREP_UARG(&i, NULL); - ret = exec_simple_cmd(&dsps->os, - OSSP_DSP_SET_TRIGGER, &i, NULL); - if (ret) - goto err; - IOCTL_RETURN(0, NULL); - - case SNDCTL_DSP_GETOSPACE: - case SNDCTL_DSP_GETISPACE: { - struct audio_buf_info info; - - ret = -EINVAL; - if (cmd == SNDCTL_DSP_GETOSPACE) { - if (!(dsps->rw & (1 << PLAY))) - goto err; - op = OSSP_DSP_GET_OSPACE; - } else { - if (!(dsps->rw & (1 << REC))) - goto err; - op = OSSP_DSP_GET_ISPACE; - } - - PREP_UARG(NULL, &info); - ret = exec_simple_cmd(&dsps->os, op, NULL, &info); - if (ret) - goto err; - IOCTL_RETURN(0, &info); - } - - case SNDCTL_DSP_GETOPTR: - case SNDCTL_DSP_GETIPTR: { - struct count_info info; - - op = cmd == SNDCTL_DSP_GETOPTR ? OSSP_DSP_GET_OPTR - : OSSP_DSP_GET_IPTR; - PREP_UARG(NULL, &info); - ret = exec_simple_cmd(&dsps->os, op, NULL, &info); - if (ret) - goto err; - IOCTL_RETURN(0, &info); - } - - case SNDCTL_DSP_GETODELAY: - PREP_UARG(NULL, &i); - i = 0; - ret = exec_simple_cmd(&dsps->os, OSSP_DSP_GET_ODELAY, NULL, &i); - IOCTL_RETURN(ret, &i); /* always copy out result, 0 on err */ - - case SOUND_PCM_WRITE_FILTER: - case SOUND_PCM_READ_FILTER: - ret = -EIO; - goto err; - - case SNDCTL_DSP_MAPINBUF: - case SNDCTL_DSP_MAPOUTBUF: - ret = -EINVAL; - goto err; - - case SNDCTL_DSP_SETSYNCRO: - case SNDCTL_DSP_SETDUPLEX: - case SNDCTL_DSP_PROFILE: - IOCTL_RETURN(0, NULL); - - default: - warn_os(os, "unknown ioctl 0x%x", cmd); - ret = -EINVAL; - goto err; - } - assert(0); /* control shouldn't reach here */ -err: - fuse_reply_err(req, -ret); -} - -#ifdef OSSP_MMAP -static int dsp_mmap_dir(int prot) -{ - if (!(prot & PROT_WRITE)) - return REC; - return PLAY; -} - -static void dsp_mmap(fuse_req_t req, void *addr, size_t len, int prot, - int flags, off_t offset, struct fuse_file_info *fi, - uint64_t mh) -{ - int dir = dsp_mmap_dir(prot); - struct ossp_dsp_mmap_arg arg = { }; - struct ossp_stream *os; - struct ossp_dsp_stream *dsps; - ssize_t ret; - - os = find_os(fi->fh); - if (!os) { - fuse_reply_err(req, EBADF); - return; - } - dsps = os_to_dsps(os); - - if (!os->mmap_off || len > os->mmap_size / 2) { - fuse_reply_err(req, EINVAL); - return; - } - - pthread_mutex_lock(&os->mmap_mutex); - - ret = -EBUSY; - if (dsps->mmapped & (1 << dir)) - goto out_unlock; - - arg.dir = dir; - arg.size = len; - - ret = exec_simple_cmd(os, OSSP_DSP_MMAP, &arg, NULL); - if (ret == 0) - dsps->mmapped |= 1 << dir; - -out_unlock: - pthread_mutex_unlock(&os->mmap_mutex); - - if (ret == 0) - fuse_reply_mmap(req, os->mmap_off + dir * os->mmap_size / 2, 0); - else - fuse_reply_err(req, -ret); -} - -static void dsp_munmap(fuse_req_t req, size_t len, struct fuse_file_info *fi, - off_t offset, uint64_t mh) -{ - struct ossp_stream *os; - struct ossp_dsp_stream *dsps; - int dir, rc; - - os = find_os(fi->fh); - if (!os) - goto out; - dsps = os_to_dsps(os); - - pthread_mutex_lock(&os->mmap_mutex); - - for (dir = 0; dir < 2; dir++) - if (offset == os->mmap_off + dir * os->mmap_size / 2) - break; - if (dir == 2 || len > os->mmap_size / 2) { - warn_os(os, "invalid munmap request " - "offset=%llu len=%zu mmapped=0x%x", - (unsigned long long)offset, len, dsps->mmapped); - goto out_unlock; - } - - rc = exec_simple_cmd(os, OSSP_DSP_MUNMAP, &dir, NULL); - if (rc) - warn_ose(os, rc, "MUNMAP failed for dir=%d", dir); - - dsps->mmapped &= ~(1 << dir); - -out_unlock: - pthread_mutex_unlock(&os->mmap_mutex); -out: - fuse_reply_none(req); -} -#endif - - -/*************************************************************************** - * Notify poller - */ - -static void *notify_poller(void *arg) -{ - struct epoll_event events[1024]; - int i, nfds; - -repeat: - nfds = epoll_wait(notify_epfd, events, ARRAY_SIZE(events), -1); - for (i = 0; i < nfds; i++) { - int do_notify = 0; - struct ossp_stream *os; - struct ossp_notify notify; - ssize_t ret; - - os = find_os_by_notify_rx(events[i].data.fd); - if (!os) { - err("can't find stream for notify_rx fd %d", - events[i].data.fd); - epoll_ctl(notify_epfd, EPOLL_CTL_DEL, events[i].data.fd, - NULL); - /* we don't know what's going on, don't close the fd */ - continue; - } - - while ((ret = read(os->notify_rx, - ¬ify, sizeof(notify))) > 0) { - if (os->dead) - continue; - if (ret != sizeof(notify)) { - warn_os(os, "short read on notify_rx (%zu, " - "expected %zu), killing the stream", - ret, sizeof(notify)); - os->dead = 1; - break; - } - if (notify.magic != OSSP_NOTIFY_MAGIC) { - warn_os(os, "invalid magic on notification, " - "killing the stream"); - os->dead = 1; - break; - } - - if (notify.opcode >= OSSP_NR_NOTIFY_OPCODES) - goto unknown; - - dbg1_os(os, "NOTIFY %s", ossp_notify_str[notify.opcode]); - - switch (notify.opcode) { - case OSSP_NOTIFY_POLL: - do_notify = 1; - break; - case OSSP_NOTIFY_OBITUARY: - os->dead = 1; - break; - case OSSP_NOTIFY_VOLCHG: - pthread_mutex_lock(&mixer_mutex); - os->mixer->modify_counter++; - pthread_mutex_unlock(&mixer_mutex); - break; - default: - unknown: - warn_os(os, "unknown notification %d", - notify.opcode); - } - } - if (ret == 0) - os->dead = 1; - else if (ret < 0 && errno != EAGAIN) { - warn_ose(os, -errno, "read fail on notify fd"); - os->dead = 1; - } - - if (!do_notify && !os->dead) - continue; - - pthread_mutex_lock(&mutex); - - if (os->ph) { - fuse_lowlevel_notify_poll(os->ph); - fuse_pollhandle_destroy(os->ph); - os->ph = NULL; - } - - if (os->dead) { - dbg0_os(os, "removing %d from notify poll list", - os->notify_rx); - epoll_ctl(notify_epfd, EPOLL_CTL_DEL, os->notify_rx, - NULL); - close(os->notify_rx); - os->notify_rx = -1; - pthread_cond_broadcast(¬ify_poller_kill_wait); - } - - pthread_mutex_unlock(&mutex); - } - goto repeat; -} - - -/*************************************************************************** - * Slave corpse reaper - */ - -static void *slave_reaper(void *arg) -{ - struct ossp_stream *os; - int status; - pid_t pid; - - pthread_mutex_lock(&mutex); -repeat: - while (list_empty(&slave_corpse_list)) - pthread_cond_wait(&slave_reaper_wait, &mutex); - - os = list_first_entry(&slave_corpse_list, struct ossp_stream, link); - list_del_init(&os->link); - - pthread_mutex_unlock(&mutex); - - do { - pid = waitpid(os->slave_pid, &status, 0); - } while (pid < 0 && errno == EINTR); - - if (pid < 0) { - if (errno == ECHILD) - warn_ose(os, -errno, "slave %d already gone?", - os->slave_pid); - else - fatal_e(-errno, "waitpid(%d) failed", os->slave_pid); - } - - pthread_mutex_lock(&mutex); - - dbg1_os(os, "slave %d reaped", os->slave_pid); - __clear_bit(os->id, os_id_bitmap); - free(os); - - goto repeat; -} - - -/*************************************************************************** - * Stuff to bind and start everything - */ - -static void ossp_daemonize(void) -{ - int fd, pfd[2]; - pid_t pid; - ssize_t ret; - int err; - - fd = open("/dev/null", O_RDWR); - if (fd >= 0) { - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - if (fd > 2) - close(fd); - } - - if (pipe(pfd)) - fatal_e(-errno, "failed to create pipe for init wait"); - - if (fcntl(pfd[0], F_SETFD, FD_CLOEXEC) < 0 || - fcntl(pfd[1], F_SETFD, FD_CLOEXEC) < 0) - fatal_e(-errno, "failed to set CLOEXEC on init wait pipe"); - - pid = fork(); - if (pid < 0) - fatal_e(-errno, "failed to fork for daemon"); - - if (pid == 0) { - close(pfd[0]); - init_wait_fd = pfd[1]; - - /* be evil, my child */ - chdir("/"); - setsid(); - return; - } - - /* wait for init completion and pass over success indication */ - close(pfd[1]); - - do { - ret = read(pfd[0], &err, sizeof(err)); - } while (ret < 0 && errno == EINTR); - - if (ret == sizeof(err) && err == 0) - exit(0); - - fatal("daemon init failed ret=%zd err=%d", ret, err); - exit(1); -} - -static void ossp_init_done(void *userdata) -{ - /* init complete, notify parent if it's waiting */ - if (init_wait_fd >= 0) { - ssize_t ret; - int err = 0; - - ret = write(init_wait_fd, &err, sizeof(err)); - if (ret != sizeof(err)) - fatal_e(-errno, "failed to notify init completion, " - "ret=%zd", ret); - close(init_wait_fd); - init_wait_fd = -1; - } -} - -static const struct cuse_lowlevel_ops mixer_ops = { - .open = mixer_open, - .release = mixer_release, - .ioctl = mixer_ioctl, -}; - -static const struct cuse_lowlevel_ops dsp_ops = { - .init_done = ossp_init_done, - .open = dsp_open, - .release = dsp_release, - .read = dsp_read, - .write = dsp_write, - .poll = dsp_poll, - .ioctl = dsp_ioctl, -#ifdef OSSP_MMAP - .mmap = dsp_mmap, - .munmap = dsp_munmap, -#endif -}; - -static const struct cuse_lowlevel_ops adsp_ops = { - .open = adsp_open, - .release = dsp_release, - .read = dsp_read, - .write = dsp_write, - .poll = dsp_poll, - .ioctl = dsp_ioctl, -#ifdef OSSP_MMAP - .mmap = dsp_mmap, - .munmap = dsp_munmap, -#endif -}; - -static const char *usage = -"usage: osspd [options]\n" -"\n" -"options:\n" -" --help print this help message\n" -" --dsp=NAME DSP device name (default dsp)\n" -" --dsp-maj=MAJ DSP device major number (default 14)\n" -" --dsp-min=MIN DSP device minor number (default 3)\n" -" --adsp=NAME Aux DSP device name (default adsp, blank to disable)\n" -" --adsp-maj=MAJ Aux DSP device major number (default 14)\n" -" --adsp-min=MIN Aux DSP device minor number (default 12)\n" -" --mixer=NAME mixer device name (default mixer, blank to disable)\n" -" --mixer-maj=MAJ mixer device major number (default 14)\n" -" --mixer-min=MIN mixer device minor number (default 0)\n" -" --max=MAX maximum number of open streams (default 256)\n" -" --umax=MAX maximum number of open streams per UID (default --max)\n" -" --exit-on-idle exit if idle\n" -" --dsp-slave=PATH DSP slave (default ossp-padsp in the same dir)\n" -" --log=LEVEL log level (0..6)\n" -" --timestamp timestamp log messages\n" -" -v increase verbosity, can be specified multiple times\n" -" -f Run in foreground (don't daemonize)\n" -"\n"; - -struct ossp_param { - char *dsp_name; - unsigned dsp_major; - unsigned dsp_minor; - char *adsp_name; - unsigned adsp_major; - unsigned adsp_minor; - char *mixer_name; - unsigned mixer_major; - unsigned mixer_minor; - unsigned max_streams; - unsigned umax_streams; - char *dsp_slave_path; - unsigned log_level; - int exit_on_idle; - int timestamp; - int fg; - int help; -}; - -#define OSSP_OPT(t, p) { t, offsetof(struct ossp_param, p), 1 } - -static const struct fuse_opt ossp_opts[] = { - OSSP_OPT("--dsp=%s", dsp_name), - OSSP_OPT("--dsp-maj=%u", dsp_major), - OSSP_OPT("--dsp-min=%u", dsp_minor), - OSSP_OPT("--adsp=%s", adsp_name), - OSSP_OPT("--adsp-maj=%u", adsp_major), - OSSP_OPT("--adsp-min=%u", adsp_minor), - OSSP_OPT("--mixer=%s", mixer_name), - OSSP_OPT("--mixer-maj=%u", mixer_major), - OSSP_OPT("--mixer-min=%u", mixer_minor), - OSSP_OPT("--max=%u", max_streams), - OSSP_OPT("--umax=%u", umax_streams), - OSSP_OPT("--exit-on-idle", exit_on_idle), - OSSP_OPT("--dsp-slave=%s", dsp_slave_path), - OSSP_OPT("--timestamp", timestamp), - OSSP_OPT("--log=%u", log_level), - OSSP_OPT("-f", fg), - FUSE_OPT_KEY("-h", 0), - FUSE_OPT_KEY("--help", 0), - FUSE_OPT_KEY("-v", 1), - FUSE_OPT_END -}; - -static struct fuse_session *setup_ossp_cuse(const struct cuse_lowlevel_ops *ops, - const char *name, int major, - int minor, int argc, char **argv) -{ - char name_buf[128]; - const char *bufp = name_buf; - struct cuse_info ci = { .dev_major = major, .dev_minor = minor, - .dev_info_argc = 1, .dev_info_argv = &bufp, - .flags = CUSE_UNRESTRICTED_IOCTL }; - struct fuse_session *se; - int fd; - - snprintf(name_buf, sizeof(name_buf), "DEVNAME=%s", name); - - se = cuse_lowlevel_setup(argc, argv, &ci, ops, NULL, NULL); - if (!se) { - err("failed to setup %s CUSE", name); - return NULL; - } - - fd = fuse_chan_fd(fuse_session_next_chan(se, NULL)); - if ( -#ifdef OSSP_MMAP - fd != fuse_mmap_fd(se) && -#endif - fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) { - err_e(-errno, "failed to set CLOEXEC on %s CUSE fd", name); - cuse_lowlevel_teardown(se); - return NULL; - } - - return se; -} - -static void *cuse_worker(void *arg) -{ - struct fuse_session *se = arg; - int rc; - - rc = fuse_session_loop_mt(se); - cuse_lowlevel_teardown(se); - - return (void *)(unsigned long)rc; -} - -static int process_arg(void *data, const char *arg, int key, - struct fuse_args *outargs) -{ - struct ossp_param *param = data; - - switch (key) { - case 0: - fprintf(stderr, usage); - param->help = 1; - return 0; - case 1: - param->log_level++; - return 0; - } - return 1; -} - -int main(int argc, char **argv) -{ - static struct ossp_param param = { - .dsp_name = DFL_DSP_NAME, - .dsp_major = DFL_DSP_MAJOR, .dsp_minor = DFL_DSP_MINOR, - .adsp_name = DFL_ADSP_NAME, - .adsp_major = DFL_ADSP_MAJOR, .adsp_minor = DFL_ADSP_MINOR, - .mixer_name = DFL_MIXER_NAME, - .mixer_major = DFL_MIXER_MAJOR, .mixer_minor = DFL_MIXER_MINOR, - .max_streams = DFL_MAX_STREAMS, - }; - struct fuse_args args = FUSE_ARGS_INIT(argc, argv); - char path_buf[PATH_MAX], *dir; - char adsp_buf[64] = "", mixer_buf[64] = ""; - struct sigaction sa; - struct stat stat_buf; - ssize_t ret; - unsigned u; - - snprintf(ossp_log_name, sizeof(ossp_log_name), "osspd"); - param.log_level = ossp_log_level; - - if (fuse_opt_parse(&args, ¶m, ossp_opts, process_arg)) - fatal("failed to parse arguments"); - - if (param.help) - return 0; - - max_streams = param.max_streams; - hashtbl_size = max_streams / 2 + 13; - - umax_streams = max_streams; - if (param.umax_streams) - umax_streams = param.umax_streams; - if (param.log_level > OSSP_LOG_MAX) - param.log_level = OSSP_LOG_MAX; - if (!param.fg) - param.log_level = -param.log_level; - ossp_log_level = param.log_level; - ossp_log_timestamp = param.timestamp; - - if (!param.fg) - ossp_daemonize(); - - /* daemonization already handled, prevent forking inside FUSE */ - fuse_opt_add_arg(&args, "-f"); - - info("OSS Proxy v%s (C) 2008-2010 by Tejun Heo ", - OSSP_VERSION); - - /* ignore stupid SIGPIPEs */ - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_IGN; - if (sigaction(SIGPIPE, &sa, NULL)) - fatal_e(-errno, "failed to ignore SIGPIPE"); - -//#ifdef GIOVANNI - /* determine slave path and check for availability */ - ret = readlink("/proc/self/exe", path_buf, PATH_MAX - 1); - if (ret < 0) - fatal_e(-errno, "failed to determine executable path"); - path_buf[ret] = '\0'; - dir = dirname(path_buf); - - if (param.dsp_slave_path) { - strncpy(dsp_slave_path, param.dsp_slave_path, PATH_MAX - 1); - dsp_slave_path[PATH_MAX - 1] = '\0'; - } else { - ret = snprintf(dsp_slave_path, PATH_MAX, "%s/%s", - dir, "ossp-padsp"); - if (ret >= PATH_MAX) - fatal("dsp slave pathname too long"); - } - - if (stat(dsp_slave_path, &stat_buf)) - fatal_e(-errno, "failed to stat %s", dsp_slave_path); - if (!S_ISREG(stat_buf.st_mode) || !(stat_buf.st_mode & 0444)) - fatal("%s is not executable", dsp_slave_path); - -//#endif// GIOVANNI - /* allocate tables */ - os_id_bitmap = calloc(BITS_TO_LONGS(max_streams), sizeof(long)); - mixer_tbl = calloc(hashtbl_size, sizeof(mixer_tbl[0])); - os_tbl = calloc(hashtbl_size, sizeof(os_tbl[0])); - os_pgrp_tbl = calloc(hashtbl_size, sizeof(os_pgrp_tbl[0])); - os_notify_tbl = calloc(hashtbl_size, sizeof(os_notify_tbl[0])); - if (!os_id_bitmap || !mixer_tbl || !os_tbl || !os_pgrp_tbl || - !os_notify_tbl) - fatal("failed to allocate stream hash tables"); - for (u = 0; u < hashtbl_size; u++) { - INIT_LIST_HEAD(&mixer_tbl[u]); - INIT_LIST_HEAD(&os_tbl[u]); - INIT_LIST_HEAD(&os_pgrp_tbl[u]); - INIT_LIST_HEAD(&os_notify_tbl[u]); - } - __set_bit(0, os_id_bitmap); /* don't use id 0 */ - - /* create mixer delayed reference worker */ - ret = -pthread_create(&mixer_delayed_put_thread, NULL, - mixer_delayed_put_worker, NULL); - if (ret) - fatal_e(ret, "failed to create mixer delayed put worker"); - - /* if exit_on_idle, touch mixer for pgrp0 */ - exit_on_idle = param.exit_on_idle; - if (exit_on_idle) { - struct ossp_mixer *mixer; - - mixer = get_mixer(0); - if (!mixer) - fatal("failed to touch idle mixer"); - put_mixer(mixer); - } - - /* create notify epoll and kick off watcher thread */ - notify_epfd = epoll_create(max_streams); - if (notify_epfd < 0) - fatal_e(-errno, "failed to create notify epoll"); - if (fcntl(notify_epfd, F_SETFD, FD_CLOEXEC) < 0) - fatal_e(-errno, "failed to set CLOEXEC on notify epfd"); - - ret = -pthread_create(¬ify_poller_thread, NULL, notify_poller, NULL); - if (ret) - fatal_e(ret, "failed to create notify poller thread"); - - /* create reaper for slave corpses */ - ret = -pthread_create(&slave_reaper_thread, NULL, slave_reaper, NULL); - if (ret) - fatal_e(ret, "failed to create slave reaper thread"); - -#ifdef GIOVANNI - /* we're set, let's setup fuse structures */ - if (strlen(param.mixer_name)) - mixer_se = setup_ossp_cuse(&mixer_ops, param.mixer_name, - param.mixer_major, param.mixer_minor, - args.argc, args.argv); - if (strlen(param.adsp_name)) - adsp_se = setup_ossp_cuse(&dsp_ops, param.adsp_name, - param.adsp_major, param.adsp_minor, - args.argc, args.argv); - -#endif// GIOVANNI - dsp_se = setup_ossp_cuse(&dsp_ops, param.dsp_name, - param.dsp_major, param.dsp_minor, - args.argc, args.argv); - if (!dsp_se) - fatal("can't create dsp, giving up"); - -#ifdef GIOVANNI - if (mixer_se) - snprintf(mixer_buf, sizeof(mixer_buf), ", %s (%d:%d)", - param.mixer_name, param.mixer_major, param.mixer_minor); - if (adsp_se) - snprintf(adsp_buf, sizeof(adsp_buf), ", %s (%d:%d)", - param.adsp_name, param.adsp_major, param.adsp_minor); - -#endif// GIOVANNI - info("Creating %s (%d:%d)%s%s", param.dsp_name, param.dsp_major, - param.dsp_minor, adsp_buf, mixer_buf); - -#ifdef GIOVANNI - /* start threads for mixer and adsp */ - if (mixer_se) { - ret = -pthread_create(&cuse_mixer_thread, NULL, - cuse_worker, mixer_se); - if (ret) - err_e(ret, "failed to create mixer worker"); - } - if (adsp_se) { - ret = -pthread_create(&cuse_adsp_thread, NULL, - cuse_worker, adsp_se); - if (ret) - err_e(ret, "failed to create adsp worker"); - } -#endif// GIOVANNI - - /* run CUSE for /dev/dsp in the main thread */ - ret = (ssize_t)cuse_worker(dsp_se); - if (ret < 0) - fatal("dsp worker failed"); - return 0; -} diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index bcc8f75692..c1431c28e9 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -766,7 +766,6 @@ static switch_status_t sofia_read_video_frame(switch_core_session_t *session, sw { private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session); switch_channel_t *channel = switch_core_session_get_channel(session); - int payload = 0; switch_assert(tech_pvt != NULL); @@ -810,8 +809,6 @@ static switch_status_t sofia_read_video_frame(switch_core_session_t *session, sw return status; } - payload = tech_pvt->video_read_frame.payload; - if (tech_pvt->video_read_frame.datalen > 0) { break; } @@ -867,7 +864,6 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f { private_object_t *tech_pvt = switch_core_session_get_private(session); switch_channel_t *channel = switch_core_session_get_channel(session); - int payload = 0; uint32_t sanity = 1000; switch_rtcp_frame_t rtcp_frame; @@ -979,8 +975,6 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f return SWITCH_STATUS_SUCCESS; } - payload = tech_pvt->read_frame.payload; - if (switch_rtp_has_dtmf(tech_pvt->rtp_session)) { switch_dtmf_t dtmf = { 0 }; switch_rtp_dequeue_dtmf(tech_pvt->rtp_session, &dtmf); @@ -1859,13 +1853,13 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi const char *name = msg->string_array_arg[0], *number = msg->string_array_arg[1]; char *arg = NULL; char *argv[2] = { 0 }; - int argc; + //int argc; if (zstr(name) && !zstr(msg->string_arg)) { arg = strdup(msg->string_arg); switch_assert(arg); - argc = switch_separate_string(arg, '|', argv, (sizeof(argv) / sizeof(argv[0]))); + switch_separate_string(arg, '|', argv, (sizeof(argv) / sizeof(argv[0]))); name = argv[0]; number = argv[1]; @@ -4910,7 +4904,7 @@ static switch_status_t list_profile_gateway(const char *line, const char *cursor switch_console_callback_match_t *my_matches = NULL; switch_status_t status = SWITCH_STATUS_FALSE; char *dup = NULL; - int argc; + //int argc; char *argv[4] = { 0 }; if (zstr(line)) { @@ -4918,7 +4912,7 @@ static switch_status_t list_profile_gateway(const char *line, const char *cursor } dup = strdup(line); - argc = switch_split(dup, ' ', argv); + switch_split(dup, ' ', argv); if (zstr(argv[2]) || !strcmp(argv[2], " ")) { goto end; @@ -4962,7 +4956,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) switch_find_local_ip(mod_sofia_globals.guess_ip, sizeof(mod_sofia_globals.guess_ip), &mod_sofia_globals.guess_mask, AF_INET); in.s_addr = mod_sofia_globals.guess_mask; switch_set_string(mod_sofia_globals.guess_mask_str, inet_ntoa(in)); - gethostname(mod_sofia_globals.hostname, sizeof(mod_sofia_globals.hostname)); + + strcpy(mod_sofia_globals.hostname, switch_core_get_switchname()); switch_core_hash_init(&mod_sofia_globals.profile_hash, mod_sofia_globals.pool); diff --git a/src/mod/endpoints/mod_sofia/sip-dig.c b/src/mod/endpoints/mod_sofia/sip-dig.c index d0c9aa6aff..556abae96d 100644 --- a/src/mod/endpoints/mod_sofia/sip-dig.c +++ b/src/mod/endpoints/mod_sofia/sip-dig.c @@ -210,17 +210,14 @@ void _usage(int exitcode, switch_stream_handle_t *stream) switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream) { - int exitcode = 0; int o_sctp = 1, o_tls_sctp = 1, o_verbatim = 1; int family = 0, multiple = 0; - char const *dnsserver = NULL; char const *string; url_t *uri = NULL; char const *host; char const *port; char *transport = NULL, tport[32]; - int argc; char *argv_[25] = { 0 }; char *mycmd = NULL; char **argv; @@ -239,7 +236,7 @@ switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_cor mycmd = strdup(cmd); - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv_) / sizeof(argv_[0])) - 1); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv_) / sizeof(argv_[0])) - 1); argv = argv_; @@ -321,10 +318,6 @@ switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_cor if (!family) dig->ip4 = 1, dig->ip6 = 2; - if (argv[1] && argv[1][0] == '@') - dnsserver = argv++[1] + 1; - - if (!argv[1]) {usage(2);} @@ -360,7 +353,6 @@ switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_cor if (!uri || (uri->url_type != url_sip && uri->url_type != url_sips)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: invalid uri\n", string); - exitcode = 1; continue; } @@ -387,7 +379,6 @@ switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_cor if (!host_is_domain(host)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: invalid host\n", string); - exitcode = 1; continue; } @@ -402,7 +393,6 @@ switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_cor continue /* resolved a/aaaa */; stream->write_function(stream, "-ERR: %s: not found\n", string); - exitcode = 1; } if (xml) { diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 2bf27d5ba8..3682260809 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -519,6 +519,14 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status, cause = sofia_glue_sip_cause_to_freeswitch(status); } + if (sip->sip_content_type && sip->sip_content_type->c_type) { + switch_channel_set_variable(channel, "sip_bye_content_type", sip->sip_content_type->c_type); + } + + if (sip->sip_payload && sip->sip_payload->pl_data) { + switch_channel_set_variable(channel, "sip_bye_payload", sip->sip_payload->pl_data); + } + switch_snprintf(st, sizeof(st), "%d", status); switch_channel_set_variable(channel, "sip_term_status", st); switch_snprintf(st, sizeof(st), "sip:%d", status); @@ -1457,7 +1465,7 @@ switch_thread_t *launch_sofia_worker_thread(sofia_profile_t *profile) void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void *obj) { sofia_profile_t *profile = (sofia_profile_t *) obj; - switch_memory_pool_t *pool; + //switch_memory_pool_t *pool; sip_alias_node_t *node; switch_event_t *s_event; int use_100rel = !sofia_test_pflag(profile, PFLAG_DISABLE_100REL); @@ -1717,7 +1725,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void su_home_unref(profile->home); su_root_destroy(profile->s_root); - pool = profile->pool; + //pool = profile->pool; sofia_glue_del_profile(profile); switch_core_hash_destroy(&profile->chat_hash); @@ -4790,7 +4798,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (status == 183 && !r_sdp) { if ((channel && switch_true(switch_channel_get_variable(channel, "sip_ignore_183nosdp"))) || sofia_test_pflag(profile, PFLAG_IGNORE_183NOSDP)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Ignoring 183 w/o sdp\n", switch_channel_get_name(channel)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Ignoring 183 w/o sdp\n", channel ? switch_channel_get_name(channel) : "None"); goto done; } status = 180; @@ -5581,7 +5589,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t { /* Incoming refer */ sip_from_t const *from; - sip_to_t const *to; + //sip_to_t const *to; sip_refer_to_t const *refer_to; private_object_t *tech_pvt = switch_core_session_get_private(session); char *etmp = NULL, *exten = NULL; @@ -5604,7 +5612,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t } from = sip->sip_from; - to = sip->sip_to; + //to = sip->sip_to; home = su_home_new(sizeof(*home)); switch_assert(home != NULL); @@ -6374,7 +6382,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ const char *displayname = NULL; const char *destination_number = NULL; const char *from_user = NULL, *from_host = NULL; - const char *referred_by_user = NULL, *referred_by_host = NULL; + const char *referred_by_user = NULL;//, *referred_by_host = NULL; const char *context = NULL; const char *dialplan = NULL; char network_ip[80]; @@ -6905,7 +6913,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ if (sip->sip_referred_by) { referred_by_user = sip->sip_referred_by->b_url->url_user; - referred_by_host = sip->sip_referred_by->b_url->url_host; + //referred_by_host = sip->sip_referred_by->b_url->url_host; channel_name = url_set_chanvars(session, sip->sip_referred_by->b_url, sip_referred_by); check_decode(referred_by_user, session); @@ -7047,8 +7055,9 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ } if (!gateway && gw_param_name) { - gateway = sofia_reg_find_gateway(gw_param_name); - extension = gateway->real_extension; + if ((gateway = sofia_reg_find_gateway(gw_param_name))) { + extension = gateway->real_extension; + } } if (gateway) { @@ -7149,7 +7158,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ const char *data = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_DATA_VARIABLE); if (app && data && !strcasecmp(app, "conference")) { - destination_number = switch_core_session_sprintf(b_session, "answer,conference:%s", data); + destination_number = switch_core_session_sprintf(session, "answer,conference:%s", data); dialplan = "inline"; } else { if (switch_core_session_check_interface(b_session, sofia_endpoint_interface)) { @@ -7157,8 +7166,6 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ } if ((uuid = switch_channel_get_variable(b_channel, SWITCH_SIGNAL_BOND_VARIABLE))) { - switch_channel_set_variable(b_channel, "presence_call_info", NULL); - switch_channel_set_variable(b_channel, "presence_call_info_full", NULL); one_leg = 0; } else { uuid = switch_core_session_get_uuid(b_session); @@ -7187,7 +7194,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ if (!one_leg && (!b_tech_pvt || !sofia_test_flag(b_tech_pvt, TFLAG_SIP_HOLD)) && (!c_tech_pvt || !sofia_test_flag(c_tech_pvt, TFLAG_SIP_HOLD))) { - char *ext = switch_core_session_sprintf(b_session, "answer,conference:%s@sla+flags{mintwo}", uuid); + char *ext = switch_core_session_sprintf(session, "answer,conference:%s@sla+flags{mintwo}", uuid); switch_channel_set_flag(c_channel, CF_REDIRECT); switch_ivr_session_transfer(b_session, ext, "inline", NULL); @@ -7199,16 +7206,17 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ } if (do_conf) { - destination_number = switch_core_session_sprintf(b_session, "answer,conference:%s@sla+flags{mintwo}", uuid); + destination_number = switch_core_session_sprintf(session, "answer,conference:%s@sla+flags{mintwo}", uuid); } else { if (one_leg && c_app) { if (c_data) { - destination_number = switch_core_session_sprintf(b_session, "answer,%s:%s", c_app, c_data); + destination_number = switch_core_session_sprintf(session, "answer,%s:%s", c_app, c_data); } else { - destination_number = switch_core_session_sprintf(b_session, "answer,%s", c_app); + destination_number = switch_core_session_sprintf(session, "answer,%s", c_app); } } else { - destination_number = switch_core_session_sprintf(b_session, "answer,intercept:%s", uuid); + switch_channel_mark_hold(b_channel, SWITCH_FALSE); + destination_number = switch_core_session_sprintf(session, "answer,intercept:%s", uuid); } } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 66bf8ea644..74da94b2c4 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -187,7 +187,7 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t * static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen, switch_port_t port, - int cur_ptime, const char *append_audio, const char *sr, int use_cng, int cng_type, switch_event_t *map, int verbose_sdp) + int cur_ptime, const char *append_audio, const char *sr, int use_cng, int cng_type, switch_event_t *map, int verbose_sdp, int secure) { int i = 0; int rate; @@ -195,7 +195,7 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen, int ptime = 0, noptime = 0; switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "m=audio %d RTP/%sAVP", - port, (!zstr(tech_pvt->local_crypto_key) && sofia_test_flag(tech_pvt, TFLAG_SECURE)) ? "S" : ""); + port, secure ? "S" : ""); @@ -312,6 +312,11 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen, switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d telephone-event/8000\na=fmtp:%d 0-16\n", tech_pvt->te, tech_pvt->te); } + if (secure) { + switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=crypto:%s\n", tech_pvt->local_crypto_key); + //switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n"); + } + if (!cng_type) { //switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d CN/8000\n", cng_type); //} else { @@ -333,7 +338,6 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen, if (sr) { switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=%s\n", sr); } - } void sofia_glue_check_dtmf_type(private_object_t *tech_pvt) @@ -529,7 +533,11 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 if (sr) { switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=%s\n", sr); } - + + if (!zstr(tech_pvt->local_crypto_key) && sofia_test_flag(tech_pvt, TFLAG_SECURE)) { + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=crypto:%s\n", tech_pvt->local_crypto_key); + //switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n"); + } } else if (tech_pvt->num_codecs) { int i; @@ -545,7 +553,15 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 } if (!switch_true(switch_channel_get_variable(tech_pvt->channel, "sdp_m_per_ptime"))) { - generate_m(tech_pvt, buf, sizeof(buf), port, 0, append_audio, sr, use_cng, cng_type, map, verbose_sdp); + char *bp = buf; + + if ((!zstr(tech_pvt->local_crypto_key) && sofia_test_flag(tech_pvt, TFLAG_SECURE))) { + generate_m(tech_pvt, buf, sizeof(buf), port, 0, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 1); + bp = (buf + strlen(buf)); + } + + generate_m(tech_pvt, bp, sizeof(buf) - strlen(buf), port, 0, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 0); + } else { for (i = 0; i < tech_pvt->num_codecs; i++) { @@ -558,8 +574,15 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 this_ptime = imp->microseconds_per_packet / 1000; if (cur_ptime != this_ptime) { - cur_ptime = this_ptime; - generate_m(tech_pvt, buf, sizeof(buf), port, cur_ptime, append_audio, sr, use_cng, cng_type, map, verbose_sdp); + char *bp = buf; + cur_ptime = this_ptime; + + if ((!zstr(tech_pvt->local_crypto_key) && sofia_test_flag(tech_pvt, TFLAG_SECURE))) { + generate_m(tech_pvt, buf, sizeof(buf), port, cur_ptime, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 1); + bp = (buf + strlen(buf)); + } + + generate_m(tech_pvt, bp, sizeof(buf) - strlen(buf), port, cur_ptime, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 0); } } @@ -567,11 +590,6 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 } - if (!zstr(tech_pvt->local_crypto_key) && sofia_test_flag(tech_pvt, TFLAG_SECURE)) { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=crypto:%s\n", tech_pvt->local_crypto_key); - //switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n"); - } - if (sofia_test_flag(tech_pvt, TFLAG_VIDEO)) { if (!tech_pvt->local_sdp_video_port) { sofia_glue_tech_choose_video_port(tech_pvt, 0); @@ -1261,7 +1279,9 @@ int sofia_glue_check_nat(sofia_profile_t *profile, const char *network_ip) { switch_assert(network_ip); - return (profile->extsipip && !switch_check_network_list_ip(network_ip, profile->local_network)); + return (profile->extsipip && + !switch_check_network_list_ip(network_ip, "loopback.auto") && + !switch_check_network_list_ip(network_ip, profile->local_network)); } int sofia_glue_transport_has_tls(const sofia_transport_t tp) @@ -2110,8 +2130,9 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) if (!from_display && !strcasecmp(tech_pvt->caller_profile->caller_id_name, "_undef_")) { from_str = switch_core_session_sprintf(session, "<%s>", use_from_str); } else { - from_str = switch_core_session_sprintf(session, "\"%s\" <%s>", from_display ? from_display : - tech_pvt->caller_profile->caller_id_name, use_from_str); + char *name = switch_core_session_strdup(session, from_display ? from_display : tech_pvt->caller_profile->caller_id_name); + check_decode(name, session); + from_str = switch_core_session_sprintf(session, "\"%s\" <%s>", name, use_from_str); } if (!(call_id = switch_channel_get_variable(channel, "sip_invite_call_id"))) { @@ -2643,9 +2664,7 @@ switch_status_t sofia_glue_tech_set_video_codec(private_object_t *tech_pvt, int switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Can't load codec?\n"); return SWITCH_STATUS_FALSE; } else { - int ms; tech_pvt->video_read_frame.rate = tech_pvt->video_rm_rate; - ms = tech_pvt->video_write_codec.implementation->microseconds_per_packet / 1000; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Set VIDEO Codec %s %s/%ld %d ms\n", switch_channel_get_name(tech_pvt->channel), tech_pvt->video_rm_encoding, tech_pvt->video_rm_rate, tech_pvt->video_codec_ms); tech_pvt->video_read_frame.codec = &tech_pvt->video_read_codec; @@ -2670,7 +2689,6 @@ switch_status_t sofia_glue_tech_set_video_codec(private_object_t *tech_pvt, int switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) { - int ms; switch_status_t status = SWITCH_STATUS_SUCCESS; int resetting = 0; @@ -2763,7 +2781,6 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) } tech_pvt->read_frame.rate = tech_pvt->rm_rate; - ms = tech_pvt->write_codec.implementation->microseconds_per_packet / 1000; if (!switch_core_codec_ready(&tech_pvt->read_codec)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Can't load codec?\n"); @@ -2846,7 +2863,6 @@ switch_status_t sofia_glue_build_crypto(private_object_t *tech_pvt, int index, s switch_status_t sofia_glue_add_crypto(private_object_t *tech_pvt, const char *key_str, switch_rtp_crypto_direction_t direction) { unsigned char key[SWITCH_RTP_MAX_CRYPTO_LEN]; - int index; switch_rtp_crypto_key_type_t type; char *p; @@ -2855,8 +2871,6 @@ switch_status_t sofia_glue_add_crypto(private_object_t *tech_pvt, const char *ke goto bad; } - index = atoi(key_str); - p = strchr(key_str, ' '); if (p && *p && *(p + 1)) { @@ -2903,7 +2917,6 @@ switch_status_t sofia_glue_add_crypto(private_object_t *tech_pvt, const char *ke switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_flag_t myflags) { - int bw, ms; const char *err = NULL; const char *val = NULL; switch_rtp_flag_t flags; @@ -2944,9 +2957,6 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f goto end; } - bw = tech_pvt->read_impl.bits_per_second; - ms = tech_pvt->read_impl.microseconds_per_packet; - if (myflags) { flags = myflags; } else if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) && @@ -4076,7 +4086,7 @@ void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp) sdp_session_t *sdp; private_object_t *tech_pvt = switch_core_session_get_private(session); sdp_attribute_t *attr; - int ptime = 0, dptime = 0, dmaxptime = 0, maxptime = 0; + int ptime = 0, dptime = 0; if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) { return; @@ -4097,8 +4107,6 @@ void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp) if (!strcasecmp(attr->a_name, "ptime")) { dptime = atoi(attr->a_value); - } else if (!strcasecmp(attr->a_name, "maxptime")) { - dmaxptime = atoi(attr->a_value); } } @@ -4106,7 +4114,7 @@ void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp) for (m = sdp->sdp_media; m; m = m->m_next) { ptime = dptime; - maxptime = dmaxptime; + //maxptime = dmaxptime; if (m->m_proto == sdp_proto_rtp) { sdp_rtpmap_t *map; @@ -4114,7 +4122,7 @@ void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp) if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) { ptime = atoi(attr->a_value); } else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) { - maxptime = atoi(attr->a_value); + //maxptime = atoi(attr->a_value); } } @@ -4784,7 +4792,6 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s } else if (m->m_type == sdp_media_video && m->m_port) { sdp_rtpmap_t *map; const char *rm_encoding; - int framerate = 0; const switch_codec_implementation_t *mimp = NULL; int vmatch = 0, i; switch_channel_set_variable(tech_pvt->channel, "video_possible", "true"); @@ -4804,7 +4811,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s for (attr = m->m_attributes; attr; attr = attr->a_next) { if (!strcasecmp(attr->a_name, "framerate") && attr->a_value) { - framerate = atoi(attr->a_value); + //framerate = atoi(attr->a_value); } if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value) { switch_channel_set_variable(tech_pvt->channel, "sip_remote_video_rtcp_port", attr->a_value); @@ -6234,7 +6241,7 @@ switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *use contact = sofia_glue_get_url_from_contact((char *) o_contact, 1); if (!zstr(network_ip) && sofia_glue_check_nat(profile, network_ip)) { char *ptr = NULL; - const char *transport_str = NULL; + //const char *transport_str = NULL; id = switch_mprintf("sip:%s@%s", user, profile->extsipip); @@ -6242,7 +6249,7 @@ switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *use if ((ptr = sofia_glue_find_parameter(o_contact, "transport="))) { sofia_transport_t transport = sofia_glue_str2transport(ptr); - transport_str = sofia_glue_transport2str(transport); + //transport_str = sofia_glue_transport2str(transport); switch (transport) { case SOFIA_TRANSPORT_TCP: contact_str = profile->tcp_public_contact; @@ -6450,7 +6457,7 @@ void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str) char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np) { char *contact_str = NULL; - const char *contact_host, *contact_user; + const char *contact_host;//, *contact_user; sip_contact_t const *contact; char *port; const char *display = "\"user\""; @@ -6478,7 +6485,7 @@ char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sof port = (char *) contact->m_url->url_port; contact_host = sip->sip_contact->m_url->url_host; - contact_user = sip->sip_contact->m_url->url_user; + //contact_user = sip->sip_contact->m_url->url_user; display = contact->m_display; diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index cbc45024e1..fdc3bd4d9a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -208,10 +208,10 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co if (!zstr(remote_ip) && sofia_glue_check_nat(profile, remote_ip)) { char *ptr = NULL; - const char *transport_str = NULL; + //const char *transport_str = NULL; if ((ptr = sofia_glue_find_parameter(dst->contact, "transport="))) { sofia_transport_t transport = sofia_glue_str2transport(ptr); - transport_str = sofia_glue_transport2str(transport); + //transport_str = sofia_glue_transport2str(transport); switch (transport) { case SOFIA_TRANSPORT_TCP: contact_str = profile->tcp_public_contact; @@ -2059,7 +2059,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, tagi_t tags[]) { - long exp_abs, exp_delta; + long exp_delta; char exp_delta_str[30] = ""; sip_to_t const *to; const char *from_user = NULL, *from_host = NULL; @@ -2080,7 +2080,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, int sent_reply = 0; sip_contact_t const *contact; const char *ipv6; - const char *contact_host, *contact_user; + const char *contact_user; sofia_nat_parse_t np = { { 0 } }; if (!sip) { @@ -2095,7 +2095,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, return; } - contact_host = sip->sip_contact->m_url->url_host; + //contact_host = sip->sip_contact->m_url->url_host; contact_user = sip->sip_contact->m_url->url_user; tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END()); @@ -2142,10 +2142,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, } } - if (exp_delta) { - exp_abs = (long) switch_epoch_time_now(NULL) + exp_delta; - } else { - exp_abs = 0; + if (!exp_delta) { sub_state = nua_substate_terminated; } @@ -2773,9 +2770,7 @@ void sofia_presence_handle_sip_i_message(int status, sip_to_t const *to = sip->sip_to; const char *to_user = NULL; const char *to_host = NULL; - sip_subject_t const *sip_subject = sip->sip_subject; sip_payload_t *payload = sip->sip_payload; - const char *subject = "n/a"; char *msg = NULL; if (sip->sip_content_type && sip->sip_content_type->c_subtype) { @@ -2802,14 +2797,9 @@ void sofia_presence_handle_sip_i_message(int status, msg = payload->pl_data; } - if (sip_subject) { - subject = sip_subject->g_value; - } - if (nh) { char hash_key[512]; private_object_t *tech_pvt; - switch_channel_t *channel; switch_event_t *event; char *to_addr; char *from_addr; @@ -2840,7 +2830,6 @@ void sofia_presence_handle_sip_i_message(int status, } if (sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT) && (tech_pvt = (private_object_t *) switch_core_hash_find(profile->chat_hash, hash_key))) { - channel = switch_core_session_get_channel(tech_pvt->session); if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index cac1d2f051..9130ceb569 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -852,7 +852,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand const char *reg_host = profile->reg_db_domain; const char *sub_host = profile->sub_domain; char contact_str[1024] = ""; - int nat_hack = 0; uint8_t multi_reg = 0, multi_reg_contact = 0, avoid_multi_reg = 0; uint8_t stale = 0, forbidden = 0; auth_res_t auth_res; @@ -863,7 +862,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand char network_ip[80]; char network_port_c[6]; char url_ip[80]; - char *register_gateway = NULL; int network_port; const char *reg_desc = "Registered"; const char *call_id = NULL; @@ -1094,8 +1092,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand avoid_multi_reg = 1; } - register_gateway = switch_event_get_header(*v_event, "sip-register-gateway"); - /* Allow us to force the SIP user to be something specific - needed if * we - for example - want to be able to ensure that the username a UA can * be contacted at is the same one that they used for authentication. @@ -1166,7 +1162,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand reg_desc = "Registered(AUTO-NAT)"; exptime = 30; } - nat_hack = 1; } else { char *p; switch_copy_string(contact_str, v_contact_str, sizeof(contact_str)); diff --git a/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c b/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c index c139c053b1..4ea128dd31 100644 --- a/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c +++ b/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c @@ -94,7 +94,6 @@ static void do_rotate(cdr_fd_t *fd) char date[80] = ""; switch_size_t retsize; char *p; - size_t len; close(fd->fd); fd->fd = -1; @@ -103,7 +102,7 @@ static void do_rotate(cdr_fd_t *fd) switch_time_exp_lt(&tm, switch_micro_time_now()); switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d-%H-%M-%S", &tm); - len = strlen(fd->path) + strlen(date) + 2; + p = switch_mprintf("%s.%s", fd->path, date); assert(p); switch_file_rename(fd->path, p, globals.pool); diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c index 0b96db82a1..7f2a7e8b3c 100644 --- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c +++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c @@ -160,7 +160,6 @@ static void do_rotate(cdr_fd_t *fd) char date[80] = ""; switch_size_t retsize; char *p; - size_t len; close(fd->fd); fd->fd = -1; @@ -169,7 +168,6 @@ static void do_rotate(cdr_fd_t *fd) switch_time_exp_lt(&tm, switch_micro_time_now()); switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d-%H-%M-%S", &tm); - len = strlen(fd->path) + strlen(date) + 2; p = switch_mprintf("%s.%s", fd->path, date); assert(p); switch_file_rename(fd->path, p, globals.pool); diff --git a/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c b/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c index 5c4d11e807..2c0b927c0f 100644 --- a/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c +++ b/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c @@ -51,7 +51,6 @@ static struct { char *address; char *bindings; uint32_t key_count; - char hostname[80]; switch_port_t port; switch_sockaddr_t *addr; switch_socket_t *udp_socket; @@ -282,7 +281,7 @@ static void event_handler(switch_event_t *event) case SWITCH_EVENT_LOG: return; default: - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Multicast-Sender", globals.hostname); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Multicast-Sender", switch_core_get_switchname()); if (switch_event_serialize(event, &packet, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { size_t len; char *buf; @@ -377,7 +376,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_event_multicast_load) switch_core_hash_init(&globals.event_hash, module_pool); switch_core_hash_init(&globals.peer_hash, module_pool); - gethostname(globals.hostname, sizeof(globals.hostname)); globals.key_count = 0; if (load_config() != SWITCH_STATUS_SUCCESS) { diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index f6a02623a7..4fbdcc8b96 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -990,19 +990,19 @@ SWITCH_STANDARD_API(event_sink_function) stream->write_function(stream, "\n"); while (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS) { - char *etype; + //char *etype; pevent = (switch_event_t *) pop; if (listener->format == EVENT_FORMAT_PLAIN) { - etype = "plain"; + //etype = "plain"; switch_event_serialize(pevent, &listener->ebuf, SWITCH_TRUE); stream->write_function(stream, "\n%s", listener->ebuf); } else if (listener->format == EVENT_FORMAT_JSON) { - etype = "json"; + //etype = "json"; switch_event_serialize_json(pevent, &listener->ebuf); } else { switch_xml_t xml; - etype = "xml"; + //etype = "xml"; if ((xml = switch_event_xmlize(pevent, SWITCH_VA_NONE))) { listener->ebuf = switch_xml_toxml(xml, SWITCH_FALSE); diff --git a/src/mod/event_handlers/mod_event_zmq/Makefile b/src/mod/event_handlers/mod_event_zmq/Makefile index 46d03f4bea..a724a63d1e 100644 --- a/src/mod/event_handlers/mod_event_zmq/Makefile +++ b/src/mod/event_handlers/mod_event_zmq/Makefile @@ -1,6 +1,6 @@ BASE=../../../.. -ZMQ=zeromq-2.1.3 +ZMQ=zeromq-2.1.4 ZMQ_BASEURL=http://download.zeromq.org diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c index 8d58667687..69f135d6bd 100644 --- a/src/mod/event_handlers/mod_snmp/subagent.c +++ b/src/mod/event_handlers/mod_snmp/subagent.c @@ -140,7 +140,7 @@ int channelList_load(netsnmp_cache *cache, void *vmagic) idx = 1; - sprintf(sql, "SELECT * FROM channels WHERE hostname='%s' ORDER BY created_epoch", switch_core_get_hostname()); + sprintf(sql, "SELECT * FROM channels WHERE hostname='%s' ORDER BY created_epoch", switch_core_get_switchname()); switch_cache_db_execute_sql_callback(dbh, sql, channelList_callback, NULL, NULL); switch_cache_db_release_db_handle(&dbh); @@ -237,14 +237,13 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio case SS_CURRENT_CALLS: { switch_cache_db_handle_t *dbh; - char sql[1024] = "", hostname[256] = ""; + char sql[1024] = ""; if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { return SNMP_ERR_GENERR; } - gethostname(hostname, sizeof(hostname)); - sprintf(sql, "SELECT COUNT(*) FROM calls WHERE hostname='%s'", hostname); + sprintf(sql, "SELECT COUNT(*) FROM calls WHERE hostname='%s'", switch_core_get_switchname()); switch_cache_db_execute_sql_callback(dbh, sql, sql_count_callback, &int_val, NULL); snmp_set_var_typed_integer(requests->requestvb, ASN_GAUGE, int_val); switch_cache_db_release_db_handle(&dbh); diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.c b/src/mod/formats/mod_local_stream/mod_local_stream.c index ea94bd1cd6..4f36e20128 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -758,7 +758,7 @@ SWITCH_STANDARD_API(start_local_stream_function) char *mycmd = NULL, *argv[8] = { 0 }; char *local_stream_name = NULL, *path = NULL, *timer_name = NULL; uint32_t prebuf = 1; - int rate = 8000, shuffle = 1, interval = 20; + int rate = 8000, interval = 20; uint8_t channels = 1; int argc = 0; char *cf = "local_stream.conf"; @@ -790,7 +790,7 @@ SWITCH_STANDARD_API(start_local_stream_function) } } - shuffle = argv[3] ? switch_true(argv[3]) : 1; + //shuffle = argv[3] ? switch_true(argv[3]) : 1; prebuf = argv[4] ? atoi(argv[4]) : DEFAULT_PREBUFFER_SIZE; if (argv[5]) { @@ -833,8 +833,8 @@ SWITCH_STANDARD_API(start_local_stream_function) if (tmp == 8000 || tmp == 16000 || tmp == 32000) { rate = tmp; } - } else if (!strcasecmp(var, "shuffle")) { - shuffle = switch_true(val); + //} else if (!strcasecmp(var, "shuffle")) { + //shuffle = switch_true(val); } else if (!strcasecmp(var, "prebuf")) { tmp = atoi(val); if (tmp > 0) { diff --git a/src/mod/formats/mod_sndfile/mod_sndfile.c b/src/mod/formats/mod_sndfile/mod_sndfile.c index d2c53f0ba1..5b011dccb2 100644 --- a/src/mod/formats/mod_sndfile/mod_sndfile.c +++ b/src/mod/formats/mod_sndfile/mod_sndfile.c @@ -339,7 +339,6 @@ static char **supported_formats; static switch_status_t setup_formats(void) { SF_FORMAT_INFO info; - SF_INFO sfinfo; char buffer[128]; int format, major_count, subtype_count, m, s; int len, x, skip; @@ -358,7 +357,7 @@ static switch_status_t setup_formats(void) sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT, &major_count, sizeof(int)); sf_command(NULL, SFC_GET_FORMAT_SUBTYPE_COUNT, &subtype_count, sizeof(int)); - sfinfo.channels = 1; + //sfinfo.channels = 1; len = ((major_count + (exlen + 2)) * sizeof(char *)); supported_formats = switch_core_permanent_alloc(len); @@ -402,7 +401,7 @@ static switch_status_t setup_formats(void) info.format = s; sf_command(NULL, SFC_GET_FORMAT_SUBTYPE, &info, sizeof(info)); format = (format & SF_FORMAT_TYPEMASK) | info.format; - sfinfo.format = format; + //sfinfo.format = format; /* if (sf_format_check(&sfinfo)) { switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, " %s\n", info.name); diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp index 7bc3d50b8a..0b0a17a225 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.cpp +++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp @@ -123,7 +123,6 @@ void Session::check_hangup_hook() void Session::do_hangup_hook() { if (hh && !mark) { - const char *err = NULL; int arg_count = 2; mark++; diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index e08ed5c253..7165efc483 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -1121,6 +1121,16 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE_get } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE_get() { + char * jresult ; + char *result = 0 ; + + result = (char *)("execute_on_tone_detect"); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CALL_TIMEOUT_VARIABLE_get() { char * jresult ; char *result = 0 ; @@ -4263,6 +4273,35 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_say_args_t_gender_get(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_args_t_ext_set(void * jarg1, char * jarg2) { + switch_say_args_t *arg1 = (switch_say_args_t *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_say_args_t *)jarg1; + arg2 = (char *)jarg2; + { + if (arg2) { + arg1->ext = (char const *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->ext, (const char *)arg2); + } else { + arg1->ext = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_say_args_t_ext_get(void * jarg1) { + char * jresult ; + switch_say_args_t *arg1 = (switch_say_args_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_say_args_t *)jarg1; + result = (char *) ((arg1)->ext); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_say_args_t() { void * jresult ; switch_say_args_t *result = 0 ; @@ -10331,6 +10370,11 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_persistant_execute_trans(void } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_set_signal_handlers() { + switch_core_set_signal_handlers(); +} + + SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_core_debug_level() { unsigned long jresult ; uint32_t result; @@ -10436,6 +10480,79 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_expire_registration(int jarg1) { } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_say_file_handle_get_variable(void * jarg1, char * jarg2) { + char * jresult ; + switch_say_file_handle_t *arg1 = (switch_say_file_handle_t *) 0 ; + char *arg2 = (char *) 0 ; + char *result = 0 ; + + arg1 = (switch_say_file_handle_t *)jarg1; + arg2 = (char *)jarg2; + result = (char *)switch_say_file_handle_get_variable(arg1,(char const *)arg2); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_say_file_handle_get_path(void * jarg1) { + char * jresult ; + switch_say_file_handle_t *arg1 = (switch_say_file_handle_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_say_file_handle_t *)jarg1; + result = (char *)switch_say_file_handle_get_path(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_say_file_handle_detach_path(void * jarg1) { + char * jresult ; + switch_say_file_handle_t *arg1 = (switch_say_file_handle_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_say_file_handle_t *)jarg1; + result = (char *)switch_say_file_handle_detach_path(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_file_handle_destroy(void * jarg1) { + switch_say_file_handle_t **arg1 = (switch_say_file_handle_t **) 0 ; + + arg1 = (switch_say_file_handle_t **)jarg1; + switch_say_file_handle_destroy(arg1); +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_say_file_handle_create(void * jarg1, char * jarg2, void * jarg3) { + int jresult ; + switch_say_file_handle_t **arg1 = (switch_say_file_handle_t **) 0 ; + char *arg2 = (char *) 0 ; + switch_event_t **arg3 = (switch_event_t **) 0 ; + switch_status_t result; + + arg1 = (switch_say_file_handle_t **)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_event_t **)jarg3; + result = (switch_status_t)switch_say_file_handle_create(arg1,(char const *)arg2,arg3); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_file(void * jarg1, char * jarg2) { + switch_say_file_handle_t *arg1 = (switch_say_file_handle_t *) 0 ; + char *arg2 = (char *) 0 ; + void *arg3 = 0 ; + + arg1 = (switch_say_file_handle_t *)jarg1; + arg2 = (char *)jarg2; + switch_say_file(arg1,(char const *)arg2,arg3); +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_module_name_set(void * jarg1, char * jarg2) { switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; char *arg2 = (char *) 0 ; @@ -12246,6 +12363,18 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_clean_string(char * jarg1) { } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_clean_name_string(char * jarg1) { + char * jresult ; + char *arg1 = (char *) 0 ; + char *result = 0 ; + + arg1 = (char *)jarg1; + result = (char *)switch_clean_name_string(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_safe_strdup(char * jarg1) { char * jresult ; char *arg1 = (char *) 0 ; @@ -19356,6 +19485,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_say_interface_say_function_get(void } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_interface_say_string_function_set(void * jarg1, void * jarg2) { + switch_say_interface *arg1 = (switch_say_interface *) 0 ; + switch_say_string_callback_t arg2 = (switch_say_string_callback_t) 0 ; + + arg1 = (switch_say_interface *)jarg1; + arg2 = (switch_say_string_callback_t)jarg2; + if (arg1) (arg1)->say_string_function = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_say_interface_say_string_function_get(void * jarg1) { + void * jresult ; + switch_say_interface *arg1 = (switch_say_interface *) 0 ; + switch_say_string_callback_t result; + + arg1 = (switch_say_interface *)jarg1; + result = (switch_say_string_callback_t) ((arg1)->say_string_function); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_interface_rwlock_set(void * jarg1, void * jarg2) { switch_say_interface *arg1 = (switch_say_interface *) 0 ; switch_thread_rwlock_t *arg2 = (switch_thread_rwlock_t *) 0 ; @@ -23972,6 +24123,20 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_mark_hold(void * jarg1, int ja } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_execute_on(void * jarg1, char * jarg2) { + int jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_channel_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_channel_execute_on(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_buffer_create(void * jarg1, void * jarg2, void * jarg3) { int jresult ; switch_memory_pool_t *arg1 = (switch_memory_pool_t *) 0 ; @@ -25072,7 +25237,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_json(void * jarg1, char * } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, char jarg2, char jarg3, char jarg4, void * jarg5, void * jarg6) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, char jarg2, char jarg3, char jarg4, void * jarg5, void * jarg6, int jarg7) { int jresult ; char *arg1 = (char *) 0 ; char arg2 ; @@ -25080,6 +25245,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, cha char arg4 ; switch_event_t **arg5 = (switch_event_t **) 0 ; char **arg6 = (char **) 0 ; + switch_bool_t arg7 ; switch_status_t result; arg1 = (char *)jarg1; @@ -25088,7 +25254,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, cha arg4 = (char)jarg4; arg5 = (switch_event_t **)jarg5; arg6 = (char **)jarg6; - result = (switch_status_t)switch_event_create_brackets(arg1,arg2,arg3,arg4,arg5,arg6); + arg7 = (switch_bool_t)jarg7; + result = (switch_status_t)switch_event_create_brackets(arg1,arg2,arg3,arg4,arg5,arg6,arg7); jresult = result; return jresult; } @@ -27618,6 +27785,34 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_say(void * jarg1, char * jarg2, cha } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_say_string(void * jarg1, char * jarg2, char * jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7, char * jarg8, void * jarg9) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + char *arg4 = (char *) 0 ; + char *arg5 = (char *) 0 ; + char *arg6 = (char *) 0 ; + char *arg7 = (char *) 0 ; + char *arg8 = (char *) 0 ; + char **arg9 = (char **) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + arg4 = (char *)jarg4; + arg5 = (char *)jarg5; + arg6 = (char *)jarg6; + arg7 = (char *)jarg7; + arg8 = (char *)jarg8; + arg9 = (char **)jarg9; + result = (switch_status_t)switch_ivr_say_string(arg1,(char const *)arg2,(char const *)arg3,(char const *)arg4,(char const *)arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,arg9); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_get_say_method_by_name(char * jarg1) { int jresult ; char *arg1 = (char *) 0 ; @@ -29723,6 +29918,28 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_is_switch_xml_root_t_get(void * jar } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_xml_refs_set(void * jarg1, unsigned long jarg2) { + switch_xml *arg1 = (switch_xml *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_xml *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->refs = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_xml_refs_get(void * jarg1) { + unsigned long jresult ; + switch_xml *arg1 = (switch_xml *) 0 ; + uint32_t result; + + arg1 = (switch_xml *)jarg1; + result = (uint32_t) ((arg1)->refs); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_xml() { void * jresult ; switch_xml *result = 0 ; diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index 33c18dab84..c0402e142d 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -12688,6 +12688,18 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_clean_string(char * jarg1) { } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_clean_name_string(char * jarg1) { + char * jresult ; + char *arg1 = (char *) 0 ; + char *result = 0 ; + + arg1 = (char *)jarg1; + result = (char *)switch_clean_name_string(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_safe_strdup(char * jarg1) { char * jresult ; char *arg1 = (char *) 0 ; @@ -25903,7 +25915,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_json(void * jarg1, char * } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, char jarg2, char jarg3, char jarg4, void * jarg5, void * jarg6) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, char jarg2, char jarg3, char jarg4, void * jarg5, void * jarg6, int jarg7) { int jresult ; char *arg1 = (char *) 0 ; char arg2 ; @@ -25911,6 +25923,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, cha char arg4 ; switch_event_t **arg5 = (switch_event_t **) 0 ; char **arg6 = (char **) 0 ; + switch_bool_t arg7 ; switch_status_t result; arg1 = (char *)jarg1; @@ -25919,7 +25932,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, cha arg4 = (char)jarg4; arg5 = (switch_event_t **)jarg5; arg6 = (char **)jarg6; - result = (switch_status_t)switch_event_create_brackets(arg1,arg2,arg3,arg4,arg5,arg6); + arg7 = (switch_bool_t)jarg7; + result = (switch_status_t)switch_event_create_brackets(arg1,arg2,arg3,arg4,arg5,arg6,arg7); jresult = result; return jresult; } diff --git a/src/mod/languages/mod_managed/managed/swig.2010.cs b/src/mod/languages/mod_managed/managed/swig.2010.cs index 42ae909ebf..6d8c374d44 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -2422,6 +2422,10 @@ public class freeswitch { return ret; } + public static void switch_core_set_signal_handlers() { + freeswitchPINVOKE.switch_core_set_signal_handlers(); + } + public static uint switch_core_debug_level() { uint ret = freeswitchPINVOKE.switch_core_debug_level(); return ret; @@ -2461,6 +2465,34 @@ public class freeswitch { return ret; } + public static string switch_say_file_handle_get_variable(SWIGTYPE_p_switch_say_file_handle sh, string var) { + string ret = freeswitchPINVOKE.switch_say_file_handle_get_variable(SWIGTYPE_p_switch_say_file_handle.getCPtr(sh), var); + return ret; + } + + public static string switch_say_file_handle_get_path(SWIGTYPE_p_switch_say_file_handle sh) { + string ret = freeswitchPINVOKE.switch_say_file_handle_get_path(SWIGTYPE_p_switch_say_file_handle.getCPtr(sh)); + return ret; + } + + public static string switch_say_file_handle_detach_path(SWIGTYPE_p_switch_say_file_handle sh) { + string ret = freeswitchPINVOKE.switch_say_file_handle_detach_path(SWIGTYPE_p_switch_say_file_handle.getCPtr(sh)); + return ret; + } + + public static void switch_say_file_handle_destroy(SWIGTYPE_p_p_switch_say_file_handle sh) { + freeswitchPINVOKE.switch_say_file_handle_destroy(SWIGTYPE_p_p_switch_say_file_handle.getCPtr(sh)); + } + + public static switch_status_t switch_say_file_handle_create(SWIGTYPE_p_p_switch_say_file_handle sh, string ext, SWIGTYPE_p_p_switch_event var_event) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_say_file_handle_create(SWIGTYPE_p_p_switch_say_file_handle.getCPtr(sh), ext, SWIGTYPE_p_p_switch_event.getCPtr(var_event)); + return ret; + } + + public static void switch_say_file(SWIGTYPE_p_switch_say_file_handle sh, string fmt) { + freeswitchPINVOKE.switch_say_file(SWIGTYPE_p_switch_say_file_handle.getCPtr(sh), fmt); + } + public static switch_status_t switch_loadable_module_init(switch_bool_t autoload) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_init((int)autoload); return ret; @@ -2923,6 +2955,11 @@ public class freeswitch { return ret; } + public static string switch_clean_name_string(string s) { + string ret = freeswitchPINVOKE.switch_clean_name_string(s); + return ret; + } + public static string switch_safe_strdup(string it) { string ret = freeswitchPINVOKE.switch_safe_strdup(it); return ret; @@ -3723,6 +3760,11 @@ public class freeswitch { freeswitchPINVOKE.switch_channel_mark_hold(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)on); } + public static switch_status_t switch_channel_execute_on(SWIGTYPE_p_switch_channel channel, string variable_prefix) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_execute_on(SWIGTYPE_p_switch_channel.getCPtr(channel), variable_prefix); + return ret; + } + public static switch_status_t switch_buffer_create(SWIGTYPE_p_apr_pool_t pool, SWIGTYPE_p_p_switch_buffer buffer, SWIGTYPE_p_switch_size_t max_len) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_buffer_create(SWIGTYPE_p_apr_pool_t.getCPtr(pool), SWIGTYPE_p_p_switch_buffer.getCPtr(buffer), SWIGTYPE_p_switch_size_t.getCPtr(max_len)); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); @@ -3943,8 +3985,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_event_create_brackets(string data, char a, char b, char c, SWIGTYPE_p_p_switch_event arg4, ref string new_data) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_create_brackets(data, a, b, c, SWIGTYPE_p_p_switch_event.getCPtr(arg4), ref new_data); + public static switch_status_t switch_event_create_brackets(string data, char a, char b, char c, SWIGTYPE_p_p_switch_event arg4, ref string new_data, switch_bool_t dup) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_create_brackets(data, a, b, c, SWIGTYPE_p_p_switch_event.getCPtr(arg4), ref new_data, (int)dup); return ret; } @@ -4519,6 +4561,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_ivr_say_string(SWIGTYPE_p_switch_core_session session, string lang, string ext, string tosay, string module_name, string say_type, string say_method, string say_gender, ref string rstr) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_say_string(SWIGTYPE_p_switch_core_session.getCPtr(session), lang, ext, tosay, module_name, say_type, say_method, say_gender, ref rstr); + return ret; + } + public static switch_say_method_t switch_ivr_get_say_method_by_name(string name) { switch_say_method_t ret = (switch_say_method_t)freeswitchPINVOKE.switch_ivr_get_say_method_by_name(name); return ret; @@ -5535,6 +5582,7 @@ public class freeswitch { public static readonly string SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE_get(); + public static readonly string SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE_get(); public static readonly string SWITCH_CALL_TIMEOUT_VARIABLE = freeswitchPINVOKE.SWITCH_CALL_TIMEOUT_VARIABLE_get(); public static readonly string SWITCH_HOLDING_UUID_VARIABLE = freeswitchPINVOKE.SWITCH_HOLDING_UUID_VARIABLE_get(); public static readonly string SWITCH_SOFT_HOLDING_UUID_VARIABLE = freeswitchPINVOKE.SWITCH_SOFT_HOLDING_UUID_VARIABLE_get(); @@ -6086,6 +6134,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE_get")] public static extern string SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE_get")] + public static extern string SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CALL_TIMEOUT_VARIABLE_get")] public static extern string SWITCH_CALL_TIMEOUT_VARIABLE_get(); @@ -6920,6 +6971,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_say_args_t_gender_get")] public static extern int switch_say_args_t_gender_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_args_t_ext_set")] + public static extern void switch_say_args_t_ext_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_args_t_ext_get")] + public static extern string switch_say_args_t_ext_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_say_args_t")] public static extern IntPtr new_switch_say_args_t(); @@ -8336,6 +8393,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_persistant_execute_trans")] public static extern int switch_cache_db_persistant_execute_trans(HandleRef jarg1, string jarg2, uint jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_set_signal_handlers")] + public static extern void switch_core_set_signal_handlers(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_debug_level")] public static extern uint switch_core_debug_level(); @@ -8360,6 +8420,24 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_expire_registration")] public static extern int switch_core_expire_registration(int jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_get_variable")] + public static extern string switch_say_file_handle_get_variable(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_get_path")] + public static extern string switch_say_file_handle_get_path(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_detach_path")] + public static extern string switch_say_file_handle_detach_path(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_destroy")] + public static extern void switch_say_file_handle_destroy(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_create")] + public static extern int switch_say_file_handle_create(HandleRef jarg1, string jarg2, HandleRef jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file")] + public static extern void switch_say_file(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_module_name_set")] public static extern void switch_loadable_module_interface_module_name_set(HandleRef jarg1, string jarg2); @@ -8768,6 +8846,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_clean_string")] public static extern string switch_clean_string(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_clean_name_string")] + public static extern string switch_clean_name_string(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_safe_strdup")] public static extern string switch_safe_strdup(string jarg1); @@ -10550,6 +10631,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_say_interface_say_function_get")] public static extern IntPtr switch_say_interface_say_function_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_interface_say_string_function_set")] + public static extern void switch_say_interface_say_string_function_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_interface_say_string_function_get")] + public static extern IntPtr switch_say_interface_say_string_function_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_interface_rwlock_set")] public static extern void switch_say_interface_rwlock_set(HandleRef jarg1, HandleRef jarg2); @@ -11708,6 +11795,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_mark_hold")] public static extern void switch_channel_mark_hold(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_execute_on")] + public static extern int switch_channel_execute_on(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_buffer_create")] public static extern int switch_buffer_create(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); @@ -11949,7 +12039,7 @@ class freeswitchPINVOKE { public static extern int switch_event_create_json(HandleRef jarg1, string jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_event_create_brackets")] - public static extern int switch_event_create_brackets(string jarg1, char jarg2, char jarg3, char jarg4, HandleRef jarg5, ref string jarg6); + public static extern int switch_event_create_brackets(string jarg1, char jarg2, char jarg3, char jarg4, HandleRef jarg5, ref string jarg6, int jarg7); [DllImport("mod_managed", EntryPoint="CSharp_switch_event_running")] public static extern int switch_event_running(); @@ -12455,6 +12545,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_say")] public static extern int switch_ivr_say(HandleRef jarg1, string jarg2, string jarg3, string jarg4, string jarg5, string jarg6, HandleRef jarg7); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_say_string")] + public static extern int switch_ivr_say_string(HandleRef jarg1, string jarg2, string jarg3, string jarg4, string jarg5, string jarg6, string jarg7, string jarg8, ref string jarg9); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_get_say_method_by_name")] public static extern int switch_ivr_get_say_method_by_name(string jarg1); @@ -12938,6 +13031,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_is_switch_xml_root_t_get")] public static extern int switch_xml_is_switch_xml_root_t_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_refs_set")] + public static extern void switch_xml_refs_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_refs_get")] + public static extern uint switch_xml_refs_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_xml")] public static extern IntPtr new_switch_xml(); @@ -15309,6 +15408,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_switch_input_args_t__switch_status_t { private HandleRef swigCPtr; @@ -17889,6 +18018,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_p_switch_say_file_handle { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_switch_say_file_handle(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_switch_say_file_handle() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_say_file_handle obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_p_switch_xml { private HandleRef swigCPtr; @@ -18909,6 +19068,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_switch_say_file_handle { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_switch_say_file_handle(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_switch_say_file_handle() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_switch_say_file_handle obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_switch_size_t { private HandleRef swigCPtr; @@ -23123,7 +23312,8 @@ namespace FreeSWITCH.Native { SCF_VERBOSE_EVENTS = (1 << 11), SCF_USE_WIN32_MONOTONIC = (1 << 12), SCF_AUTO_SCHEMAS = (1 << 13), - SCF_MINIMAL = (1 << 14) + SCF_MINIMAL = (1 << 14), + SCF_USE_NAT_MAPPING = (1 << 15) } } @@ -28791,7 +28981,7 @@ namespace FreeSWITCH.Native { SWITCH_RTP_FLAG_NOBLOCK = (1 << 0), SWITCH_RTP_FLAG_IO = (1 << 1), SWITCH_RTP_FLAG_USE_TIMER = (1 << 2), - SWITCH_RTP_FLAG_TIMER_RECLOCK = (1 << 3), + SWITCH_RTP_FLAG_RTCP_PASSTHRU = (1 << 3), SWITCH_RTP_FLAG_SECURE_SEND = (1 << 4), SWITCH_RTP_FLAG_SECURE_RECV = (1 << 5), SWITCH_RTP_FLAG_AUTOADJ = (1 << 6), @@ -28818,8 +29008,7 @@ namespace FreeSWITCH.Native { SWITCH_RTP_FLAG_DEBUG_RTP_READ = (1 << 27), SWITCH_RTP_FLAG_DEBUG_RTP_WRITE = (1 << 28), SWITCH_RTP_FLAG_VIDEO = (1 << 29), - SWITCH_RTP_FLAG_ENABLE_RTCP = (1 << 30), - SWITCH_RTP_FLAG_RTCP_PASSTHRU = (1 << 31) + SWITCH_RTP_FLAG_ENABLE_RTCP = (1 << 30) } } @@ -29291,6 +29480,16 @@ public class switch_say_args_t : IDisposable { } } + public string ext { + set { + freeswitchPINVOKE.switch_say_args_t_ext_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_say_args_t_ext_get(swigCPtr); + return ret; + } + } + public switch_say_args_t() : this(freeswitchPINVOKE.new_switch_say_args_t(), true) { } @@ -29378,6 +29577,17 @@ public class switch_say_interface : IDisposable { } } + public SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t say_string_function { + set { + freeswitchPINVOKE.switch_say_interface_say_string_function_set(swigCPtr, SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_say_interface_say_string_function_get(swigCPtr); + SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t(cPtr, false); + return ret; + } + } + public SWIGTYPE_p_switch_thread_rwlock_t rwlock { set { freeswitchPINVOKE.switch_say_interface_rwlock_set(swigCPtr, SWIGTYPE_p_switch_thread_rwlock_t.getCPtr(value)); @@ -31672,6 +31882,16 @@ public class switch_xml : IDisposable { } } + public uint refs { + set { + freeswitchPINVOKE.switch_xml_refs_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_xml_refs_get(swigCPtr); + return ret; + } + } + public switch_xml() : this(freeswitchPINVOKE.new_switch_xml(), true) { } diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 400acef378..497630fd26 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -2945,6 +2945,11 @@ public class freeswitch { return ret; } + public static string switch_clean_name_string(string s) { + string ret = freeswitchPINVOKE.switch_clean_name_string(s); + return ret; + } + public static string switch_safe_strdup(string it) { string ret = freeswitchPINVOKE.switch_safe_strdup(it); return ret; @@ -3970,8 +3975,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_event_create_brackets(string data, char a, char b, char c, SWIGTYPE_p_p_switch_event arg4, ref string new_data) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_create_brackets(data, a, b, c, SWIGTYPE_p_p_switch_event.getCPtr(arg4), ref new_data); + public static switch_status_t switch_event_create_brackets(string data, char a, char b, char c, SWIGTYPE_p_p_switch_event arg4, ref string new_data, switch_bool_t dup) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_create_brackets(data, a, b, c, SWIGTYPE_p_p_switch_event.getCPtr(arg4), ref new_data, (int)dup); return ret; } @@ -8827,6 +8832,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_clean_string")] public static extern string switch_clean_string(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_clean_name_string")] + public static extern string switch_clean_name_string(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_safe_strdup")] public static extern string switch_safe_strdup(string jarg1); @@ -12017,7 +12025,7 @@ class freeswitchPINVOKE { public static extern int switch_event_create_json(HandleRef jarg1, string jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_event_create_brackets")] - public static extern int switch_event_create_brackets(string jarg1, char jarg2, char jarg3, char jarg4, HandleRef jarg5, ref string jarg6); + public static extern int switch_event_create_brackets(string jarg1, char jarg2, char jarg3, char jarg4, HandleRef jarg5, ref string jarg6, int jarg7); [DllImport("mod_managed", EntryPoint="CSharp_switch_event_running")] public static extern int switch_event_running(); diff --git a/src/mod/languages/mod_python/mod_python.c b/src/mod/languages/mod_python/mod_python.c index bcaebd8856..78caf3b04f 100644 --- a/src/mod/languages/mod_python/mod_python.c +++ b/src/mod/languages/mod_python/mod_python.c @@ -77,13 +77,11 @@ static void eval_some_python(const char *funcname, char *args, switch_core_sessi char *dupargs = NULL; char *argv[2] = { 0 }; int argc; - int lead = 0; char *script = NULL; PyObject *module = NULL, *sp = NULL, *stp = NULL, *eve = NULL; PyObject *function = NULL; PyObject *arg = NULL; PyObject *result = NULL; - switch_channel_t *channel = NULL; char *p; if (str) { @@ -105,8 +103,6 @@ static void eval_some_python(const char *funcname, char *args, switch_core_sessi script = strdup(switch_str_nil(argv[0])); - lead = 1; - if ((p = strstr(script, "::"))) { *p = '\0'; p += 2; @@ -157,7 +153,6 @@ static void eval_some_python(const char *funcname, char *args, switch_core_sessi } if (session) { - channel = switch_core_session_get_channel(session); sp = mod_python_conjure_session(module, session); } diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c index 1a57f5f2ae..7341a2b1e1 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c @@ -766,11 +766,8 @@ static JSBool dtmf_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * { switch_dtmf_t *dtmf; int32 duration = switch_core_default_dtmf_duration(0); - char *ename; - if (argc > 0) { - ename = JS_GetStringBytes(JS_ValueToString(cx, argv[0])); - } else { + if (argc <= 0) { eval_some_js("~throw new Error(\"Invalid Args\");", cx, obj, rval); return JS_FALSE; } @@ -1911,7 +1908,6 @@ static JSBool session_speak(JSContext * cx, JSObject * obj, uintN argc, jsval * char *tts_name = NULL; char *voice_name = NULL; char *text = NULL; - switch_codec_t *codec; void *bp = NULL; int len = 0; struct input_callback_state cb_state = { 0 }; @@ -1979,7 +1975,6 @@ static JSBool session_speak(JSContext * cx, JSObject * obj, uintN argc, jsval * } } - codec = switch_core_session_get_read_codec(jss->session); cb_state.ret = BOOLEAN_TO_JSVAL(JS_FALSE); cb_state.saveDepth = JS_SuspendRequest(cx); args.input_callback = dtmf_func; @@ -2281,13 +2276,12 @@ static JSBool session_detach(JSContext * cx, JSObject * obj, uintN argc, jsval * static JSBool session_execute(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval) { JSBool retval = JS_FALSE; - switch_channel_t *channel; + struct js_session *jss = JS_GetPrivate(cx, obj); jsval ret = JS_TRUE; METHOD_SANITY_CHECK(); - channel = switch_core_session_get_channel(jss->session); /* you can execute some apps before you answer CHANNEL_SANITY_CHECK(); */ if (argc > 0) { @@ -3498,7 +3492,6 @@ static JSBool js_bridge(JSContext * cx, JSObject * obj, uintN argc, jsval * argv struct js_session *jss_a = NULL, *jss_b = NULL; JSObject *session_obj_a = NULL, *session_obj_b = NULL; void *bp = NULL; - int len = 0; switch_input_callback_function_t dtmf_func = NULL; struct input_callback_state cb_state = { 0 }; JSFunction *function; @@ -3548,7 +3541,6 @@ static JSBool js_bridge(JSContext * cx, JSObject * obj, uintN argc, jsval * argv cb_state.session_state = jss_a; dtmf_func = js_collect_input_callback; bp = &cb_state; - len = sizeof(cb_state); } } diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey_odbc.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey_odbc.c index e60d8ce793..63709a4d8f 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey_odbc.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey_odbc.c @@ -513,12 +513,12 @@ static JSBool odbc_setProperty(JSContext * cx, JSObject * obj, jsval id, jsval * static JSBool odbc_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp) { - int param; + //int param; char *name = JS_GetStringBytes(JS_ValueToString(cx, id)); /* numbers are our props anything else is a method */ if (name[0] >= 48 && name[0] <= 57) { - param = atoi(name); + // param = atoi(name); } else { return JS_TRUE; } diff --git a/src/mod/say/mod_say_de/mod_say_de.c b/src/mod/say/mod_say_de/mod_say_de.c index 7212a5f581..667f3f6669 100644 --- a/src/mod/say/mod_say_de/mod_say_de.c +++ b/src/mod/say/mod_say_de/mod_say_de.c @@ -40,6 +40,7 @@ * Anthony Minessale II * Michael B. Murdock * Daniel Swarbrick + * Christian Benke * * mod_say_de.c -- Say for German * @@ -80,17 +81,27 @@ SWITCH_MODULE_DEFINITION(mod_say_de, mod_say_de_load, NULL, NULL); return SWITCH_STATUS_FALSE; \ }} \ -static switch_status_t play_group(switch_say_method_t method, int a, int b, int c, char *what, switch_core_session_t *session, switch_input_args_t *args) +static switch_status_t play_group(switch_say_method_t method, switch_say_gender_t gender, int a, int b, int c, char *what, switch_core_session_t *session, switch_input_args_t *args) { if (a) { - say_file("digits/%d.wav", a); - say_file("digits/hundred.wav"); + /*german nominativ for "one" in numbers like 21, 171, 4591 is flexed("ein" instead of "eins"), 2-9 are not*/ + if ( a == 1 ) { + say_file("digits/s-%d.wav"); + } else { + say_file("digits/%d.wav", a); + } + say_file("digits/hundred.wav"); } if (b) { if (b > 1) { - say_file("digits/%d.wav", c); + /*german nominativ for "one" in numbers like 21, 171, 4591 is flexed, 2-9 are not*/ + if ( c == 1 ) { + say_file("digits/s-%d.wav"); + } else { + say_file("digits/%d.wav", c); + } say_file("currency/and.wav"); if (method == SSM_COUNTED) { say_file("digits/h-%d0.wav", b); @@ -111,7 +122,15 @@ static switch_status_t play_group(switch_say_method_t method, int a, int b, int if (method == SSM_COUNTED) { say_file("digits/h-%d.wav", c); } else { - say_file("digits/%d.wav", c); + /*"one" used as an article is feminine or masculine in german, e.g. voicemail-message is feminine + only applies to the likes of 1, 101, 1001 etc.*/ + if ( b == 0 && c == 1 && gender == SSG_FEMININE ) { + say_file("digits/%d_f.wav", c); + } else if ( b == 0 && c == 1 && what ) { + say_file("digits/s-%d.wav"); + } else { + say_file("digits/%d.wav", c); + } } } @@ -150,7 +169,7 @@ static switch_status_t de_say_general_count(switch_core_session_t *session, char in = atoi(tosay); - if (in != 0) { + if (in != 0) { /*fills the places-array with tosay(resp. in) from tail to front e.g. 84371 would be places[|1|7|3|4|8|0|0|0|], up to 1 billion minus 1*/ for (x = 8; x >= 0; x--) { int num = (int) pow(10, x); if ((places[(uint32_t) x] = in / num)) { @@ -161,13 +180,13 @@ static switch_status_t de_say_general_count(switch_core_session_t *session, char switch (say_args->method) { case SSM_COUNTED: case SSM_PRONOUNCED: - if ((status = play_group(SSM_PRONOUNCED, places[8], places[7], places[6], "digits/million.wav", session, args)) != SWITCH_STATUS_SUCCESS) { + if ((status = play_group(SSM_PRONOUNCED, say_args->gender, places[8], places[7], places[6], "digits/million.wav", session, args)) != SWITCH_STATUS_SUCCESS) { return status; } - if ((status = play_group(SSM_PRONOUNCED, places[5], places[4], places[3], "digits/thousand.wav", session, args)) != SWITCH_STATUS_SUCCESS) { + if ((status = play_group(SSM_PRONOUNCED, say_args->gender, places[5], places[4], places[3], "digits/thousand.wav", session, args)) != SWITCH_STATUS_SUCCESS) { return status; } - if ((status = play_group(say_args->method, places[2], places[1], places[0], NULL, session, args)) != SWITCH_STATUS_SUCCESS) { + if ((status = play_group(say_args->method, say_args->gender, places[2], places[1], places[0], NULL, session, args)) != SWITCH_STATUS_SUCCESS) { return status; } break; diff --git a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c index 30889cad4c..e49d1d958e 100644 --- a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c +++ b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c @@ -239,6 +239,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) #endif int wrote; wrote = write(fd, xml_text, (unsigned) strlen(xml_text)); + wrote++; close(fd); fd = -1; } else { @@ -393,6 +394,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) #endif int wrote; wrote = write(fd, xml_text, (unsigned) strlen(xml_text)); + wrote++; close(fd); fd = -1; } else { diff --git a/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c b/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c index bc143d7e48..6aa899babb 100644 --- a/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c +++ b/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c @@ -155,7 +155,7 @@ static switch_xml_t xml_url_fetch(const char *section, const char *tag_name, con char *uri = NULL; char *dynamic_url = NULL; - gethostname(hostname, sizeof(hostname)); + strncpy(hostname, switch_core_get_switchname(), sizeof(hostname)); if (!binding) { return NULL; diff --git a/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c b/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c index e58377ef5a..1ac0d38889 100644 --- a/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c +++ b/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c @@ -50,7 +50,8 @@ typedef enum { XML_LDAP_CONFIG = 0, XML_LDAP_DIRECTORY, XML_LDAP_DIALPLAN, - XML_LDAP_PHRASE + XML_LDAP_PHRASE, + XML_LDAP_LANGUAGE } xml_ldap_query_type_t; SWITCH_MODULE_LOAD_FUNCTION(mod_xml_ldap_load); @@ -247,6 +248,8 @@ static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, c query_type = XML_LDAP_DIALPLAN; } else if (!strcmp(section, "phrases")) { query_type = XML_LDAP_PHRASE; + } else if (!strcmp(section, "languages")) { + query_type = XML_LDAP_LANGUAGE; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid section\n"); return NULL; @@ -269,6 +272,7 @@ static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, c case XML_LDAP_DIALPLAN: case XML_LDAP_PHRASE: + case XML_LDAP_LANGUAGE: break; } } @@ -326,6 +330,7 @@ static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, c break; case XML_LDAP_PHRASE: + case XML_LDAP_LANGUAGE: break; } } else { diff --git a/src/switch.c b/src/switch.c index 7d4d1a8217..401829cf82 100644 --- a/src/switch.c +++ b/src/switch.c @@ -776,10 +776,10 @@ int main(int argc, char *argv[]) #if defined(HAVE_SETRLIMIT) && !defined(__sun) if (!waste && !(flags & SCF_VG)) { - int x; + //int x; memset(&rlp, 0, sizeof(rlp)); - x = getrlimit(RLIMIT_STACK, &rlp); + getrlimit(RLIMIT_STACK, &rlp); if (rlp.rlim_max > SWITCH_THREAD_STACKSIZE) { char buf[1024] = ""; diff --git a/src/switch_channel.c b/src/switch_channel.c index bc8daabbc6..37ece108a4 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -634,6 +634,10 @@ SWITCH_DECLARE(void) switch_channel_mark_hold(switch_channel_t *channel, switch_ { switch_event_t *event; + if (!!on == !!switch_channel_test_flag(channel, CF_LEG_HOLDING)) { + return; + } + if (on) { switch_channel_set_flag(channel, CF_LEG_HOLDING); } else { @@ -1189,16 +1193,12 @@ SWITCH_DECLARE(switch_bool_t) switch_channel_clear_flag_partner(switch_channel_t SWITCH_DECLARE(void) switch_channel_wait_for_state(switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state) { - switch_channel_state_t state, mystate; + switch_assert(channel); + for (;;) { - if (other_channel) { - state = switch_channel_get_running_state(other_channel); - } - mystate = switch_channel_get_running_state(channel); - if ((channel->state == channel->running_state && channel->running_state == want_state) || - (other_channel && other_channel->state >= CS_HANGUP) || channel->state >= CS_HANGUP) { + (other_channel && switch_channel_down(other_channel)) || switch_channel_down(channel)) { break; } switch_yield(20000); @@ -1208,11 +1208,10 @@ SWITCH_DECLARE(void) switch_channel_wait_for_state(switch_channel_t *channel, sw SWITCH_DECLARE(void) switch_channel_wait_for_state_timeout(switch_channel_t *channel, switch_channel_state_t want_state, uint32_t timeout) { - switch_channel_state_t state; + uint32_t count = 0; for (;;) { - state = switch_channel_get_running_state(channel); if ((channel->state == channel->running_state && channel->running_state == want_state) || channel->state >= CS_HANGUP) { break; @@ -2514,9 +2513,19 @@ SWITCH_DECLARE(switch_caller_extension_t *) switch_channel_get_caller_extension( } +SWITCH_DECLARE(void) switch_channel_set_bridge_time(switch_channel_t *channel) +{ + switch_mutex_lock(channel->profile_mutex); + if (channel->caller_profile && channel->caller_profile->times) { + channel->caller_profile->times->bridged = switch_micro_time_now(); + } + switch_mutex_unlock(channel->profile_mutex); +} + + SWITCH_DECLARE(void) switch_channel_set_hangup_time(switch_channel_t *channel) { - if (channel->caller_profile && channel->caller_profile->times && !channel->caller_profile->times->hungup) { + if (channel->caller_profile && channel->caller_profile->times && !channel->caller_profile->times->bridged) { switch_mutex_lock(channel->profile_mutex); channel->caller_profile->times->hungup = switch_micro_time_now(); switch_mutex_unlock(channel->profile_mutex); @@ -3349,14 +3358,14 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t * switch_caller_profile_t *caller_profile, *ocp; switch_app_log_t *app_log, *ap; char *last_app = NULL, *last_arg = NULL; - char start[80] = "", resurrect[80] = "", answer[80] = "", progress[80] = "", progress_media[80] = "", end[80] = "", tmp[80] = "", + char start[80] = "", resurrect[80] = "", answer[80] = "", bridge[80] = "", progress[80] = "", progress_media[80] = "", end[80] = "", tmp[80] = "", profile_start[80] = ""; int32_t duration = 0, legbillsec = 0, billsec = 0, mduration = 0, billmsec = 0, legbillmsec = 0, progressmsec = 0, progress_mediamsec = 0; - int32_t answersec = 0, answermsec = 0; + int32_t answersec = 0, answermsec = 0, waitsec = 0, waitmsec = 0; switch_time_t answerusec = 0; - switch_time_t uduration = 0, legbillusec = 0, billusec = 0, progresssec = 0, progressusec = 0, progress_mediasec = 0, progress_mediausec = 0; - time_t tt_created = 0, tt_answered = 0, tt_resurrected = 0, - tt_progress = 0, tt_progress_media = 0, tt_hungup = 0, mtt_created = 0, mtt_answered = 0, mtt_resurrected = 0, + switch_time_t uduration = 0, legbillusec = 0, billusec = 0, progresssec = 0, progressusec = 0, progress_mediasec = 0, progress_mediausec = 0, waitusec = 0; + time_t tt_created = 0, tt_answered = 0, tt_resurrected = 0, tt_bridged, + tt_progress = 0, tt_progress_media = 0, tt_hungup = 0, mtt_created = 0, mtt_answered = 0, mtt_bridged = 0, mtt_hungup = 0, tt_prof_created, mtt_prof_created, mtt_progress = 0, mtt_progress_media = 0; void *pop; char dtstr[SWITCH_DTMF_LOG_LEN + 1] = ""; @@ -3428,6 +3437,12 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t * switch_channel_set_variable(channel, "answer_stamp", answer); } + if (caller_profile->times->bridged) { + switch_time_exp_lt(&tm, caller_profile->times->bridged); + switch_strftime_nocheck(bridge, &retsize, sizeof(bridge), fmt, &tm); + switch_channel_set_variable(channel, "bridge_stamp", bridge); + } + if (caller_profile->times->resurrected) { switch_time_exp_lt(&tm, caller_profile->times->resurrected); switch_strftime_nocheck(resurrect, &retsize, sizeof(resurrect), fmt, &tm); @@ -3471,8 +3486,14 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t * switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->answered); switch_channel_set_variable(channel, "answer_uepoch", tmp); + tt_bridged = (time_t) (caller_profile->times->bridged / 1000000); + mtt_bridged = (time_t) (caller_profile->times->bridged / 1000); + switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_bridged); + switch_channel_set_variable(channel, "bridge_epoch", tmp); + switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->bridged); + switch_channel_set_variable(channel, "bridge_uepoch", tmp); + tt_resurrected = (time_t) (caller_profile->times->resurrected / 1000000); - mtt_resurrected = (time_t) (caller_profile->times->resurrected / 1000); switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_resurrected); switch_channel_set_variable(channel, "resurrect_epoch", tmp); switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->resurrected); @@ -3503,6 +3524,16 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t * mduration = (int32_t) (mtt_hungup - mtt_created); uduration = caller_profile->times->hungup - caller_profile->times->created; + if (caller_profile->times->bridged > caller_profile->times->created) { + waitsec = (int32_t) (tt_bridged - tt_created); + waitmsec = (int32_t) (mtt_bridged - mtt_created); + waitusec = caller_profile->times->bridged - caller_profile->times->created; + } else { + waitsec = 0; + waitmsec = 0; + waitusec = 0; + } + if (caller_profile->times->answered) { billsec = (int32_t) (tt_hungup - tt_answered); billmsec = (int32_t) (mtt_hungup - mtt_answered); @@ -3547,6 +3578,9 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t * switch_snprintf(tmp, sizeof(tmp), "%d", answersec); switch_channel_set_variable(channel, "answersec", tmp); + switch_snprintf(tmp, sizeof(tmp), "%d", waitsec); + switch_channel_set_variable(channel, "waitsec", tmp); + switch_snprintf(tmp, sizeof(tmp), "%d", progress_mediasec); switch_channel_set_variable(channel, "progress_mediasec", tmp); @@ -3565,6 +3599,9 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t * switch_snprintf(tmp, sizeof(tmp), "%d", answermsec); switch_channel_set_variable(channel, "answermsec", tmp); + switch_snprintf(tmp, sizeof(tmp), "%d", waitmsec); + switch_channel_set_variable(channel, "waitmsec", tmp); + switch_snprintf(tmp, sizeof(tmp), "%d", progress_mediamsec); switch_channel_set_variable(channel, "progress_mediamsec", tmp); @@ -3583,6 +3620,9 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t * switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, answerusec); switch_channel_set_variable(channel, "answerusec", tmp); + switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, waitusec); + switch_channel_set_variable(channel, "waitusec", tmp); + switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, progress_mediausec); switch_channel_set_variable(channel, "progress_mediausec", tmp); diff --git a/src/switch_console.c b/src/switch_console.c index a73bb58e89..d902af69e7 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -443,11 +443,8 @@ SWITCH_DECLARE(void) switch_console_printf(switch_text_channel_t channel, const fflush(handle); } -static char hostname[256] = ""; static int32_t running = 1; - - struct helper { int len; int hits; @@ -643,9 +640,9 @@ SWITCH_DECLARE_NONSTD(switch_status_t) switch_console_list_uuid(const char *line if (!zstr(cursor)) { sql = switch_mprintf("select distinct uuid from channels where uuid like '%q%%' and hostname='%q' order by uuid", - cursor, switch_core_get_hostname()); + cursor, switch_core_get_switchname()); } else { - sql = switch_mprintf("select distinct uuid from channels where hostname='%q' order by uuid", switch_core_get_hostname()); + sql = switch_mprintf("select distinct uuid from channels where hostname='%q' order by uuid", switch_core_get_switchname()); } switch_cache_db_execute_sql_callback(db, sql, uuid_callback, &h, &errmsg); @@ -764,7 +761,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch if (h.words == 0) { sql = switch_mprintf("select distinct name from interfaces where type='api' and name like '%q%%' and hostname='%q' order by name", - buf, switch_core_get_hostname()); + buf, switch_core_get_switchname()); } if (sql) { @@ -792,7 +789,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch if (h.words == 0) { stream.write_function(&stream, "select distinct a1 from complete where " "a1 not in (select name from interfaces where hostname='%s') %s ", - switch_core_get_hostname(), argc ? "and" : ""); + switch_core_get_switchname(), argc ? "and" : ""); } else { if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) { stream.write_function(&stream, "select distinct a%d,'%q','%q' from complete where ", h.words + 1, switch_str_nil(dup), switch_str_nil(lp)); @@ -821,7 +818,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch } } - stream.write_function(&stream, " and hostname='%s' order by a%d", switch_core_get_hostname(), h.words + 1); + stream.write_function(&stream, " and hostname='%s' order by a%d", switch_core_get_switchname(), h.words + 1); switch_cache_db_execute_sql_callback(db, stream.data, comp_callback, &h, &errmsg); @@ -1001,7 +998,7 @@ static unsigned char console_f12key(EditLine * el, int ch) char *prompt(EditLine * e) { if (*prompt_str == '\0') { - switch_snprintf(prompt_str, sizeof(prompt_str), "freeswitch@%s> ", hostname); + switch_snprintf(prompt_str, sizeof(prompt_str), "freeswitch@%s> ", switch_core_get_switchname()); } return prompt_str; @@ -1067,8 +1064,6 @@ SWITCH_DECLARE(void) switch_console_loop(void) switch_threadattr_t *thd_attr = NULL; switch_memory_pool_t *pool; - gethostname(hostname, sizeof(hostname)); - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n"); return; @@ -1508,9 +1503,9 @@ SWITCH_DECLARE(void) switch_console_loop(void) /* Load/Init the config first */ console_xml_config(); - gethostname(hostname, sizeof(hostname)); + #ifdef _MSC_VER - sprintf(cmd, "\nfreeswitch@%s> ", hostname); + sprintf(cmd, "\nfreeswitch@%s> ", switch_core_get_switchname()); console_bufferInput(0, 0, cmd, PROMPT_OP); memset(cmd, 0, sizeof(cmd)); #endif @@ -1531,7 +1526,7 @@ SWITCH_DECLARE(void) switch_console_loop(void) } if (activity) { - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, "\nfreeswitch@%s> ", hostname); + switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, "\nfreeswitch@%s> ", switch_core_get_switchname()); } #ifdef _MSC_VER activity = 0; @@ -1799,7 +1794,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) } } } - mystream.write_function(&mystream, " '%s')", switch_core_get_hostname()); + mystream.write_function(&mystream, " '%s')", switch_core_get_switchname()); switch_cache_db_persistant_execute(db, mystream.data, 5); status = SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(argv[0], "add")) { @@ -1815,7 +1810,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) } } } - mystream.write_function(&mystream, " '%s')", switch_core_get_hostname()); + mystream.write_function(&mystream, " '%s')", switch_core_get_switchname()); switch_cache_db_persistant_execute(db, mystream.data, 5); status = SWITCH_STATUS_SUCCESS; @@ -1832,7 +1827,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) mystream.write_function(&mystream, "a%d = '%w'%w", x + 1, switch_str_nil(argv[x + 1]), x == argc - 2 ? "" : " and "); } } - mystream.write_function(&mystream, " and hostname='%s'", switch_core_get_hostname()); + mystream.write_function(&mystream, " and hostname='%s'", switch_core_get_switchname()); switch_cache_db_persistant_execute(db, mystream.data, 1); } status = SWITCH_STATUS_SUCCESS; @@ -1868,38 +1863,38 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string) } if (!strcasecmp(argv[0], "stickyadd") && argc == 3) { - sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_hostname()); + sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_switchname()); switch_cache_db_persistant_execute(db, sql, 5); switch_safe_free(sql); if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) { sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (1, '%q','%q','%q')", - argv[1], argv[2], switch_core_get_hostname()); + argv[1], argv[2], switch_core_get_switchname()); } else { sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (1, '%w','%w','%w')", - argv[1], argv[2], switch_core_get_hostname()); + argv[1], argv[2], switch_core_get_switchname()); } switch_cache_db_persistant_execute(db, sql, 5); status = SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(argv[0], "add") && argc == 3) { - sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_hostname()); + sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_switchname()); switch_cache_db_persistant_execute(db, sql, 5); switch_safe_free(sql); if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) { sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (0, '%q','%q','%q')", - argv[1], argv[2], switch_core_get_hostname()); + argv[1], argv[2], switch_core_get_switchname()); } else { sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (0, '%w','%w','%w')", - argv[1], argv[2], switch_core_get_hostname()); + argv[1], argv[2], switch_core_get_switchname()); } switch_cache_db_persistant_execute(db, sql, 5); status = SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(argv[0], "del") && argc == 2) { char *what = argv[1]; if (!strcasecmp(what, "*")) { - sql = switch_mprintf("delete from aliases where hostname='%q'", switch_core_get_hostname()); + sql = switch_mprintf("delete from aliases where hostname='%q'", switch_core_get_switchname()); switch_cache_db_persistant_execute(db, sql, 1); } else { - sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_hostname()); + sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_switchname()); switch_cache_db_persistant_execute(db, sql, 5); } status = SWITCH_STATUS_SUCCESS; diff --git a/src/switch_core.c b/src/switch_core.c index d3a696bef5..e340a26ffc 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -265,6 +265,13 @@ SWITCH_DECLARE(const char *) switch_core_get_hostname(void) return runtime.hostname; } +SWITCH_DECLARE(const char *) switch_core_get_switchname(void) +{ + if (!zstr(runtime.switchname)) return runtime.switchname; + return runtime.hostname; +} + + SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname) { char *val; @@ -1280,6 +1287,7 @@ static void switch_core_set_serial(void) if ((write_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) >= 0) { bytes = write(write_fd, buf, sizeof(buf)); + bytes++; close(write_fd); write_fd = -1; } @@ -1409,9 +1417,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS; - runtime.tipping_point = 5000; + runtime.tipping_point = 0; runtime.timer_affinity = -1; - + runtime.microseconds_per_tick = 20000; + switch_load_core_config("switch.conf"); switch_core_state_machine_init(runtime.memory_pool); @@ -1662,9 +1671,6 @@ static void switch_load_core_config(const char *file) switch_time_set_monotonic(switch_true(val)); } else if (!strcasecmp(var, "enable-softtimer-timerfd")) { switch_time_set_timerfd(switch_true(val)); - if (switch_true(val)) { - switch_clear_flag((&runtime), SCF_CALIBRATE_CLOCK); - } } else if (!strcasecmp(var, "enable-clock-nanosleep")) { switch_time_set_nanosleep(switch_true(val)); } else if (!strcasecmp(var, "enable-cond-yield")) { @@ -1684,6 +1690,8 @@ static void switch_load_core_config(const char *file) switch_core_min_idle_cpu(atof(val)); } else if (!strcasecmp(var, "tipping-point") && !zstr(val)) { runtime.tipping_point = atoi(val); + } else if (!strcasecmp(var, "1ms-timer") && switch_true(val)) { + runtime.microseconds_per_tick = 1000; } else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) { if (!strcasecmp(val, "disabled")) { runtime.timer_affinity = -1; @@ -1718,6 +1726,9 @@ static void switch_load_core_config(const char *file) } else if (!strcasecmp(var, "rtp-enable-zrtp")) { switch_core_set_variable("zrtp_enabled", val); #endif + } else if (!strcasecmp(var, "switchname") && !zstr(val)) { + runtime.switchname = switch_core_strdup(runtime.memory_pool, val); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Set switchname to %s\n", runtime.switchname); } } } diff --git a/src/switch_core_codec.c b/src/switch_core_codec.c index 96f8d57726..feaca4b7ed 100644 --- a/src/switch_core_codec.c +++ b/src/switch_core_codec.c @@ -658,7 +658,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_decode(switch_codec_t *codec, if (frames && codec->implementation->decoded_bytes_per_packet * frames > *decoded_data_len) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Buffer size sanity check failed!\n"); - return SWITCH_STATUS_GENERR; + *decoded_data_len = codec->implementation->decoded_bytes_per_packet; + memset(decoded_data, 255, *decoded_data_len); + return SWITCH_STATUS_SUCCESS; } } diff --git a/src/switch_core_file.c b/src/switch_core_file.c index fc7d223b5b..a3f7cc12cc 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -204,7 +204,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh, void *data, switch_size_t *len) { switch_status_t status = SWITCH_STATUS_FALSE; - switch_size_t want, got, orig_len = *len; + switch_size_t want, orig_len = *len; switch_assert(fh != NULL); switch_assert(fh->file_interface != NULL); @@ -276,8 +276,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh, } - got = *len; - if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->native_rate != fh->samplerate) { if (!fh->resampler) { if (switch_resample_create(&fh->resampler, @@ -567,15 +565,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh) if (fh->spool_path) { char *command; - int result; #ifdef _MSC_VER command = switch_mprintf("move %s %s", fh->spool_path, fh->file_path); #else command = switch_mprintf("/bin/mv %s %s", fh->spool_path, fh->file_path); #endif - result = system(command); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Copy spooled file [%s] to [%s]\n", fh->spool_path, fh->file_path); + if (system(command) == -1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to copy spooled file [%s] to [%s] because of a command error : %s\n", fh->spool_path, fh->file_path, command); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Copy spooled file [%s] to [%s]\n", fh->spool_path, fh->file_path); + } free(command); } diff --git a/src/switch_core_media_bug.c b/src/switch_core_media_bug.c index 1e7b260078..5cc28a3c88 100644 --- a/src/switch_core_media_bug.c +++ b/src/switch_core_media_bug.c @@ -511,7 +511,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove(switch_core_session SWITCH_DECLARE(uint32_t) switch_core_media_bug_prune(switch_core_session_t *session) { switch_media_bug_t *bp = NULL, *last = NULL; - switch_status_t status = SWITCH_STATUS_FALSE; int ttl = 0; @@ -540,7 +539,7 @@ SWITCH_DECLARE(uint32_t) switch_core_media_bug_prune(switch_core_session_t *sess switch_thread_rwlock_unlock(session->bug_rwlock); if (bp) { - status = switch_core_media_bug_close(&bp); + switch_core_media_bug_close(&bp); ttl++; goto top; } diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 2080c0b624..8d4a2851f3 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -481,15 +481,13 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_ UNPROTECT_INTERFACE(endpoint_interface); return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; } else { - switch_caller_profile_t *profile = NULL, *peer_profile = NULL, *cloned_profile = NULL; + switch_caller_profile_t *profile = NULL, *cloned_profile = NULL; switch_event_t *event; switch_channel_t *peer_channel = switch_core_session_get_channel(*new_session); const char *use_uuid; switch_assert(peer_channel); - peer_profile = switch_channel_get_caller_profile(peer_channel); - if ((use_uuid = switch_event_get_header(var_event, "origination_uuid"))) { use_uuid = switch_core_session_strdup(*new_session, use_uuid); if (switch_core_session_set_uuid(*new_session, use_uuid) == SWITCH_STATUS_SUCCESS) { @@ -1454,13 +1452,12 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_xml(switch_e switch_channel_t *channel; switch_xml_t tag, tag2, tag3, vars, callflow; switch_call_direction_t direction = SWITCH_CALL_DIRECTION_OUTBOUND; - char *bridgeto, *flag_str = NULL, *cap_str = NULL, *direction_s = NULL, *uuid = NULL; + char *flag_str = NULL, *cap_str = NULL, *direction_s = NULL, *uuid = NULL; uint32_t flags[CF_FLAG_MAX] = { 0 }; uint32_t caps[CC_FLAG_MAX] = { 0 }; int i; vars = switch_xml_child(xml, "variables"); - bridgeto = xml_find_var(vars, SWITCH_SIGNAL_BOND_VARIABLE); uuid = xml_find_var(vars, "uuid"); if ((tag = switch_xml_child(xml, "channel_data"))) { diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 7f2c9c712f..686c5d24de 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -201,9 +201,11 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); } + /* I *think* we can do without this now, if not let me know if (r == SWITCH_STATUS_SUCCESS && !(*dbh)->io_mutex) { (*dbh)->io_mutex = sql_manager.io_mutex; } + */ return r; } @@ -289,6 +291,8 @@ SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t switch_mutex_lock(sql_manager.dbh_mutex); (*dbh)->last_used = switch_epoch_time_now(NULL); + (*dbh)->io_mutex = NULL; + if ((*dbh)->use_count) { if (--(*dbh)->use_count == 0) { (*dbh)->thread_hash = 1; @@ -1137,7 +1141,7 @@ static void core_event_handler(switch_event_t *event) new_sql() = switch_mprintf("insert into tasks values(%q,'%q','%q',%q, '%q')", id, switch_event_get_header_nil(event, "task-desc"), - switch_event_get_header_nil(event, "task-group"), manager ? manager : "0", switch_core_get_hostname() + switch_event_get_header_nil(event, "task-group"), manager ? manager : "0", switch_core_get_switchname() ); } } @@ -1145,7 +1149,7 @@ static void core_event_handler(switch_event_t *event) case SWITCH_EVENT_DEL_SCHEDULE: case SWITCH_EVENT_EXE_SCHEDULE: new_sql() = switch_mprintf("delete from tasks where task_id=%q and hostname='%q'", - switch_event_get_header_nil(event, "task-id"), switch_core_get_hostname()); + switch_event_get_header_nil(event, "task-id"), switch_core_get_switchname()); break; case SWITCH_EVENT_RE_SCHEDULE: { @@ -1156,7 +1160,7 @@ static void core_event_handler(switch_event_t *event) new_sql() = switch_mprintf("update tasks set task_desc='%q',task_group='%q', task_sql_manager=%q where task_id=%q and hostname='%q'", switch_event_get_header_nil(event, "task-desc"), switch_event_get_header_nil(event, "task-group"), manager ? manager : "0", id, - switch_core_get_hostname()); + switch_core_get_switchname()); } } break; @@ -1166,10 +1170,10 @@ static void core_event_handler(switch_event_t *event) if (uuid) { new_sql() = switch_mprintf("delete from channels where uuid='%q' and hostname='%q'", - uuid, switch_core_get_hostname()); + uuid, switch_core_get_switchname()); new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q') and hostname='%q'", - uuid, uuid, switch_core_get_hostname()); + uuid, uuid, switch_core_get_switchname()); } } @@ -1181,12 +1185,12 @@ static void core_event_handler(switch_event_t *event) "update calls set callee_uuid='%q' where callee_uuid='%q' and hostname='%q'", switch_event_get_header_nil(event, "unique-id"), switch_event_get_header_nil(event, "old-unique-id"), - switch_core_get_hostname(), + switch_core_get_switchname(), switch_event_get_header_nil(event, "unique-id"), switch_event_get_header_nil(event, "old-unique-id"), - switch_core_get_hostname(), + switch_core_get_switchname(), switch_event_get_header_nil(event, "unique-id"), - switch_event_get_header_nil(event, "old-unique-id"), switch_core_get_hostname() + switch_event_get_header_nil(event, "old-unique-id"), switch_core_get_switchname() ); break; } @@ -1201,7 +1205,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-state"), switch_event_get_header_nil(event, "channel-call-state"), switch_event_get_header_nil(event, "caller-dialplan"), - switch_event_get_header_nil(event, "caller-context"), switch_core_get_hostname() + switch_event_get_header_nil(event, "caller-context"), switch_core_get_switchname() ); break; case SWITCH_EVENT_CODEC: @@ -1214,7 +1218,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-write-codec-name"), switch_event_get_header_nil(event, "channel-write-codec-rate"), switch_event_get_header_nil(event, "channel-write-codec-bit-rate"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_switchname()); break; case SWITCH_EVENT_CHANNEL_HOLD: case SWITCH_EVENT_CHANNEL_UNHOLD: @@ -1226,7 +1230,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "application-data"), switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname() + switch_event_get_header_nil(event, "unique-id"), switch_core_get_switchname() ); } @@ -1241,7 +1245,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-presence-data"), switch_event_get_header_nil(event, "channel-call-uuid"), extra_cols, - switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_switchname()); free(extra_cols); } else { new_sql() = switch_mprintf("update channels set " @@ -1249,7 +1253,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), switch_event_get_header_nil(event, "channel-call-uuid"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_switchname()); } } @@ -1284,7 +1288,7 @@ static void core_event_handler(switch_event_t *event) switch_str_nil(name), switch_str_nil(number), switch_event_get_header_nil(event, "direction"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_switchname()); name = switch_event_get_header(event, "callee-name"); number = switch_event_get_header(event, "callee-number"); @@ -1301,7 +1305,7 @@ static void core_event_handler(switch_event_t *event) { new_sql() = switch_mprintf("update channels set callstate='%q' where uuid='%q' and hostname='%q'", switch_event_get_header_nil(event, "channel-call-state"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_switchname()); } break; @@ -1333,7 +1337,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), extra_cols, - switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_switchname()); free(extra_cols); } else { new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q'," @@ -1348,13 +1352,13 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "caller-context"), switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_switchname()); } break; default: new_sql() = switch_mprintf("update channels set state='%s' where uuid='%s' and hostname='%q'", switch_event_get_header_nil(event, "channel-state"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_switchname()); break; } @@ -1380,7 +1384,7 @@ static void core_event_handler(switch_event_t *event) new_sql() = switch_mprintf("update channels set call_uuid='%q' where uuid='%s' and hostname='%q'", switch_event_get_header_nil(event, "channel-call-uuid"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_switchname()); if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { func_name = "function"; @@ -1407,7 +1411,7 @@ static void core_event_handler(switch_event_t *event) callee_cid_num, switch_event_get_header_nil(event, "Other-Leg-destination-number"), switch_event_get_header_nil(event, "Other-Leg-channel-name"), - switch_event_get_header_nil(event, "Other-Leg-unique-id"), switch_core_get_hostname() + switch_event_get_header_nil(event, "Other-Leg-unique-id"), switch_core_get_switchname() ); } break; @@ -1416,14 +1420,14 @@ static void core_event_handler(switch_event_t *event) char *uuid = switch_event_get_header_nil(event, "caller-unique-id"); new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q') and hostname='%q'", - uuid, uuid, switch_core_get_hostname()); + uuid, uuid, switch_core_get_switchname()); break; } case SWITCH_EVENT_SHUTDOWN: new_sql() = switch_mprintf("delete from channels where hostname='%q';" "delete from interfaces where hostname='%q';" "delete from calls where hostname='%q'", - switch_core_get_hostname(), switch_core_get_hostname(), switch_core_get_hostname() + switch_core_get_switchname(), switch_core_get_switchname(), switch_core_get_switchname() ); break; case SWITCH_EVENT_LOG: @@ -1441,7 +1445,7 @@ static void core_event_handler(switch_event_t *event) switch_mprintf ("insert into interfaces (type,name,description,syntax,ikey,filename,hostname) values('%q','%q','%q','%q','%q','%q','%q')", type, name, switch_str_nil(description), switch_str_nil(syntax), switch_str_nil(key), switch_str_nil(filename), - switch_core_get_hostname() + switch_core_get_switchname() ); } break; @@ -1452,7 +1456,7 @@ static void core_event_handler(switch_event_t *event) const char *name = switch_event_get_header_nil(event, "name"); if (!zstr(type) && !zstr(name)) { new_sql() = switch_mprintf("delete from interfaces where type='%q' and name='%q' and hostname='%q'", type, name, - switch_core_get_hostname()); + switch_core_get_switchname()); } break; } @@ -1464,7 +1468,7 @@ static void core_event_handler(switch_event_t *event) break; } new_sql() = switch_mprintf("update channels set secure='%s' where uuid='%s' and hostname='%q'", - type, switch_event_get_header_nil(event, "caller-unique-id"), switch_core_get_hostname() + type, switch_event_get_header_nil(event, "caller-unique-id"), switch_core_get_switchname() ); break; } @@ -1475,12 +1479,12 @@ static void core_event_handler(switch_event_t *event) if (!strcmp("add", op)) { new_sql() = switch_mprintf("insert into nat (port, proto, sticky, hostname) values (%s, %s, %d,'%q')", switch_event_get_header_nil(event, "port"), - switch_event_get_header_nil(event, "proto"), sticky, switch_core_get_hostname() + switch_event_get_header_nil(event, "proto"), sticky, switch_core_get_switchname() ); } else if (!strcmp("del", op)) { new_sql() = switch_mprintf("delete from nat where port=%s and proto=%s and hostname='%q'", switch_event_get_header_nil(event, "port"), - switch_event_get_header_nil(event, "proto"), switch_core_get_hostname()); + switch_event_get_header_nil(event, "proto"), switch_core_get_switchname()); } else if (!strcmp("status", op)) { /* call show nat api */ } else if (!strcmp("status_response", op)) { @@ -1638,29 +1642,22 @@ static char create_registrations_sql[] = SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, const char *realm, const char *token, const char *url, uint32_t expires, const char *network_ip, const char *network_port, const char *network_proto) { - switch_cache_db_handle_t *dbh; char *sql; if (!switch_test_flag((&runtime), SCF_USE_SQL)) { return SWITCH_STATUS_FALSE; } - if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); - return SWITCH_STATUS_FALSE; - } - if (runtime.multiple_registrations) { sql = switch_mprintf("delete from registrations where hostname='%q' and (url='%q' or token='%q')", - switch_core_get_hostname(), url, switch_str_nil(token)); + switch_core_get_switchname(), url, switch_str_nil(token)); } else { sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q'", - user, realm, switch_core_get_hostname()); + user, realm, switch_core_get_switchname()); } - switch_cache_db_execute_sql(dbh, sql, NULL); - free(sql); - + switch_queue_push(sql_manager.sql_queue[0], sql); + sql = switch_mprintf("insert into registrations (reg_user,realm,token,url,expires,network_ip,network_port,network_proto,hostname) " "values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q')", switch_str_nil(user), @@ -1671,42 +1668,31 @@ SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, c switch_str_nil(network_ip), switch_str_nil(network_port), switch_str_nil(network_proto), - switch_core_get_hostname() + switch_core_get_switchname() ); + + + switch_queue_push(sql_manager.sql_queue[0], sql); - switch_cache_db_execute_sql(dbh, sql, NULL); - switch_cache_db_release_db_handle(&dbh); - - free(sql); - return SWITCH_STATUS_SUCCESS; } SWITCH_DECLARE(switch_status_t) switch_core_del_registration(const char *user, const char *realm, const char *token) { - switch_cache_db_handle_t *dbh; char *sql; if (!switch_test_flag((&runtime), SCF_USE_SQL)) { return SWITCH_STATUS_FALSE; } - if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); - return SWITCH_STATUS_FALSE; - } - if (!zstr(token) && runtime.multiple_registrations) { - sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q' and token='%q'", user, realm, switch_core_get_hostname(), token); + sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q' and token='%q'", user, realm, switch_core_get_switchname(), token); } else { - sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q'", user, realm, switch_core_get_hostname()); + sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q'", user, realm, switch_core_get_switchname()); } - switch_cache_db_execute_sql(dbh, sql, NULL); - switch_cache_db_release_db_handle(&dbh); - - free(sql); + switch_queue_push(sql_manager.sql_queue[0], sql); return SWITCH_STATUS_SUCCESS; } @@ -1714,7 +1700,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_del_registration(const char *user, c SWITCH_DECLARE(switch_status_t) switch_core_expire_registration(int force) { - switch_cache_db_handle_t *dbh; char *sql; time_t now; @@ -1722,23 +1707,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_expire_registration(int force) return SWITCH_STATUS_FALSE; } - if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); - return SWITCH_STATUS_FALSE; - } - now = switch_epoch_time_now(NULL); if (force) { - sql = switch_mprintf("delete from registrations where hostname='%q'", switch_core_get_hostname()); + sql = switch_mprintf("delete from registrations where hostname='%q'", switch_core_get_switchname()); } else { - sql = switch_mprintf("delete from registrations where expires > 0 and expires <= %ld and hostname='%q'", now, switch_core_get_hostname()); + sql = switch_mprintf("delete from registrations where expires > 0 and expires <= %ld and hostname='%q'", now, switch_core_get_switchname()); } - switch_cache_db_execute_sql(dbh, sql, NULL); - switch_cache_db_release_db_handle(&dbh); - - free(sql); + switch_queue_push(sql_manager.sql_queue[0], sql); return SWITCH_STATUS_SUCCESS; @@ -1790,7 +1767,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ char sql[512] = ""; char *tables[] = { "channels", "calls", "interfaces", "tasks", NULL }; int i; - const char *hostname = switch_core_get_hostname(); + const char *hostname = switch_core_get_switchname(); for (i = 0; tables[i]; i++) { switch_snprintf(sql, sizeof(sql), "delete from %s where hostname='%s'", tables[i], hostname); diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index e69c408013..6551b2b777 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -636,6 +636,18 @@ SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t * if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hangup-Cause", switch_channel_cause2str(cause)); switch_channel_event_set_data(session->channel, event); + if (switch_true(switch_channel_get_variable(session->channel, "hangup_complete_with_xml"))) { + switch_xml_t cdr = NULL; + char *xml_cdr_text; + + if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) { + xml_cdr_text = switch_xml_toxml(cdr, SWITCH_FALSE); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CDR-Attached", "xml"); + switch_event_add_body(event, "%s", xml_cdr_text); + switch_xml_free(cdr); + switch_safe_free(xml_cdr_text); + } + } switch_event_fire(&event); } diff --git a/src/switch_event.c b/src/switch_event.c index e290987248..6d97041901 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -35,7 +35,7 @@ #include #include -#define DISPATCH_QUEUE_LEN 5000 +#define DISPATCH_QUEUE_LEN 10000 //#define DEBUG_DISPATCH_QUEUES /*! \brief A node to store binded events */ @@ -66,7 +66,6 @@ struct switch_event_subclass { #define MAX_DISPATCH_VAL 20 static unsigned int MAX_DISPATCH = MAX_DISPATCH_VAL; static unsigned int SOFT_MAX_DISPATCH = 0; -static char hostname[128] = ""; static char guess_ip_v4[80] = ""; static char guess_ip_v6[80] = ""; static switch_event_node_t *EVENT_NODES[SWITCH_EVENT_ALL + 1] = { NULL }; @@ -291,6 +290,7 @@ static void *SWITCH_THREAD_FUNC switch_event_thread(switch_thread_t *thread, voi switch_queue_t *queue = (switch_queue_t *) obj; uint32_t index = 0; int my_id = 0; + int auto_pause = 0; switch_mutex_lock(EVENT_QUEUE_MUTEX); THREAD_COUNT++; @@ -307,6 +307,14 @@ static void *SWITCH_THREAD_FUNC switch_event_thread(switch_thread_t *thread, voi switch_event_t *event = NULL; int loops = 0; + if (auto_pause) { + if (!--auto_pause) { + switch_core_session_ctl(SCSC_PAUSE_INBOUND, &auto_pause); + } else { + switch_cond_next(); + } + } + if (switch_queue_pop(queue, &pop) != SWITCH_STATUS_SUCCESS) { break; } @@ -323,8 +331,22 @@ static void *SWITCH_THREAD_FUNC switch_event_thread(switch_thread_t *thread, voi while (event) { + if (++loops > 2) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Event system overloading\n"); + uint32_t last_sps = 0, sess_count = switch_core_session_count(); + if (auto_pause) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Event system *still* overloading.\n"); + } else { + switch_core_session_ctl(SCSC_LAST_SPS, &last_sps); + last_sps = (uint32_t) (float) (last_sps * 0.75f); + sess_count = (uint32_t) (float) (sess_count * 0.75f); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, + "Event system overloading. Taking a 10 second break, Reducing max_sessions to %d %dsps\n", sess_count, last_sps); + switch_core_session_limit(sess_count); + switch_core_session_ctl(SCSC_SPS, &last_sps); + auto_pause = 10; + switch_core_session_ctl(SCSC_PAUSE_INBOUND, &auto_pause); + } switch_yield(1000000); } @@ -624,7 +646,6 @@ SWITCH_DECLARE(switch_status_t) switch_event_init(switch_memory_pool_t *pool) switch_mutex_unlock(EVENT_QUEUE_MUTEX); switch_threadattr_create(&thd_attr, pool); - gethostname(hostname, sizeof(hostname)); switch_find_local_ip(guess_ip_v4, sizeof(guess_ip_v4), NULL, AF_INET); switch_find_local_ip(guess_ip_v6, sizeof(guess_ip_v6), NULL, AF_INET6); @@ -1075,17 +1096,21 @@ SWITCH_DECLARE(switch_status_t) switch_event_serialize(switch_event_t *event, ch } -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) { - char *vdata, *vdatap; + char *vdata, *vdatap = NULL; char *end, *check_a, *check_b; switch_event_t *e = *event; char *var_array[1024] = { 0 }; int var_count = 0; char *next; - - vdatap = strdup(data); - vdata = vdatap; + + if (dup) { + vdatap = strdup(data); + vdata = vdatap; + } else { + vdata = data; + } end = switch_find_end_paren(vdata, a, b); @@ -1103,7 +1128,9 @@ SWITCH_DECLARE(switch_status_t) switch_event_create_brackets(char *data, char a, vdata++; *end++ = '\0'; } else { - free(vdatap); + if (dup) { + free(vdatap); + } return SWITCH_STATUS_FALSE; } @@ -1121,7 +1148,15 @@ SWITCH_DECLARE(switch_status_t) switch_event_create_brackets(char *data, char a, next = pnext + 1; } } - + + + if (vdata) { + if (*vdata == '^' && *(vdata + 1) == '^') { + vdata += 2; + c = *vdata++; + } + } + if ((var_count = switch_separate_string(vdata, c, var_array, (sizeof(var_array) / sizeof(var_array[0]))))) { int x = 0; for (x = 0; x < var_count; x++) { @@ -1130,6 +1165,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_create_brackets(char *data, char a, if ((inner_var_count = switch_separate_string(var_array[x], '=', inner_var_array, (sizeof(inner_var_array) / sizeof(inner_var_array[0])))) == 2) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Parsing variable [%s]=[%s]\n", inner_var_array[0], inner_var_array[1]); switch_event_add_header_string(e, SWITCH_STACK_BOTTOM, inner_var_array[0], inner_var_array[1]); } } @@ -1144,9 +1180,14 @@ SWITCH_DECLARE(switch_status_t) switch_event_create_brackets(char *data, char a, } *event = e; - *new_data = strdup(end); - free(vdatap); + if (dup) { + *new_data = strdup(end); + free(vdatap); + } else { + *new_data = end; + } + return SWITCH_STATUS_SUCCESS; } @@ -1316,7 +1357,8 @@ SWITCH_DECLARE(void) switch_event_prep_for_delivery_detailed(const char *file, c switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Event-Name", switch_event_name(event->event_id)); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Core-UUID", switch_core_get_uuid()); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FreeSWITCH-Hostname", hostname); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FreeSWITCH-Hostname", switch_core_get_hostname()); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FreeSWITCH-Switchname", switch_core_get_switchname()); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FreeSWITCH-IPv4", guess_ip_v4); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FreeSWITCH-IPv6", guess_ip_v6); @@ -1355,11 +1397,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_fire_detailed(const char *file, con for (;;) { for (index = (*event)->priority; index < 3; index++) { - int was = (*event)->priority; if (switch_queue_trypush(EVENT_QUEUE[index], *event) == SWITCH_STATUS_SUCCESS) { - if (index != was) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "queued event at a lower priority %d/%d!\n", index, was); - } goto end; } } diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 07c341a580..4932606ff2 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -29,6 +29,7 @@ * Matt Klein * Michael Jerris * Ken Rice + * Marc Olivier Chouinard * * switch_ivr.c -- IVR Library * @@ -298,14 +299,11 @@ static void *SWITCH_THREAD_FUNC unicast_thread_run(switch_thread_t *thread, void { switch_unicast_conninfo_t *conninfo = (switch_unicast_conninfo_t *) obj; switch_size_t len; - switch_channel_t *channel; if (!conninfo) { return NULL; } - channel = switch_core_session_get_channel(conninfo->session); - while (switch_test_flag(conninfo, SUF_READY) && switch_test_flag(conninfo, SUF_THREAD_RUNNING)) { len = conninfo->write_frame.buflen; if (switch_socket_recv(conninfo->socket, conninfo->write_frame.data, &len) != SWITCH_STATUS_SUCCESS || len == 0) { @@ -1362,11 +1360,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_ switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 250, NULL); switch_yield(250000); } else { - switch_status_t st; switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL); switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL); switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL); - st = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); + switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); } if ((flags & SMF_REBRIDGE) @@ -2222,6 +2219,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_ switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->answered); switch_xml_set_txt_d(time_tag, tmp); + if (!(time_tag = switch_xml_add_child_d(x_times, "bridged_time", t_off++))) { + goto error; + } + switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->bridged); + switch_xml_set_txt_d(time_tag, tmp); + if (!(time_tag = switch_xml_add_child_d(x_times, "hangup_time", t_off++))) { goto error; } @@ -2273,7 +2276,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3 switch_frame_t *read_frame, write_frame = { 0 }; switch_status_t status; switch_channel_t *channel = switch_core_session_get_channel(session); - uint32_t interval, samples; + uint32_t interval; uint32_t ts = 0; switch_codec_implementation_t read_impl = { 0 }; switch_core_session_get_read_impl(session, &read_impl); @@ -2285,7 +2288,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3 } interval = read_impl.microseconds_per_packet / 1000; - samples = switch_samples_per_packet(read_impl.samples_per_second, interval); + //samples = switch_samples_per_packet(read_impl.samples_per_second, interval); qlen = delay_ms / (interval); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting delay to %dms (%d frames)\n", delay_ms, qlen); @@ -2327,9 +2330,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session, switch_say_interface_t *si; switch_channel_t *channel; switch_status_t status = SWITCH_STATUS_FALSE; - const char *save_path = NULL, *chan_lang = NULL, *lang = NULL, *lname = NULL, *sound_path = NULL; + const char *save_path = NULL, *chan_lang = NULL, *lang = NULL, *sound_path = NULL; switch_event_t *hint_data; - switch_xml_t cfg, xml = NULL, language, macros; + switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL; char *p; switch_assert(session); @@ -2341,6 +2344,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session, } if (module_name) { + char *p; p = switch_core_session_strdup(session, module_name); module_name = p; @@ -2371,58 +2375,35 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session, switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang); switch_channel_event_set_data(channel, hint_data); - if (switch_xml_locate("phrases", NULL, NULL, NULL, &xml, &cfg, hint_data, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of phrases failed.\n"); + if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, ¯os, chan_lang) != SWITCH_STATUS_SUCCESS) { goto done; } - if (!(macros = switch_xml_child(cfg, "macros"))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros tag.\n"); - goto done; - } - - if (!(language = switch_xml_child(macros, "language"))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language tag.\n"); - goto done; - } - - while (language) { - if ((lname = (char *) switch_xml_attr(language, "name")) && !strcasecmp(lname, chan_lang)) { - const char *tmp; - - if ((tmp = switch_xml_attr(language, "module"))) { - module_name = tmp; - } - break; - } - language = language->next; - } - - if (!language) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language %s.\n", chan_lang); - goto done; - } - - if (!module_name) { + if ((p = (char *) switch_xml_attr(language, "say-module"))) { + module_name = switch_core_session_strdup(session, p); + } else if ((p = (char *) switch_xml_attr(language, "module"))) { + module_name = switch_core_session_strdup(session, p); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n"); + } else { module_name = chan_lang; } - if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) { - sound_path = (char *) switch_xml_attr(language, "sound_path"); + if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) { + if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) { + sound_path = (char *) switch_xml_attr(language, "sound_path"); + } } - save_path = switch_channel_get_variable(channel, "sound_prefix"); - - if (sound_path) { - switch_channel_set_variable(channel, "sound_prefix", sound_path); - p = switch_core_session_strdup(session, sound_path); - sound_path = p; + if (channel) { + const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced"); + if (!switch_true(p)) { + save_path = switch_channel_get_variable(channel, "sound_prefix"); + if (sound_path) { + switch_channel_set_variable(channel, "sound_prefix", sound_path); + } + } } - if (xml) { - switch_xml_free(xml); - } - if ((si = switch_loadable_module_get_say_interface(module_name))) { /* should go back and proto all the say mods to const.... */ switch_say_args_t say_args = {0}; @@ -2446,7 +2427,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session, if (save_path) { switch_channel_set_variable(channel, "sound_prefix", save_path); } - + + if (xml) { + switch_xml_free(xml); + } + return status; } @@ -2463,9 +2448,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say_string(switch_core_session_t *ses switch_say_interface_t *si; switch_channel_t *channel = NULL; switch_status_t status = SWITCH_STATUS_FALSE; - const char *save_path = NULL, *chan_lang = NULL, *lname = NULL, *sound_path = NULL; + const char *save_path = NULL, *chan_lang = NULL, *sound_path = NULL; switch_event_t *hint_data; - switch_xml_t cfg, xml = NULL, language, macros; + switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL; if (session) { channel = switch_core_session_get_channel(session); @@ -2498,52 +2483,31 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say_string(switch_core_session_t *ses switch_channel_event_set_data(channel, hint_data); } - if (switch_xml_locate("phrases", NULL, NULL, NULL, &xml, &cfg, hint_data, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of phrases failed.\n"); + if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, ¯os, chan_lang) != SWITCH_STATUS_SUCCESS) { goto done; } - if (!(macros = switch_xml_child(cfg, "macros"))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros tag.\n"); - goto done; - } - - if (!(language = switch_xml_child(macros, "language"))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language tag.\n"); - goto done; - } - - while (language) { - if ((lname = (char *) switch_xml_attr(language, "name")) && !strcasecmp(lname, chan_lang)) { - const char *tmp; - - if ((tmp = switch_xml_attr(language, "module"))) { - module_name = tmp; - } - break; - } - language = language->next; - } - - if (!language) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language %s.\n", chan_lang); - goto done; - } - - if (!module_name) { + if ((module_name = switch_xml_attr(language, "say-module"))) { + } else if ((module_name = switch_xml_attr(language, "module"))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n"); + } else { module_name = chan_lang; } - if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) { - sound_path = (char *) switch_xml_attr(language, "sound_path"); + if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) { + if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) { + sound_path = (char *) switch_xml_attr(language, "sound_path"); + } } if (channel) { - save_path = switch_channel_get_variable(channel, "sound_prefix"); - } - - if (sound_path && channel) { - switch_channel_set_variable(channel, "sound_prefix", sound_path); + const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced"); + if (!switch_true(p)) { + save_path = switch_channel_get_variable(channel, "sound_prefix"); + if (sound_path) { + switch_channel_set_variable(channel, "sound_prefix", sound_path); + } + } } if ((si = switch_loadable_module_get_say_interface(module_name))) { diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 9fb2eea95c..016fee7246 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1637,7 +1637,6 @@ static switch_bool_t preprocess_callback(switch_media_bug_t *bug, void *user_dat pp_cb_t *cb = (pp_cb_t *) user_data; switch_codec_implementation_t read_impl = { 0 }; switch_frame_t *frame = NULL; - int y; switch_core_session_get_read_impl(session, &read_impl); @@ -1682,7 +1681,7 @@ static switch_bool_t preprocess_callback(switch_media_bug_t *bug, void *user_dat memcpy(frame->data, cb->read_out, frame->datalen); } - y = speex_preprocess_run(cb->read_st, frame->data); + speex_preprocess_run(cb->read_st, frame->data); } if (cb->write_ec) { @@ -1703,7 +1702,7 @@ static switch_bool_t preprocess_callback(switch_media_bug_t *bug, void *user_dat memcpy(frame->data, cb->write_out, frame->datalen); } - y = speex_preprocess_run(cb->write_st, frame->data); + speex_preprocess_run(cb->write_st, frame->data); } if (cb->read_ec) { diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index f1a6bdba22..0fecc309f7 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -201,7 +201,9 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) chan_a = switch_core_session_get_channel(session_a); chan_b = switch_core_session_get_channel(session_b); - + + switch_channel_set_bridge_time(chan_a); + if ((exec_app = switch_channel_get_variable(chan_a, "bridge_pre_execute_app"))) { exec_data = switch_channel_get_variable(chan_a, "bridge_pre_execute_data"); } @@ -862,10 +864,9 @@ static switch_status_t hanguphook(switch_core_session_t *session) switch_core_session_message_t msg = { 0 }; switch_channel_t *channel = NULL; switch_event_t *event; - switch_channel_state_t state; channel = switch_core_session_get_channel(session); - state = switch_channel_get_state(channel); + msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE; msg.from = __FILE__; @@ -1068,6 +1069,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_signal_bridge(switch_core_session_t * switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", switch_core_session_get_uuid(session)); switch_event_fire(&event); } + + switch_channel_set_bridge_time(caller_channel); + switch_channel_set_bridge_time(peer_channel); switch_channel_set_state_flag(caller_channel, CF_RESET); switch_channel_set_state_flag(peer_channel, CF_RESET); @@ -1576,6 +1580,8 @@ SWITCH_DECLARE(void) switch_ivr_intercept_session(switch_core_session_t *session switch_channel_answer(rchannel); } + switch_channel_mark_hold(rchannel, SWITCH_FALSE); + switch_channel_set_state_flag(rchannel, CF_TRANSFER); switch_channel_set_state(rchannel, CS_PARK); diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 0c4c336e51..b0a159eea9 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1346,9 +1346,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_sess switch_event_header_t *hi = NULL; struct ent_originate_ringback rb_data = { 0 }; const char *ringback_data = NULL; - char *vars = NULL; - int var_block_count = 0; - char *e = NULL; switch_event_t *var_event = NULL; switch_core_new_memory_pool(&pool); @@ -1360,53 +1357,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_sess data = switch_core_strdup(pool, bridgeto); - /* strip leading spaces */ - while (data && *data && *data == ' ') { - data++; - } - - /* extract channel variables, allowing multiple sets of braces */ - while (*data == '<') { - if (!var_block_count) { - e = switch_find_end_paren(data, '<', '>'); - if (!e || !*e) { - goto var_extract_error; - } - vars = data + 1; - *e = '\0'; - data = e + 1; - } else { - int j = 0, k = 0; - if (e) { - *e = ','; - } - e = switch_find_end_paren(data, '<', '>'); - if (!e || !*e) { - goto var_extract_error; - } - /* swallow the opening bracket */ - while ((data + k) && *(data + k)) { - j = k; - k++; - /* note that this affects vars[] */ - data[j] = data[k]; - } - *(--e) = '\0'; - data = e + 1; - } - var_block_count++; - continue; - - var_extract_error: - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n"); - switch_goto_status(SWITCH_STATUS_GENERR, done); - } - - /* strip leading spaces (again) */ - while (data && *data && *data == ' ') { - data++; - } - if (session) { switch_caller_profile_t *cpp = NULL; channel = switch_core_session_get_channel(session); @@ -1430,23 +1380,28 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_sess if (channel) { switch_channel_process_export(channel, NULL, var_event, SWITCH_EXPORT_VARS_VARIABLE); } - - if (vars) { /* Parse parameters specified from the dialstring */ - char *var_array[1024] = { 0 }; - int var_count = 0; - if ((var_count = switch_separate_string(vars, ',', var_array, (sizeof(var_array) / sizeof(var_array[0]))))) { - int x = 0; - for (x = 0; x < var_count; x++) { - char *inner_var_array[2] = { 0 }; - int inner_var_count; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "variable string %d = [%s]\n", x, var_array[x]); - if ((inner_var_count = - switch_separate_string(var_array[x], '=', inner_var_array, (sizeof(inner_var_array) / sizeof(inner_var_array[0])))) == 2) { - switch_event_del_header(var_event, inner_var_array[0]); - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, inner_var_array[0], inner_var_array[1]); - } - } + + /* strip leading spaces */ + while (data && *data && *data == ' ') { + data++; + } + + /* extract channel variables, allowing multiple sets of braces */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Parsing ultra-global variables\n"); + while (*data == '<') { + char *parsed = NULL; + + if (switch_event_create_brackets(data, '<', '>', ',', &var_event, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n"); + switch_goto_status(SWITCH_STATUS_GENERR, done); } + + data = parsed; + } + + /* strip leading spaces (again) */ + while (data && *data && *data == ' ') { + data++; } if (ovars && ovars != var_event) { @@ -1751,9 +1706,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_call_cause_t reason = SWITCH_CAUSE_NONE; switch_call_cause_t force_reason = SWITCH_CAUSE_NONE; uint8_t to = 0; - char *var_val, *vars = NULL; - int var_block_count = 0; - char *e = NULL; + char *var_val; const char *ringback_data = NULL; switch_event_t *var_event = NULL; int8_t fail_on_single_reject = 0; @@ -1870,59 +1823,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess data = odata; - /* strip leading spaces */ - while (data && *data && *data == ' ') { - data++; - } - - /* extract channel variables, allowing multiple sets of braces */ - while (*data == '{') { - if (!var_block_count) { - e = switch_find_end_paren(data, '{', '}'); - if (!e || !*e) { - goto var_extract_error; - } - vars = data + 1; - *e = '\0'; - data = e + 1; - } else { - int j = 0, k = 0; - if (e) { - *e = ','; - } - e = switch_find_end_paren(data, '{', '}'); - if (!e || !*e) { - goto var_extract_error; - } - /* swallow the opening bracket */ - while ((data + k) && *(data + k)) { - j = k; - k++; - /* note that this affects vars[] */ - data[j] = data[k]; - } - *(--e) = '\0'; - data = e + 1; - } - var_block_count++; - continue; - - var_extract_error: - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n"); - status = SWITCH_STATUS_GENERR; - goto done; - } - - /* strip leading spaces (again) */ - while (data && *data && *data == ' ') { - data++; - } - - if (zstr(data)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "No origination URL specified!\n"); - status = SWITCH_STATUS_GENERR; - goto done; - } /* Some channel are created from an originating channel and some aren't so not all outgoing calls have a way to get params so we will normalize dialstring params and channel variables (when there is an originator) into an event that we @@ -1962,24 +1862,39 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_channel_process_export(caller_channel, NULL, var_event, SWITCH_EXPORT_VARS_VARIABLE); } - if (vars) { /* Parse parameters specified from the dialstring */ - char *var_array[1024] = { 0 }; - int var_count = 0; - if ((var_count = switch_separate_string(vars, ',', var_array, (sizeof(var_array) / sizeof(var_array[0]))))) { - int x = 0; - for (x = 0; x < var_count; x++) { - char *inner_var_array[2] = { 0 }; - int inner_var_count; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "variable string %d = [%s]\n", x, var_array[x]); - if ((inner_var_count = - switch_separate_string(var_array[x], '=', inner_var_array, (sizeof(inner_var_array) / sizeof(inner_var_array[0])))) == 2) { - switch_event_del_header(var_event, inner_var_array[0]); - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, inner_var_array[0], inner_var_array[1]); - } - } - } + + + /* strip leading spaces */ + while (data && *data && *data == ' ') { + data++; } + /* extract channel variables, allowing multiple sets of braces */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Parsing global variables\n"); + while (*data == '{') { + char *parsed = NULL; + + if (switch_event_create_brackets(data, '{', '}', ',', &var_event, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n"); + switch_goto_status(SWITCH_STATUS_GENERR, done); + } + + data = parsed; + } + + + /* strip leading spaces (again) */ + while (data && *data && *data == ' ') { + data++; + } + + if (zstr(data)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "No origination URL specified!\n"); + status = SWITCH_STATUS_GENERR; + goto done; + } + + if (oglobals.session) { switch_event_header_t *hi; const char *cdr_total_var; @@ -2271,8 +2186,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess for (r = 0; r < or_argc; r++) { char *p, *end = NULL; - const char *var_begin, *var_end; - int q = 0; + int q = 0, alt = 0; + check_reject = 1; oglobals.hups = 0; @@ -2309,19 +2224,27 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_yield(sleep_ms * 1000); } } - + p = pipe_names[r]; + while (p && *p) { if (*p == '[') { end = switch_find_end_paren(p, '[', ']'); + if (*(p+1) == '^' && *(p + 2) == '^') { + alt = 1; + } else { + alt = 0; + } + q = 0; } - + if (*p == '\'') { q = !q; } if (end && p < end && *p == ',') { - if (q) { + + if (q || alt) { *p = QUOTED_ESC_COMMA; } else { *p = UNQUOTED_ESC_COMMA; @@ -2343,41 +2266,55 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } for (i = 0; i < and_argc; i++) { - char *vdata; const char *current_variable; - char variable_buffer[512] = ""; switch_event_t *local_var_event = NULL, *originate_var_event = NULL, *event = NULL; - char *check_a = NULL, *check_b = NULL; end = NULL; chan_type = peer_names[i]; + + /* strip leading spaces */ + while (chan_type && *chan_type && *chan_type == ' ') { + chan_type++; + } + + /* extract channel variables, allowing multiple sets of braces */ + + if (*chan_type == '[') { + switch_event_create_plain(&local_var_event, SWITCH_EVENT_CHANNEL_DATA); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Parsing session specific variables\n"); + } + + while (*chan_type == '[') { + char *parsed = NULL; + + for (p = chan_type; p && *p && *p != ']'; p++) { + if (*p == QUOTED_ESC_COMMA) { + *p = ','; + } + } + + if (switch_event_create_brackets(chan_type, '[', ']', UNQUOTED_ESC_COMMA, + &local_var_event, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n"); + switch_goto_status(SWITCH_STATUS_GENERR, done); + } + + chan_type = parsed; + } + + + /* strip leading spaces (again) */ + while (chan_type && *chan_type && *chan_type == ' ') { + chan_type++; + } + while (chan_type && *chan_type && *chan_type == ' ') { chan_type++; } - vdata = chan_type; - end = switch_find_end_paren(vdata, '[', ']'); - - check_a = end; - - while (check_a && (check_b = strchr(check_a, '['))) { - if ((check_b = switch_find_end_paren(check_b, '[', ']'))) { - check_a = check_b; - } - } - - if (check_a) end = check_a; - - if (end) { - vdata++; - *end++ = '\0'; - chan_type = end; - } else { - vdata = NULL; - } - + if ((chan_data = strchr(chan_type, '/')) != 0) { *chan_data = '\0'; chan_data++; @@ -2440,7 +2377,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if (and_argc > 1 || or_argc > 1) { myflags |= SOF_FORKED_DIAL; } - + if (var_event) { const char *vvar; if ((vvar = switch_event_get_header(var_event, "forked_dial")) && switch_true(vvar)) { @@ -2451,80 +2388,30 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } - /* only valid in [] since it's unique to each channel leg */ + + /* Valid in both {} and [] with [] taking precedence */ - if (vdata && (var_begin = switch_stristr("origination_uuid=", vdata))) { - char tmp[512] = ""; - var_begin += strlen("origination_uuid="); - var_end = strchr(var_begin, UNQUOTED_ESC_COMMA); + /* make a special var event with mixture of the {} and the [] vars to pass down as global vars to the outgoing channel + so if something like the user channel does another originate our options will be passed down properly + */ + + switch_event_dup(&originate_var_event, var_event); - if (var_end) { - strncpy(tmp, var_begin, var_end - var_begin); - } else { - strncpy(tmp, var_begin, strlen(var_begin)); - } - - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_uuid", tmp); + if (local_var_event) { + switch_event_merge(originate_var_event, local_var_event); } - /* The rest are valid in both {} and [] with [] taking precedence */ - - current_variable = NULL; - - if (vdata && (var_begin = switch_stristr("origination_caller_id_number=", vdata))) { - var_begin += strlen("origination_caller_id_number="); - var_end = strchr(var_begin, UNQUOTED_ESC_COMMA); - - if (var_end) { - strncpy(variable_buffer, var_begin, var_end - var_begin); - } else { - strncpy(variable_buffer, var_begin, strlen(var_begin)); - } - - current_variable = variable_buffer; - } - - if (current_variable || (current_variable = switch_event_get_header(var_event, "origination_caller_id_number"))) { + if ((current_variable = switch_event_get_header(originate_var_event, "origination_caller_id_number"))) { new_profile->caller_id_number = switch_core_strdup(new_profile->pool, current_variable); myflags |= SOF_NO_EFFECTIVE_CID_NUM; } - current_variable = NULL; - - if (vdata && (var_begin = switch_stristr("origination_caller_id_name=", vdata))) { - var_begin += strlen("origination_caller_id_name="); - var_end = strchr(var_begin, UNQUOTED_ESC_COMMA); - - if (var_end) { - strncpy(variable_buffer, var_begin, var_end - var_begin); - } else { - strncpy(variable_buffer, var_begin, strlen(var_begin)); - } - - current_variable = variable_buffer; - } - - if (current_variable || (current_variable = switch_event_get_header(var_event, "origination_caller_id_name"))) { + if ((current_variable = switch_event_get_header(originate_var_event, "origination_caller_id_name"))) { new_profile->caller_id_name = switch_core_strdup(new_profile->pool, current_variable); myflags |= SOF_NO_EFFECTIVE_CID_NAME; } - current_variable = NULL; - - if (vdata && (var_begin = switch_stristr("origination_privacy=", vdata))) { - var_begin += strlen("origination_privacy="); - var_end = strchr(var_begin, UNQUOTED_ESC_COMMA); - - if (var_end) { - strncpy(variable_buffer, var_begin, var_end - var_begin); - } else { - strncpy(variable_buffer, var_begin, strlen(var_begin)); - } - - current_variable = variable_buffer; - } - - if (current_variable || (current_variable = switch_event_get_header(var_event, "origination_privacy"))) { + if ((current_variable = switch_event_get_header(originate_var_event, "origination_privacy"))) { new_profile->flags = SWITCH_CPF_NONE; if (switch_stristr("screen", current_variable)) { @@ -2540,79 +2427,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } - current_variable = NULL; switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "originate_early_media", oglobals.early_ok ? "true" : "false"); - if (vdata) { - char *var_array[1024] = { 0 }; - int var_count = 0; - char *next; - - - switch_event_create_plain(&local_var_event, SWITCH_EVENT_CHANNEL_DATA); - - - for (;;) { - if ((next = strchr(vdata, ']'))) { - char *pnext; - *next++ = '\0'; - - if ((pnext = switch_strchr_strict(next, '[', " "))) { - next = pnext + 1; - } - } - - if ((var_count = switch_separate_string(vdata, UNQUOTED_ESC_COMMA, var_array, (sizeof(var_array) / sizeof(var_array[0]))))) { - int x = 0; - for (x = 0; x < var_count; x++) { - char *inner_var_array[2] = { 0 }; - int inner_var_count; - char *p; - - for (p = var_array[x]; p && *p; p++) { - if (*p == QUOTED_ESC_COMMA) { - *p = ','; - } - } - - - - if ((inner_var_count = - switch_separate_string(var_array[x], '=', - inner_var_array, (sizeof(inner_var_array) / sizeof(inner_var_array[0])))) == 2) { - - /* this is stupid but necessary: if the value begins with ^^ take the very next char as a delim, - increment the string to start the next char after that and replace every instance of the delim with a , */ - - if (*inner_var_array[1] == '^' && *(inner_var_array[1] + 1) == '^') { - char *iv; - char d = 0; - inner_var_array[1] += 2; - d = *inner_var_array[1]++; - - if (d) { - for(iv = inner_var_array[1]; iv && *iv; iv++) { - if (*iv == d) *iv = ','; - } - } - } - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "local variable string %d = [%s=%s]\n", - x, inner_var_array[0], inner_var_array[1]); - switch_event_add_header_string(local_var_event, SWITCH_STACK_BOTTOM, inner_var_array[0], inner_var_array[1]); - - } - } - } - - if (next) { - vdata = next; - } else { - break; - } - - } - } if (caller_channel && switch_true(switch_channel_get_variable(caller_channel, "push_channel_name"))) { char *new_name = switch_core_session_sprintf(session, "%s__B", switch_channel_get_name(caller_channel)); @@ -2620,16 +2436,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess new_name = switch_core_session_sprintf(session, "_%s", switch_channel_get_name(caller_channel)); switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "sip_h_X-FS-Channel-Name", new_name); } - - /* make a special var event with mixture of the {} and the [] vars to pass down as global vars to the outgoing channel - so if something like the user channel does another originate our options will be passed down properly - */ - switch_event_dup(&originate_var_event, var_event); - - if (local_var_event) { - switch_event_merge(originate_var_event, local_var_event); - } reason = switch_core_session_outgoing_channel(oglobals.session, originate_var_event, chan_type, new_profile, &new_session, NULL, myflags, cancel_cause); diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 6c769ecfd8..bec7eb45a4 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -28,6 +28,7 @@ * Neal Horman * Matt Klein * Michael Jerris + * Marc Olivier Chouinard * * switch_ivr_play_say.c -- IVR Library (functions to play or say audio) * @@ -39,8 +40,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio switch_input_args_t *args) { switch_event_t *hint_data; - switch_xml_t cfg, xml = NULL, language, macros, macro, input, action; - char *lname = NULL, *mname = NULL; + switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL, macro, input, action; switch_status_t status = SWITCH_STATUS_GENERR; const char *old_sound_prefix = NULL, *sound_path = NULL, *tts_engine = NULL, *tts_voice = NULL; const char *module_name = NULL, *chan_lang = NULL; @@ -49,6 +49,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio int matches = 0; const char *pause_val; int pause = 100; + const char *group_macro_name = NULL; + const char *local_macro_name = macro_name; + switch_bool_t sound_prefix_enforced = switch_true(switch_channel_get_variable(channel, "sound_prefix_enforced")); + switch_bool_t local_sound_prefix_enforced = SWITCH_FALSE; if (!macro_name) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No phrase macro specified.\n"); @@ -65,8 +69,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio chan_lang = lang; } - module_name = chan_lang; - switch_event_create(&hint_data, SWITCH_EVENT_REQUEST_PARAMS); switch_assert(hint_data); @@ -82,40 +84,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio } switch_channel_event_set_data(channel, hint_data); - if (switch_xml_locate("phrases", NULL, NULL, NULL, &xml, &cfg, hint_data, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of phrases failed.\n"); + if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, ¯os, chan_lang) != SWITCH_STATUS_SUCCESS) { goto done; } - if (!(macros = switch_xml_child(cfg, "macros"))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros tag.\n"); - goto done; + if ((module_name = switch_xml_attr(language, "say-module"))) { + } else if ((module_name = switch_xml_attr(language, "module"))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute. Use say-module instead\n"); + } else { + module_name = chan_lang; } - if (!(language = switch_xml_child(macros, "language"))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language tag.\n"); - goto done; - } - - while (language) { - if ((lname = (char *) switch_xml_attr(language, "name")) && !strcasecmp(lname, chan_lang)) { - const char *tmp; - - if ((tmp = switch_xml_attr(language, "module"))) { - module_name = tmp; - } - break; + if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) { + if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) { + sound_path = (char *) switch_xml_attr(language, "sound_path"); } - language = language->next; - } - - if (!language) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language %s.\n", chan_lang); - goto done; - } - - if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) { - sound_path = (char *) switch_xml_attr(language, "sound_path"); } if (!(tts_engine = (char *) switch_xml_attr(language, "tts-engine"))) { @@ -126,7 +109,41 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio tts_voice = (char *) switch_xml_attr(language, "tts_voice"); } - if (sound_path) { + /* If we use the new structure, check for a group name */ + if (language != macros) { + char *p; + char *macro_name_dup = switch_core_session_strdup(session, macro_name); + const char *group_sound_path; + const char *sound_prefix_enforced_str; + + if ((p = strchr(macro_name_dup, '@'))) { + *p++ = '\0'; + local_macro_name = macro_name_dup; + group_macro_name = p; + + if (!(macros = switch_xml_find_child(phrases, "macros", "name", group_macro_name))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros group %s.\n", group_macro_name); + goto done; + } + } + /* Support override of certain language attribute */ + if ((group_sound_path = (char *) switch_xml_attr(macros, "sound-prefix")) || (group_sound_path = (char *) switch_xml_attr(macros, "sound-path")) || (group_sound_path = (char *) switch_xml_attr(macros, "sound_path"))) { + sound_path = group_sound_path; + } + + if (sound_prefix_enforced == SWITCH_FALSE && (sound_prefix_enforced_str = switch_xml_attr(macros, "sound-prefix-enforced")) + && (local_sound_prefix_enforced = switch_true(sound_prefix_enforced_str)) == SWITCH_TRUE) { + switch_channel_set_variable(channel, "sound_prefix_enforced", sound_prefix_enforced_str); + } + + } + + if (!(macro = switch_xml_find_child(macros, "macro", "name", local_macro_name))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macro %s.\n", macro_name); + goto done; + } + + if (sound_path && sound_prefix_enforced == SWITCH_FALSE) { char *p; old_sound_prefix = switch_str_nil(switch_channel_get_variable(channel, "sound_prefix")); p = switch_core_session_strdup(session, old_sound_prefix); @@ -134,23 +151,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio switch_channel_set_variable(channel, "sound_prefix", sound_path); } - if (!(macro = switch_xml_child(language, "macro"))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find any macro tags.\n"); - goto done; - } - - while (macro) { - if ((mname = (char *) switch_xml_attr(macro, "name")) && !strcasecmp(mname, macro_name)) { - break; - } - macro = macro->next; - } - - if (!macro) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macro %s.\n", macro_name); - goto done; - } - if ((pause_val = switch_xml_attr(macro, "pause"))) { int tmp = atoi(pause_val); if (tmp >= 0) { @@ -342,6 +342,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio if (old_sound_prefix) { switch_channel_set_variable(channel, "sound_prefix", old_sound_prefix); } + if (local_sound_prefix_enforced == SWITCH_TRUE) { + switch_channel_set_variable(channel, "sound_prefix_enforced", NULL); + } + if (xml) { switch_xml_free(xml); } @@ -828,7 +832,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi } for (;;) { - int done = 0; switch_status_t status; if (!switch_channel_ready(channel)) { @@ -870,7 +873,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi if (switch_channel_has_dtmf(channel)) { if (!args->input_callback && !args->buf && !args->dmachine) { status = SWITCH_STATUS_BREAK; - done = 1; break; } switch_channel_dequeue_dtmf(channel, &dtmf); @@ -898,7 +900,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi } if (status != SWITCH_STATUS_SUCCESS) { - done = 1; break; } } @@ -999,7 +1000,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_status_t status = SWITCH_STATUS_SUCCESS; switch_file_handle_t lfh; const char *p; - char *title = "", *copyright = "", *software = "", *artist = "", *comment = "", *date = ""; + //char *title = "", *copyright = "", *software = "", *artist = "", *comment = "", *date = ""; char *ext; const char *prefix; const char *timer_name; @@ -1231,35 +1232,35 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess } if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_TITLE, &p) == SWITCH_STATUS_SUCCESS) { - title = switch_core_session_strdup(session, p); + //title = switch_core_session_strdup(session, p); switch_channel_set_variable(channel, "RECORD_TITLE", p); } if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, &p) == SWITCH_STATUS_SUCCESS) { - copyright = switch_core_session_strdup(session, p); + //copyright = switch_core_session_strdup(session, p); switch_channel_set_variable(channel, "RECORD_COPYRIGHT", p); } if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, &p) == SWITCH_STATUS_SUCCESS) { - software = switch_core_session_strdup(session, p); + //software = switch_core_session_strdup(session, p); switch_channel_set_variable(channel, "RECORD_SOFTWARE", p); } if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, &p) == SWITCH_STATUS_SUCCESS) { - artist = switch_core_session_strdup(session, p); + //artist = switch_core_session_strdup(session, p); switch_channel_set_variable(channel, "RECORD_ARTIST", p); } if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, &p) == SWITCH_STATUS_SUCCESS) { - comment = switch_core_session_strdup(session, p); + //comment = switch_core_session_strdup(session, p); switch_channel_set_variable(channel, "RECORD_COMMENT", p); } if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_DATE, &p) == SWITCH_STATUS_SUCCESS) { - date = switch_core_session_strdup(session, p); + //date = switch_core_session_strdup(session, p); switch_channel_set_variable(channel, "RECORD_DATE", p); } - + interval = read_impl.microseconds_per_packet / 1000; if (!fh->audio_buffer) { @@ -2310,7 +2311,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses switch_status_t status = SWITCH_STATUS_SUCCESS; switch_speech_handle_t lsh, *sh; switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; - switch_codec_t *read_codec; const char *timer_name, *var; cached_speech_handle_t *cache_obj = NULL; int need_create = 1, need_alloc = 1; @@ -2351,7 +2351,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses timer_name = switch_channel_get_variable(channel, "timer_name"); switch_core_session_reset(session, SWITCH_FALSE, SWITCH_FALSE); - read_codec = switch_core_session_get_read_codec(session); rate = read_impl.actual_samples_per_second; interval = read_impl.microseconds_per_packet / 1000; diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 627aa46707..db4f4fa1dd 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -1681,11 +1681,11 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ switch_mutex_lock(loadable_modules.mutex); for (x = 0; x < preflen; x++) { - char *cur, *last = NULL, *next = NULL, *name, *p, buf[256]; + char *cur, *next = NULL, *name, *p, buf[256]; uint32_t interval = 0, rate = 0, bit = 0; switch_copy_string(buf, prefs[x], sizeof(buf)); - last = name = next = cur = buf; + name = next = cur = buf; for (;;) { if (!next) { diff --git a/src/switch_nat.c b/src/switch_nat.c index e9d4b2b9ca..ebea68e7cb 100644 --- a/src/switch_nat.c +++ b/src/switch_nat.c @@ -586,7 +586,7 @@ SWITCH_DECLARE(switch_status_t) switch_nat_add_mapping_internal(switch_port_t po switch_event_t *event = NULL; if (!nat_globals.mapping) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "NAT port mapping disabled\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "NAT port mapping disabled\n"); return status; } diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 15424b3153..13ce9639c8 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2342,7 +2342,6 @@ static void do_flush(switch_rtp_t *rtp_session) { int was_blocking = 0; switch_size_t bytes; - switch_status_t status; if (!switch_rtp_ready(rtp_session) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) || @@ -2377,7 +2376,7 @@ static void do_flush(switch_rtp_t *rtp_session) do { if (switch_rtp_ready(rtp_session)) { bytes = sizeof(rtp_msg_t); - status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, &bytes); + switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, &bytes); if (bytes) { int do_cng = 0; @@ -3981,14 +3980,14 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL)) { switch_size_t bytes; - char bufa[30]; - const char *tx_host; + //char bufa[30]; + /* Fast PASS! */ if (!switch_test_flag(frame, SFF_PROXY_PACKET) && !switch_test_flag(frame, SFF_UDPTL_PACKET)) { return 0; } bytes = frame->packetlen; - tx_host = switch_get_addr(bufa, sizeof(bufa), rtp_session->remote_addr); + //tx_host = switch_get_addr(bufa, sizeof(bufa), rtp_session->remote_addr); send_msg = frame->packet; diff --git a/src/switch_time.c b/src/switch_time.c index 0fd7d9ee49..7c10233790 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -61,14 +61,20 @@ static int MONO = 1; static int MONO = 0; #endif +/* clock_nanosleep works badly on some kernels but really well on others. + timerfd seems to work well as long as it exists so if you have timerfd we'll also enable clock_nanosleep by default. +*/ #if defined(HAVE_TIMERFD_CREATE) -// We'll default this to 1 after we have had some positive feedback that it works well -static int TFD = 0; +static int TFD = 1; +#if defined(HAVE_CLOCK_NANOSLEEP) +static int NANO = 1; +#else +static int NANO = 0; +#endif #else static int TFD = 0; -#endif - static int NANO = 0; +#endif static int OFFSET = 0; @@ -82,11 +88,6 @@ static DWORD win32_last_get_time_tick = 0; CRITICAL_SECTION timer_section; #endif -static int STEP_MS = 1; -static int STEP_MIC = 1000; -static uint32_t TICK_PER_SEC = 1000; -static int MS_PER_TICK = 10; - static switch_memory_pool_t *module_pool = NULL; static struct { @@ -213,7 +214,7 @@ SWITCH_DECLARE(void) switch_time_calibrate_clock(void) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Timer resolution of %ld microseconds detected!\n" "Do you have your kernel timer frequency set to lower than 1,000Hz? " - "You may experience audio problems. Step MS %d\n", ts.tv_nsec / 1000, STEP_MS); + "You may experience audio problems. Step MS %d\n", ts.tv_nsec / 1000, runtime.microseconds_per_tick / 1000); do_sleep(5000000); switch_time_set_cond_yield(SWITCH_TRUE); return; @@ -326,6 +327,7 @@ SWITCH_DECLARE(void) switch_time_set_timerfd(switch_bool_t enable) #if defined(HAVE_TIMERFD_CREATE) TFD = enable ? 1 : 0; switch_time_sync(); + #else TFD = 0; #endif @@ -433,7 +435,7 @@ SWITCH_DECLARE(void) switch_sleep(switch_interval_time_t t) SWITCH_DECLARE(void) switch_cond_next(void) { - if (globals.timer_count >= runtime.tipping_point) { + if (runtime.tipping_point && globals.timer_count >= runtime.tipping_point) { os_yield(); return; } @@ -502,15 +504,20 @@ static switch_status_t timer_init(switch_timer_t *timer) private_info->roll = TIMER_MATRIX[timer->interval].roll; private_info->ready = 1; - if (timer->interval > 0 && (timer->interval < MS_PER_TICK || (timer->interval % 10) != 0)) { + if ((timer->interval == 10 || timer->interval == 30) && runtime.microseconds_per_tick > 10000) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Increasing global timer resolution to 10ms to handle interval %d\n", timer->interval); + runtime.microseconds_per_tick = 10000; + } + + if (timer->interval > 0 && (timer->interval < (int)(runtime.microseconds_per_tick / 1000) || (timer->interval % 10) != 0)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Increasing global timer resolution to 1ms to handle interval %d\n", timer->interval); - MS_PER_TICK = 1; + runtime.microseconds_per_tick = 1000; switch_time_sync(); } switch_mutex_lock(globals.mutex); globals.timer_count++; - if (globals.timer_count == (runtime.tipping_point + 1)) { + if (runtime.tipping_point && globals.timer_count == (runtime.tipping_point + 1)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Crossed tipping point of %u, shifting into high-gear.\n", runtime.tipping_point); } switch_mutex_unlock(globals.mutex); @@ -593,7 +600,7 @@ static switch_status_t timer_next(switch_timer_t *timer) while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) { check_roll(); - if (globals.timer_count >= runtime.tipping_point) { + if (runtime.tipping_point && globals.timer_count >= runtime.tipping_point) { os_yield(); globals.use_cond_yield = 0; } else { @@ -660,7 +667,7 @@ static switch_status_t timer_destroy(switch_timer_t *timer) switch_mutex_lock(globals.mutex); if (globals.timer_count) { globals.timer_count--; - if (globals.timer_count == (runtime.tipping_point - 1)) { + if (runtime.tipping_point && globals.timer_count == (runtime.tipping_point - 1)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Fell Below tipping point of %u, shifting into low-gear.\n", runtime.tipping_point); } } @@ -671,7 +678,7 @@ static switch_status_t timer_destroy(switch_timer_t *timer) SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) { - switch_time_t too_late = STEP_MIC * 1000; + switch_time_t too_late = runtime.microseconds_per_tick * 1000; uint32_t current_ms = 0; uint32_t x, tick = 0; switch_time_t ts = 0, last = 0; @@ -680,6 +687,8 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) int tfd = -1; #ifdef HAVE_TIMERFD_CREATE + int last_MICROSECONDS_PER_TICK = runtime.microseconds_per_tick; + struct itimerspec spec = { { 0 } }; if (MONO && TFD) { @@ -687,7 +696,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) if (tfd > -1) { spec.it_interval.tv_sec = 0; - spec.it_interval.tv_nsec = 1000000; + spec.it_interval.tv_nsec = runtime.microseconds_per_tick * 1000; spec.it_value.tv_sec = spec.it_interval.tv_sec; spec.it_value.tv_nsec = spec.it_interval.tv_nsec; @@ -733,7 +742,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) runtime.initiated = runtime.reference; break; } - do_sleep(STEP_MIC); + do_sleep(runtime.microseconds_per_tick); last = ts; } } @@ -756,7 +765,17 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) globals.RUNNING = 1; while (globals.RUNNING == 1) { - runtime.reference += STEP_MIC; + +#ifdef HAVE_TIMERFD_CREATE + if (last_MICROSECONDS_PER_TICK != runtime.microseconds_per_tick) { + spec.it_interval.tv_nsec = runtime.microseconds_per_tick * 1000; + timerfd_settime(tfd, TFD_TIMER_ABSTIME, &spec, NULL); + } + + last_MICROSECONDS_PER_TICK = runtime.microseconds_per_tick; +#endif + + runtime.reference += runtime.microseconds_per_tick; while (((ts = time_now(runtime.offset)) + 100) < runtime.reference) { if (ts < last) { @@ -780,15 +799,16 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) rev_errs = 0; } - if (globals.timer_count >= runtime.tipping_point) { + if (runtime.tipping_point && globals.timer_count >= runtime.tipping_point) { os_yield(); } else { if (tfd > -1 && globals.RUNNING == 1) { uint64_t exp; int r; r = read(tfd, &exp, sizeof(exp)); + r++; } else { - do_sleep(1000); + do_sleep(runtime.microseconds_per_tick); } } @@ -800,7 +820,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n"); switch_time_sync(); } else { - switch_time_t diff = ts - runtime.reference - STEP_MIC; + switch_time_t diff = ts - runtime.reference - runtime.microseconds_per_tick; #ifndef WIN32 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Forward Clock Skew Detected!\n"); #endif @@ -821,10 +841,10 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) } runtime.timestamp = ts; - current_ms += STEP_MS; - tick += STEP_MS; + current_ms += (runtime.microseconds_per_tick / 1000); + tick += (runtime.microseconds_per_tick / 1000); - if (tick >= TICK_PER_SEC) { + if (tick >= (1000000 / runtime.microseconds_per_tick)) { if (++profile_tick == 1) { switch_get_system_idle_time(runtime.profile_timer, &runtime.profile_time); profile_tick = 0; @@ -852,8 +872,8 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) #endif - if (MATRIX && (current_ms % MS_PER_TICK) == 0) { - for (x = MS_PER_TICK; x <= MAX_ELEMENTS; x += MS_PER_TICK) { + if (MATRIX && (current_ms % (runtime.microseconds_per_tick / 1000)) == 0) { + for (x = (runtime.microseconds_per_tick / 1000); x <= MAX_ELEMENTS; x += (runtime.microseconds_per_tick / 1000)) { if ((current_ms % x) == 0) { if (TIMER_MATRIX[x].count) { TIMER_MATRIX[x].tick++; @@ -879,8 +899,8 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) } globals.use_cond_yield = 0; - - for (x = MS_PER_TICK; x <= MAX_ELEMENTS; x += MS_PER_TICK) { + + for (x = (runtime.microseconds_per_tick / 1000); x <= MAX_ELEMENTS; x += (runtime.microseconds_per_tick / 1000)) { if (TIMER_MATRIX[x].mutex && switch_mutex_trylock(TIMER_MATRIX[x].mutex) == SWITCH_STATUS_SUCCESS) { switch_thread_cond_broadcast(TIMER_MATRIX[x].cond); switch_mutex_unlock(TIMER_MATRIX[x].mutex); @@ -1116,6 +1136,10 @@ SWITCH_MODULE_LOAD_FUNCTION(softtimer_load) switch_time_set_cond_yield(SWITCH_FALSE); } + if (TFD) { + switch_clear_flag((&runtime), SCF_CALIBRATE_CLOCK); + } + if (switch_test_flag((&runtime), SCF_CALIBRATE_CLOCK)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Calibrating timer, please wait...\n"); switch_time_calibrate_clock(); diff --git a/src/switch_xml.c b/src/switch_xml.c index 00f6ddd48e..243494aa7c 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -25,7 +25,7 @@ * * Anthony Minessale II * Simon Capper - * + * Marc Olivier Chouinard * * switch_xml.c -- XML PARSER * @@ -1851,7 +1851,7 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key, switch_xml_t *domain, switch_xml_t *user, switch_xml_t *ingroup, switch_event_t *params) { switch_status_t status = SWITCH_STATUS_FALSE; - switch_event_t *my_params = NULL, *search_params = NULL; + switch_event_t *my_params = NULL; switch_xml_t group = NULL, groups = NULL, users = NULL; *root = NULL; @@ -1888,10 +1888,6 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key, status = SWITCH_STATUS_FALSE; - if (params != my_params) { - search_params = params; - } - if ((groups = switch_xml_child(*domain, "groups"))) { for (group = switch_xml_child(groups, "group"); group; group = group->next) { if ((users = switch_xml_child(group, "users"))) { @@ -2785,6 +2781,62 @@ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond) { return time_match; } +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_status_t status = SWITCH_STATUS_FALSE; + + if (switch_xml_locate("languages", NULL, NULL, NULL, root, node, params, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) { + switch_xml_t sub_macros; + + if (switch_xml_locate("phrases", NULL, NULL, NULL, root, node, params, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of languages and phrases failed.\n"); + goto done; + } + if (!(sub_macros = switch_xml_child(*node, "macros"))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find macros tag.\n"); + switch_xml_free(*root); + *root = NULL; + *node = NULL; + goto done; + } + if (!(*language = switch_xml_find_child(sub_macros, "language", "name", str_language))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find language %s.\n", str_language); + switch_xml_free(*root); + *root = NULL; + *node = NULL; + goto done; + } + *macros = *language; + } else { + if (!(*language = switch_xml_find_child(*node, "language", "name", str_language))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find language %s.\n", str_language); + switch_xml_free(*root); + *root = NULL; + goto done; + } + if (!(*phrases = switch_xml_child(*language, "phrases"))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find phrases tag.\n"); + switch_xml_free(*root); + *root = NULL; + *node = NULL; + *language = NULL; + goto done; + } + + if (!(*macros = switch_xml_child(*phrases, "macros"))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find macros tag.\n"); + switch_xml_free(*root); + *root = NULL; + *node = NULL; + *language = NULL; + *phrases = NULL; + goto done; + } + } + status = SWITCH_STATUS_SUCCESS; + +done: + return status; +} #ifdef WIN32 /* diff --git a/src/switch_xml_config.c b/src/switch_xml_config.c index 5ade057b37..31f44ce175 100644 --- a/src/switch_xml_config.c +++ b/src/switch_xml_config.c @@ -337,7 +337,7 @@ SWITCH_DECLARE(switch_status_t) switch_xml_config_parse_event(switch_event_t *ev int32_t *dest = (int32_t *) ptr; int index = (int) (intptr_t) item->data; int8_t currentval = (int8_t) ! !(*dest & index); - int8_t newval = 0; + int newval = 0; if (value) { newval = switch_true(value);
+ 35716ecf:2 + 98e6c103:0 +