diff --git a/conf/autoload_configs/modules.conf.xml b/conf/autoload_configs/modules.conf.xml index 8b4a4e7ea4..0e485b24e3 100644 --- a/conf/autoload_configs/modules.conf.xml +++ b/conf/autoload_configs/modules.conf.xml @@ -52,6 +52,7 @@ + diff --git a/conf/autoload_configs/switch.conf.xml b/conf/autoload_configs/switch.conf.xml index 95c43331e4..4f72c6a65d 100644 --- a/conf/autoload_configs/switch.conf.xml +++ b/conf/autoload_configs/switch.conf.xml @@ -98,7 +98,9 @@ - + + + diff --git a/docs/ChangeLog b/docs/ChangeLog index 41f94d78ab..356cbdc852 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -35,6 +35,7 @@ freeswitch (1.0.7) config: Disallow global-intercept and group-intercept can intercept an outbound call in default dialplan (r:890871ba/FS-2777) config: fix single domain assumption in default config to be more portable *cough* bkw *cough* (r:f987903e) config: Bump Doxygen.conf version to 1.0.6... belatedly (r:cfeae1ba) + config: docs for acl (r:57b410eb) core: Add RTCP support (FSRTP-14) core: handle some errors on missing db handle conditions core: add ... and shutdown as a fail-safe when no modules are loaded @@ -164,6 +165,24 @@ freeswitch (1.0.7) core: drop rtp frame that was already replaced with a cng frame (r:34a0ca50) core: fix partial match counting as exact match in dmachine (r:5eb951aa) core: try to adjust the timer to be ok with the horrible 10000 microsecond kernel resolution on amazon ec3 but that doesn't mean it's not horribly wrong to run the kernel that slow (r:903b2901) + core: make exact matches return sooner in dmachine (r:e897646e) + core: don't let inherit_codec work when we have ep_codec_string set and the B-leg codec is not in that list since it will lead to failure (r:f79f9766) + core: set maximum query run time to 30 seconds at least on drivers that support SQL_ATTR_QUERY_TIMEOUT (r:5bb525e1) + core: dd switch_cache_db_affected_rows() to switch_core_sqldb (and switch_odbc) and expose it through Lua dbh:affected_rows() (r:d79cf484/FS-2962) + core: add bind meta on A-D and refactor (r:27869d7a) + core: add temp_hold_music var that is only valid until you transfer the call and finishing touches on bind meta to A-D (r:b262f44c) + core: add function to help set session read codec to slinear (r:1a08df9b) + core: add rtp_bug IGNORE_DTMF_DURATION to speed up dtmf detection of RFC2833 on strange carriers (r:b3fc001e) + core: Fix crash when re-connecting to non-working database server (r:29daaa07/FS-2960) + core: treat EINTR returns as a BREAK (now mapped to SWITCH_STATUS_INTR), we appriciate the interrupted syscalls but we would like to continue working properly (r:316963c5) + core: eat rtp frames with the wrong payload type number (r:fe1711fd) + core: up assert vaule on header loop detection to 1 meeeeelyonne for hmmhesegs (r:d9c56345) + core: Fix race condition in originate where USER_BUSY is reported as a no answer (r:cc06fdb5/FS-2992) + core: Allow check ip change to be optional (r:1cf79386/FS-2917) + core: handle 2833 in do_flush instead of dropping valid dtmf (r:3fa3e11c/FS-3002) + core: add record_restart_time_limit_on_dtmf var (r:7a1dcb69) + core: fix unreachable condition with a null args to make any key stop playback/record etc without dequing and remove hard-coded flush digits in play_and_get_digits be sure to flush it yourself before using (r:976859bb) + core: Fix a lock on reloadxml when stderr write is blocked. Also remove an error parsing print since reason generated were wrong and duplicate. (r:2d6161e8) embedded languages: Provide core level support for conditional Set Global Variable (r:c017c24b/FSCORE-612) embedded languages: add insertFile front end to switch_ivr_insert_file and reswig (r:c4e350ab) lang: Improve French phrase files (FSCONFIG-23) @@ -188,11 +207,14 @@ freeswitch (1.0.7) libesl: Make last_event pointer last longer (r:a15f51d5/ESL-37) libesl: use a packet buffer for ESL (r:2081bf97) libesl: Noevent/Noevents disparity (r:d29d83d7/ESL-53) + libesl: FS-2957 esl lib on windows fails to build (r:5254df04/FS-2957) + libesl: Small fix on ESL that cause event_id to be set wrong on headers that had value failure. (r:eb88304a) libfreetdm: implemented freetdm config nodes and ss7 initial configuration libfreetdm: fix codec for CAS signaling (r:b76e7f18) libfreetdm: freetdm: ss7- added support for incoming group blocks, started adding support for ansi (r:c219a73c) libg7221: A bunch of tweaks to the G.722.1 codec (r:5d548570) libgnutls: link to libgcrypt as well, please report any platforms this breaks, but it should be portable (r:c569fb0f/FS-1248) + libjs: non-portable comment syntax in .s files libopenzap: Add CLI tracing libs: Merged OpenZAP and FreeTDM into the FreeSWITCH tree. libs: Add support for TLS on Windows using openssl (r:1abe3b93/MODSOFIA-92) @@ -207,6 +229,7 @@ freeswitch (1.0.7) libspandsp: Fix Windows build after libspandsp update (r:d70cc852/FSBUILD-293) libspandsp: Fix for T.30 processing of operator interrupts, to improve compatibility with some machines, which seem to send them when no operator is around. (r:84ee0ae6) libspandsp: spandsp t38 fax receiving error in win XP - regression from f029f7ef (r:761cec8f/FS-2766) + libspandsp: Added missing error codes when an ECM FAX is abandoned with the T30_ERR message (r:ec57dc7a) mod_avmd: Initial check in - Advanced Voicemail Detect (r:10c6a30a) (by Eric Des Courtis) mod_avmd: Add to windows build (r:df4bd935) mod_avmd: Fix mem leak (r:cd951384/FS-2839) @@ -229,8 +252,12 @@ freeswitch (1.0.7) mod_callcenter: Fix bad return type so it compile on archlinux, thx bougyman (r:3a475986) mod_callcenter: Make callcenter_config agent get return the value of the item requested. Also added queue param max-wait-time-with-no-agent-time-reached: If the max-wai-time-with-no-agent is already reached for the queue, then new caller can wait for x amount of second before it kicked out of the queue rather than get rejected automatically. (r:81a03869) mod_callcenter: Add new event socket agent-offering. Plus some documentation and better handling of bad agent type -- FS-2869 (r:80174cf3/FS-2869) + mod_callcenter: Add error response for queue load and queue reload (FS-2988) (r:49a5effc/FS-2988) mod_cdr_sqlite: initial commit (r:f625fe3b) mod_cdr_sqlite: config file for mod_cdr_sqlite (r:25bc8fe3) + mod_cdr_sqlite: Drop transaction BEGIN/END around INSERT. We're only executing one command, and autocommit will automatically rollback if the INSERT fails. Sync state_handlers with mod_cdr_csv. Minor libpq fixups. (r:0f95b870) + mod_celt: Bump celt to 0.10.0 (r:231fbe5e) + mod_celt: update code in mod_celt to match API of 0.10.0 (r:6e4c30ea) mod_cidlookup: null xml is bad (r:095815f8) mod_cid_lookup: honor skipcitystate when using whitepages (r:a66654de/FSMOD-53) mod_commands: make break uuid_break and add cascade flag @@ -252,6 +279,7 @@ freeswitch (1.0.7) mod_commands: Dramatic jitterbuffer changes (r:d5470961) mod_commands: add uuid_buglist to fetch the current media-bugs attached to a given session uuid (r:f6eab64c) mod_commands: add recovery_refresh app and api and use it in mod_conference to send a message to the channel telling it to sync its recovery snapshot (r:650393fb) + mod_commands: add moh by default to uuid_broadcast when only broadcasting to A leg use aleg arg to disable this (r:d164a797) mod_conference: Fix reporting of volume up/down (MODAPP-419) mod_conference: add last talking time per member to conference xml list mod_conference: add terminate-on-silence conference param @@ -265,6 +293,10 @@ freeswitch (1.0.7) mod_conference: Add a chan var conference_enter_sound to override conference enter-sound param on the profile (r:651acc62) mod_conference: Add an unique id to the conference obj so that we can track conferences. (r:479f3de2) mod_conference: Fix corrupted audio when playing "you are now (un)muted..." (r:10257c7d/FS-2768) + mod_conference: clear last_transferred conference when you exit the conference app (r:fb017a52) + mod_conference: Add energy level to conference_add_event_member_data (r:8d6d52e0) + mod_conference: if more digits than the length of the correct pin the remaining digits are accounted for next retry (r:b88cd345/FS-3000) + mod_conference: Fix unexpected behavior with endconf and auto-outcalls and pre_answer (r:6f58e6aa/FS-2771) mod_curl: use method=post when post requested (r:c6a4ddd0/FSMOD-69) mod_db: fix stack corruption (MODAPP-407) mod_dialplan_xml: Add in the INFO log the caller id number when processing a request (Currenly only show the caller name) (r:e1df5e13) @@ -282,12 +314,16 @@ freeswitch (1.0.7) mod_dptools: refactor export code and add new bridge_export app which is like export but exports across when one channel bridges another (r:4aa9a838) mod_dptools: add bind_digit_action application (r:9537197b) mod_dptools: emit event when user presses DTMFs (r:37298f56) + mod_dptools: Log error when there's no IVR menus configured when you call 'ivr' DP app (r:30034891) + mod_easyroute: Fix possible segfaults and memory leak during unload, and add new setting odbc-retries (r:7fbc47f8/FS-2973) mod_erlang_event: Make XML fetch reply ACKs distinguishable, update freeswitch.erl (r:9d44ed04) mod_erlang_event: Add 3 new commands; session_event, session_noevents, session_nixevent (r:698fa045) mod_erlang_event: generate long node names the same as erlang does (r:9ad509c2) mod_erlang_event: Improve some logging to include UUIDs (r:c0d51b83) mod_erlang_event: Support for reading erlang cookie from a file (r:094ffe37) mod_erlang_event: Rewrite XML fetch conditional wait to be more sane (Reported by James Aimonetti) (r:6941c6eb/FS-2775) + mod_erlang_event: Don't urlencode events (and destroy an event after use) (r:4eccdfef) + mod_erlang_event Add proper locking for the list of XML bindings (r:9fe440b2) mod_event_socket: fix up other users of switch_event_xmlize() to use SWITCH_EVENT_NONE (r:d6eb7562) mod_event_socket: Fix small mem leaks (r:e4f90584/MODEVENT-68) mod_event_socket: Add "-ERR" to api cmd response when failure occurs (r:58759052/FS-2827) @@ -301,6 +337,8 @@ freeswitch (1.0.7) mod_fifo: add outbound_ring_timeout param to mod_fifo (r:3885eea7) mod_fifo: add default_lag to fifo (r:dd4fb5be) mod_fifo: Fix crash when using fifo_destroy_after_use (r:ee562c82/FS-2879) + mod_fifo: don't seg in edge case error conditions (r:9ee13b72) + mod_fifo: set tracking data before enabling hooks (r:34267869) mod_freetdm: Fix for TON and NPI not passed through to channel variables on incoming calls mod_freetdm: add pvt data to freetdm channels fix fxs features (r:9d456900) mod_freetdm: export and import boost custom data (r:edb2d582) @@ -334,6 +372,7 @@ freeswitch (1.0.7) mod_freetdm: created cmake files for freetdm (r:fc55997b) mod_freetdm: ss7 - added support to control mtp2, mtp3, and isup timers via freetdm.conf.xml (r:4455d581) mod_freetdm: made ftmod_r2 use FTDM_SPAN_USE_SIGNALS_QUEUE and properly send FTDM_SIGEVENT_SIGSTATUS_CHANGED (r:af5f0a4a) + mod_fsk: add mod_fsk (r:fcc912a9) mod_gsmopen: copy from branch mod_gsmopen: fix FS-2793, compilation stops (r:355c0dbb/FS-2793) mod_gsmopen: retry serial initialization if failed, zeroing audio buffers, slower retry on soundcard busy (EAGAIN) (r:c7aefe93) @@ -351,6 +390,7 @@ freeswitch (1.0.7) mod_hash: use 5 seconds connection timeouts for remote connections (r:7431fbe9) mod_hash: use esl_recv_timed with a 5000ms timeout when doing api commands (r:27d8378f) mod_hash: limit_remote_thread sending invalid handle to esl_connect_timeout causing core (r:6cdd3e2a/MODAPP-446) + mod_hash: avoid scheduler caling a function on null hash during shutdown (r:8458adeb) mod_h323: initial t.38 support. remake logical channel opening. add missing param name in example config. (r:8c58074c) mod_h323: some t.38 and lockinng improvements. replace ptrace with switch_log_printf. (r:5efe5c88) mod_h323: add missing conf prameter (r:0b353d7a) @@ -379,6 +419,8 @@ freeswitch (1.0.7) mod_lua: Made 2nd arg to freeswitch.Dbh:query (cb func) optional (r:87db11af) mod_lua: Added SAF_ROUTING_EXEC flag to lua app, so it can be run inline (r:7d5ca1c0) mod_lua: spelling error in -ERR return code encounterd -> encountered (r:86e7cdc5/FS-2949) + mod_lua: Make dbh:connected accessible from Lua - thanks Grmt (r:09e6fd3f) + mod_lua: Added optional core: prefix to first arg passed to freeswitch.Dbh for giving direct access to sqlite db (r:a0181479) mod_managed: Added wrapper for switch_event_bind for .net (r:a5f07a80/MODLANG-165) mod_managed: add additional support (r:5be58aac) mod_managed: add mono 2.8 patch file see FS-2774 (r:6a948bd9/FS-2774) @@ -442,6 +484,7 @@ freeswitch (1.0.7) 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) + mod_snmp: initial checkin of mod_snmp (r:6e2b1bd3) mod_sofia: Send SIP MESSAGE to unregistered users by prefixing sip: to user@domain mod_sofia: fix callee being updated with callee information mod_sofia: set appearance-index in update statement for SLA @@ -548,6 +591,20 @@ freeswitch (1.0.7) mod_sofia: improve fail2ban logging (r:f4d52d4c/FS-2943) mod_sofia: refactor sofia_contact to try the profile_name first then the domain to resolve the profile then fall back to querying every profile to reduce confusion with multi-homers (d'oh) also special profile name * will force a search-all situation (r:81608da0) mod_sofia: support allowing pidf-ful presence clients to share the same account and 'appear offline' without influencing each other =/ also refactor the contact generation string based on nat into a helper function (r:97a68c50) + mod_sofia: gateway not identified when extension-in-contact is set (r:7b289941/FS-502) + mod_sofia: Fix erroneous error log on SQL statement (r:2c595a6c/FS-2961) + mod_sofia: Fix routing behavior of inbound calls from gateways that only match gateway based on the gw request uri param (r:0132cd3f) + mod_sofia: don't say we are not for polycom phones (safe rport) when its not really nat (r:9462f53c) + mod_sofia: Set route header as a var on channel like Diversion header (r:d41e6498) + mod_sofia: fix seg related to ptime mismatch + CNG + PLC (if you ever get purple ptime mismatch warnings you want this patch) (r:54de293b) + mod_sofia: be more iOS friendly when using TCP or TLS because the phone never sleeps thus drains the battery (r:159ae989) + mod_sofia: add send-presence-on-register (true|false|first-only) param to sofia and api command sofia global debug [presence|sla|none] + mod_sofia: disable media timeout when encountering a recvonly stream (r:029d68ce) + mod_sofia: fix sofia flush_inbound_reg to work when @domain is given (r:68bf642c) + mod_sofia: fix session timer failure when freeswitch is generating the sdp and there are enough dynamic codecs enabled to conflict with the 2833 pt (4 by default) (r:018a3800) + mod_sofia: Places ;fs_path= within the contact string <...> when using NDLB-connectile-dysfunction-2.0, instead of just appending to the end of the contact string. (r:afc02747/FS-2989) + mod_sofia: Fix handling SUBSCRIBE to "park+" fifo, the NOTIFY data was not being generated from mod_fifo data. (r:3dd9d5c0/FS-3007) + mod_sofia: fsctl pause improvements (r:008e527c/FS-3012) 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) @@ -559,6 +616,7 @@ freeswitch (1.0.7) mod_spandsp: deadlock in mod_spandsp (mod_spandsp_fax.c) (r:b02c69bb/FS-1690) 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_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) @@ -579,10 +637,14 @@ freeswitch (1.0.7) mod_voicemail: add quotes to vm_cc command generated internally to escape spaces in the caller id name (r:5f012813) mod_voicemail: Play caller id of callee prior to playing a vmail (r:e7b97907/FS-2719) mod_voicemail: FS-1776 Add support for per user operator exten override param vm-operator-extension (r:df5b3498/FS-1776) + mod_voicemail: Set email address from within directory (r:83ce26b2/FS-2972) + mod_voicemail: add events for record/change greeting and record name (r:54421f59) + mod_voicemail: let vmain-key and operator-key be set empty (r:de49305a) 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) mod_xml_cdr: fix minor memory leaks and config bug (r:19253d83/MODEVENT-62) + mod_xml_cdr: Fix prefix-a-leg not respected for url submission (r:ea9021a2/FS-2998) mod_xml_rpc: Fix crash if unauthorized XML RPC is attempted (r:9835395c/FS-184) scripts: added honeypot.pl and blacklist.pl which add extra SIP security options (r:b6a81ba7) scripts: do simple verification to make sure we are getting IP addresses from VoIP abuse blacklist (r:b0049160) diff --git a/freeswitch.spec b/freeswitch.spec index 7fb9f80d8e..1000a89239 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -27,6 +27,14 @@ # Maintainer(s): Michal Bielicki 910 @@ -282,14 +295,72 @@ German language phrases module and directory structure for say module and voicem Summary: Provides a unified interface to hardware TDM cards and ss7 stacks for FreeSWITCH Group: System/Libraries Requires: %{name} = %{version}-%{release} -%{?with_sang_isdn: Requires: wanpipe } -%{?with_sang_isdn: Requires: libsng_isdn } -%{?with_sang_isdn: BuildRequires: wanpipe } -%{?with_sang_isdn: BuildRequires: libang_isdn } %description freetdm FreeTDM +%if %{build_sng_isdn} + +%package freetdm-sng-isdn +Summary: Sangoma ISDN Module for FreeTDM +Group: System/Libraries +Requires: %{name} = %{version}-%{release} +Requires: %{name}-freetdm = %{version}-%{release} +Requires: wanpipe +Requires: libsng_isdn +BuildRequires: wanpipe +BuildRequires: libsng_isdn + +%description freetdm-sng-isdn +Sangoma ISDN Module for freetdm + +%endif + +%if %{build_sng_ss7} + +%package freetdm-sng-ss7 +Summary: Provides a unified interface to hardware TDM cards and ss7 stacks for FreeSWITCH, Sangoma SS7 Module +Group: System/Libraries +Requires: %{name} = %{version}-%{release} +Requires: %{name}-freetdm = %{version}-%{release} +Requires: wanpipe +Requires: libsng_ss7 +BuildRequires: wanpipe +BuildRequires: libsng_ss7 + +%description freetdm-sng-ss7 +Sangoma SMG-SS7 drivers for FreeTDM + +%endif + + +%if %{build_sng_tc} + +%package sangoma-codec +Summary: Sangoma D100 and D500 Codec Card Support +Group: System/Libraries +Requires: %{name} = %{version}-%{release} +Requires: sng-tc-linux +BuildRequires: sng-tc-linux + +%description sangoma-codec +Sangoma D100 and D500 Codec Card Support + +%endif + +%package skypopen +Summary: Skype Endpoint +Group: System/Libraries +Requires: %{name} = %{version}-%{release} +Requires: libX11 +BuildRequires: libX11-devel + +%description skypopen +This software (Skypopen) uses the Skype API but is not endorsed, certified or otherwise approved in any way by Skype. +Skypopen is an endpoint (channel driver) that uses the Skype client as an interface to the Skype network, and allows +incoming and outgoing Skype calls to/from FreeSWITCH (that can be bridged, originated, answered, etc. as in all other +endpoints, e.g. Sofia-SIP). + ###################################################################################################################### # # Unpack and prepare Source archives, copy stuff around etc .. @@ -309,6 +380,8 @@ cp %{SOURCE8} libs/ cp %{SOURCE9} libs/ cp %{SOURCE10} libs/ cp %{SOURCE11} libs/ +cp %{SOURCE12} libs/ +cp %{SOURCE13} libs/ ###################################################################################################################### # @@ -358,7 +431,11 @@ ASR_TTS_MODULES="asr_tts/mod_pocketsphinx asr_tts/mod_flite asr_tts/mod_unimrcp" # ###################################################################################################################### CODECS_MODULES="codecs/mod_bv codecs/mod_h26x codecs/mod_speex codecs/mod_celt codecs/mod_codec2 codecs/mod_ilbc codecs/mod_mp4v \ - codecs/mod_silk codecs/mod_siren codecs/mod_theora" + codecs/mod_opus codecs/mod_silk codecs/mod_siren codecs/mod_theora " +# +%if %{build_sng_tc} +CODECS_MODULES+="codecs/mod_sangoma_codec" +%endif ###################################################################################################################### # # Dialplan Modules @@ -377,7 +454,7 @@ DIRECTORIES_MODULES="" # ###################################################################################################################### ENDPOINTS_MODULES="endpoints/mod_dingaling endpoints/mod_loopback ../../libs/freetdm/mod_freetdm endpoints/mod_portaudio \ - endpoints/mod_sofia" + endpoints/mod_sofia endpoints/mod_skinny endpoints/mod_skypopen" ###################################################################################################################### # @@ -483,11 +560,13 @@ fi %{?configure_options} #Create the version header file here -cat src/include/switch_version.h.in | sed "s/@SVN_VERSION@/%{version}/g" > src/include/switch_version.h -touch .noversion +#cat src/include/switch_version.h.in | sed "s/@SVN_VERSION@/%{version}/g" > src/include/switch_version.h +#touch .noversion %{__make} +cd libs/esl +%{__make} pymod ###################################################################################################################### # @@ -503,6 +582,11 @@ touch .noversion %{__mkdir} -p %{buildroot}%{logfiledir} %{__mkdir} -p %{buildroot}%{runtimedir} +#install the esl stuff +cd libs/esl +%{__make} DESTDIR=%{buildroot} pymod-install +cd ../.. + %ifos linux # Install init files # On SuSE: @@ -522,6 +606,23 @@ touch .noversion # Add monit file %{__install} -D -m 644 build/freeswitch.monitrc %{buildroot}/etc/monit.d/freeswitch.monitrc %endif +###################################################################################################################### +# +# Remove files that are not wanted if they exist +# +###################################################################################################################### + +%if %{build_sng_ss7} +#do not delete a thing +%else +%{__rm} -f %{buildroot}/%{prefix}/mod/ftmod_sangoma_ss7* +%endif +%if %{build_sng_isdn} +#do not delete a thing +%else +%{__rm} -f %{buildroot}/%{prefix}/mod/ftmod_sangoma_isdn* +%endif + ###################################################################################################################### @@ -545,8 +646,6 @@ fi chkconfig --add freeswitch - - %postun ###################################################################################################################### # @@ -790,6 +889,7 @@ fi %{prefix}/mod/mod_mp4v.so* %{prefix}/mod/mod_native_file.so* %{prefix}/mod/mod_nibblebill.so* +%{prefix}/mod/mod_opus.so* %{prefix}/mod/mod_pocketsphinx.so* %{prefix}/mod/mod_portaudio.so* %{prefix}/mod/mod_portaudio_stream.so* @@ -798,6 +898,7 @@ fi %{prefix}/mod/mod_shout.so* %{prefix}/mod/mod_silk.so* %{prefix}/mod/mod_siren.so* +%{prefix}/mod/mod_skinny.so* %{prefix}/mod/mod_sndfile.so* %{prefix}/mod/mod_snom.so* %{prefix}/mod/mod_sofia.so* @@ -831,7 +932,7 @@ fi %{prefix}/include/*.h ###################################################################################################################### # -# OpenZAP Module for TDM Interaction +# FreeTDM Module for TDM Interaction # ###################################################################################################################### %files freetdm @@ -844,7 +945,26 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/zt.conf %{prefix}/lib/libfreetdm.so* %{prefix}/mod/mod_freetdm.so* -%{prefix}/mod/ftm*.so* +%{prefix}/mod/ftmod_skel*.so* +%{prefix}/mod/ftmod_[a-r,t-z]*.so* + +%if %{build_sng_tc} +%files sangoma-codec +%defattr(-, freeswitch, daemon) +%{prefix}/mod/mod_sangoma_codec.so* +%endif + +%if %{build_sng_ss7} +%files freetdm-sng-ss7 +%defattr(-, freeswitch, daemon) +%{prefix}/mod/ftmod_sangoma_ss7.so* +%endif + +%if %{build_sng_isdn} +%files freetdm-sng-isdn +%defattr(-, freeswitch, daemon) +%{prefix}/mod/ftmod_sangoma_isdn.so* +%endif ###################################################################################################################### # @@ -899,9 +1019,14 @@ fi %defattr(-,freeswitch,daemon) %{prefix}/mod/mod_python*.so* %attr(0644, root, bin) /usr/lib/python*/site-packages/freeswitch.py* +%attr(0755, root, bin) /usr/lib/python*/site-packages/_ESL.so* +%attr(0755, root, bin) /usr/lib/python*/site-packages/ESL.py* %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/autoload_configs %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/python.conf.xml +%files skypopen +%defattr(-,freeswitch,daemon) +%{prefix}/mod/mod_skypopen.so* ###################################################################################################################### # # Language Modules @@ -956,6 +1081,17 @@ fi # ###################################################################################################################### %changelog +* Wed Feb 16 2011 - michal.bielicki@seventhsignal.de +- added mod_skinny +- added sangoma libraries +- added sangoma codec module for D100 and D150 and D500 +- added skypopen module +- fixes for ss7 freetdm modules +- added mod_opus +- added selector for sangoma modules +- addded python esl module to rpm +- some minor cleanups +- cut sangoma modules into separate rpms as addons for freetdm * Tue Jan 18 2011 - michal.bielicki@seventhsignal.de - Fedora adjustments * Fri Oct 15 2010 - michal.bielicki@seventhsignal.de @@ -1090,3 +1226,4 @@ fi - Added devel package * Thu Mar 15 2007 - peter+rpmspam@suntel.com.tr - Initial RPM release + diff --git a/libs/esl/Makefile b/libs/esl/Makefile index ab50bac4d9..fbc870ac24 100644 --- a/libs/esl/Makefile +++ b/libs/esl/Makefile @@ -95,4 +95,7 @@ managedmod: $(MYLIB) phpmod-install: phpmod $(MAKE) -C php install +pymod-install: pymod + $(MAKE) -C python install + everymod: perlmod phpmod luamod pymod rubymod javamod managedmod diff --git a/libs/esl/java/Makefile b/libs/esl/java/Makefile index 9474a83276..3606edf331 100644 --- a/libs/esl/java/Makefile +++ b/libs/esl/java/Makefile @@ -1,4 +1,4 @@ -LOCAL_CFLAGS=-I../src/include -I/usr/java/jdk1.6.0_14/include -I/usr/java/jdk1.6.0_14/include/linux -I/usr/lib/jvm/java-6-openjdk/include/ +LOCAL_CFLAGS=-I../src/include -I/usr/java/jdk1.6.0_14/include -I/usr/java/jdk1.6.0_14/include/linux -I/usr/lib/jvm/java-6-openjdk/include/ -I/usr/lib/jvm/java/include -I/usr/lib/jvm/java/include/linux GCC_WARNING_JUNK=-w CLASSES=org/freeswitch/esl/* diff --git a/libs/esl/php/Makefile b/libs/esl/php/Makefile index 44fdd22dae..e970ff7d82 100644 --- a/libs/esl/php/Makefile +++ b/libs/esl/php/Makefile @@ -25,6 +25,6 @@ swigclean: reswig: swigclean esl_wrap.cpp install: ESL.so - cp ESL.so $(shell php-config --extension-dir) - cp ESL.php $(shell php -r 'echo ini_get("include_path");' | cut -d: -f2) - echo 'extension=ESL.so' >> $(shell php-config --configure-options | tr " " "\n" | grep -- --with-config-file-scan-dir | cut -f2 -d=)/esl.ini + cp ESL.so $(DESTDIR)/$(shell php-config --extension-dir) + cp ESL.php /$(DESTDIR)/$(shell php -r 'echo ini_get("include_path");' | cut -d: -f2) + echo 'extension=ESL.so' >> $(DESTDIR)/$(shell php-config --configure-options | tr " " "\n" | grep -- --with-config-file-scan-dir | cut -f2 -d=)/esl.ini diff --git a/libs/esl/python/Makefile b/libs/esl/python/Makefile index 758aeaf500..7504665561 100644 --- a/libs/esl/python/Makefile +++ b/libs/esl/python/Makefile @@ -1,5 +1,6 @@ LOCAL_CFLAGS=`python ./python-config --includes` LOCAL_LDFLAGS=`python ./python-config --ldflags` +SITE_DIR=$(DESTDIR)/`python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"` all: _ESL.so @@ -12,6 +13,10 @@ esl_wrap.o: esl_wrap.cpp _ESL.so: esl_wrap.o $(CXX) $(SOLINK) esl_wrap.o $(MYLIB) $(LOCAL_LDFLAGS) -o _ESL.so -L. $(LIBS) +install: _ESL.so + install -m 755 _ESL.so $(SITE_DIR) + install -m 755 ESL.py $(SITE_DIR) + clean: rm -f *.o *.so *~ diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am index b3353f32de..a26035b2ef 100644 --- a/libs/freetdm/Makefile.am +++ b/libs/freetdm/Makefile.am @@ -39,7 +39,6 @@ libdir = @libdir@ library_includedir = $(prefix)/include INCS = -I$(FT_SRCDIR)/$(SRC)/include -I$(FT_SRCDIR)/$(SRC)/include/private -INCS += -I$(FT_SRCDIR)/$(SRC)/ftmod/ftmod_sangoma_boost if HAVE_SNG_SS7 INCS += -I/usr/include/sng_ss7 @@ -109,7 +108,6 @@ core-install: install-libLTLIBRARIES # tools & test programs # noinst_PROGRAMS = testtones detect_tones detect_dtmf testpri testr2 testanalog testapp testcid -noinst_PROGRAMS += testsangomaboost testapp_SOURCES = $(SRC)/testapp.c testapp_LDADD = libfreetdm.la @@ -143,17 +141,6 @@ testr2_SOURCES = $(SRC)/testr2.c testr2_LDADD = libfreetdm.la testr2_CFLAGS = $(AM_CFLAGS) $(FTDM_CFLAGS) -if HAVE_SCTP -noinst_PROGRAMS += testboost -testboost_SOURCES = $(SRC)/testboost.c -testboost_LDADD = libfreetdm.la -testboost_CFLAGS = $(AM_CFLAGS) $(FTDM_CFLAGS) -endif - -testsangomaboost_SOURCES = $(SRC)/testsangomaboost.c -testsangomaboost_LDADD = libfreetdm.la -testsangomaboost_CFLAGS = $(AM_CFLAGS) $(FTDM_CFLAGS) - testanalog_SOURCES = $(SRC)/testanalog.c testanalog_LDADD = libfreetdm.la testanalog_CFLAGS = $(AM_CFLAGS) $(FTDM_CFLAGS) @@ -201,14 +188,6 @@ ftmod_isdn_la_LDFLAGS = -shared -module -avoid-version $(LIBISDN_LDFLAGS) $(PCA ftmod_isdn_la_LIBADD = libfreetdm.la $(LIBISDN_LIBS) $(PCAP_LIBS) endif -if HAVE_SCTP -mod_LTLIBRARIES += ftmod_sangoma_boost.la -ftmod_sangoma_boost_la_SOURCES = $(SRC)/ftmod/ftmod_sangoma_boost/sangoma_boost_client.c $(SRC)/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c -ftmod_sangoma_boost_la_CFLAGS = $(AM_CFLAGS) $(FTDM_CFLAGS) -ftmod_sangoma_boost_la_LDFLAGS = -shared -module -avoid-version -ftmod_sangoma_boost_la_LIBADD = libfreetdm.la -endif - if HAVE_LIBPRI mod_LTLIBRARIES += ftmod_libpri.la ftmod_libpri_la_SOURCES = $(SRC)/ftmod/ftmod_libpri/ftmod_libpri.c $(SRC)/ftmod/ftmod_libpri/lpwrap_pri.c diff --git a/libs/freetdm/configure.ac b/libs/freetdm/configure.ac index 1f4fc9c6ac..38f849b9e6 100644 --- a/libs/freetdm/configure.ac +++ b/libs/freetdm/configure.ac @@ -121,8 +121,7 @@ AC_CHECK_LIB([dl], [dlopen]) AC_CHECK_LIB([pthread], [pthread_create]) AC_CHECK_LIB([m], [cos]) -AC_CHECK_HEADERS([netinet/sctp.h netdb.h sys/select.h]) -AM_CONDITIONAL([HAVE_SCTP],[test "${ac_cv_header_netinet_sctp_h}" = "yes"]) +AC_CHECK_HEADERS([netdb.h sys/select.h]) AC_CHECK_FUNC([gethostbyname_r], [], [AC_CHECK_LIB([nsl], [gethostbyname_r])] diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 260892ada0..cd2c4850a4 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2175,8 +2175,6 @@ static ftdm_status_t _ftdm_channel_call_hangup_nl(const char *file, const char * { ftdm_status_t status = FTDM_SUCCESS; - ftdm_set_echocancel_call_end(chan); - if (chan->state != FTDM_CHANNEL_STATE_DOWN) { if (chan->state == FTDM_CHANNEL_STATE_HANGUP) { /* make user's life easier, and just ignore double hangup requests */ @@ -4866,7 +4864,7 @@ FT_DECLARE(int) ftdm_load_module(const char *name) { ftdm_dso_lib_t lib; int count = 0, x = 0; - char path[128] = ""; + char path[512] = ""; char *err; ftdm_module_t *mod; diff --git a/libs/freetdm/src/ftdm_state.c b/libs/freetdm/src/ftdm_state.c index de62c0f0e7..9fe2b911dc 100644 --- a/libs/freetdm/src/ftdm_state.c +++ b/libs/freetdm/src/ftdm_state.c @@ -83,6 +83,8 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const c msg.channel = fchan; msg.event_id = FTDM_SIGEVENT_DIALING; ftdm_span_send_signal(fchan->span, &msg); + } else if (state == FTDM_CHANNEL_STATE_HANGUP) { + ftdm_set_echocancel_call_end(fchan); } /* MAINTENANCE WARNING diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 4265c9b8fa..540d7cb6e9 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -714,6 +714,7 @@ static void dump_mf(openr2_chan_t *r2chan) { char dfile[512]; FILE *f = NULL; + int rc = 0; ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; if (r2data->mf_dump_size) { @@ -727,7 +728,10 @@ static void dump_mf(openr2_chan_t *r2chan) if (f) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO input in file %s\n", dfile); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_INPUT, f); - fclose(f); + rc = fclose(f); + if (rc) { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failure closing IO input file %s: %s\n", dfile, strerror(errno)); + } } else { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Could not dump IO input in file %s, error: %s", dfile, strerror(errno)); } @@ -738,7 +742,10 @@ static void dump_mf(openr2_chan_t *r2chan) if (f) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO output in file %s\n", dfile); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_OUTPUT, f); - fclose(f); + rc = fclose(f); + if (rc) { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failure closing IO output file %s: %s\n", dfile, strerror(errno)); + } } else { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Could not dump IO output in file %s, error: %s", dfile, strerror(errno)); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/BOOST.limitations b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/BOOST.limitations deleted file mode 100644 index 663b7d376a..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/BOOST.limitations +++ /dev/null @@ -1,20 +0,0 @@ -== Boost sigmod current limitations == -- we don't support having openzap spans with physical channels - belonging to other physical spans. this is due to netborder sangoma abstraction, therefore - any openzap span using sigboost must have only channels belonging to the corresponding - physical span. - - This is the reason we added group functionality in openzap core, furthermore, previous groups in openzap - were only possible through adding of b-channels to a single span, but this forces the user to create groups - of channels only whithin the same type of trunk among other things. - -- all spans must be configured and then started, cannot configure, start, configure start etc - this is due to netborder telesoft abstraction. that requires configuring everything and - then starting everything at once. - -- sangoma_prid and sangoma_brid on Windows had to be compiled hacking make/Makefile.platform to comment all VC runtime checks, - otherwise when running in debug mode exceptions are thrown due to loss of data ie short to char conversions. - -== TODO == -- proper upper layer management of HW alarms (this must be done in mod_openzap.c) - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/boost-tasks.txt b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/boost-tasks.txt deleted file mode 100644 index f0eab3a277..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/boost-tasks.txt +++ /dev/null @@ -1,146 +0,0 @@ -== General Design == - -NBE will do its current loading of spans and configuration process through Sangoma Board Manager (SBM). -After doing SangomaBoardManager::getInstance().configure -> start. It will proceed to initalize -the openzap stack (just as the TelesoftStack is loaded after starting SMB. The procedure will be: - -- create a static or malloced zap_io_interface_t -- call zap_global_set_logger with the logging hooks. -- call zap_global_set_memhandler() with the memory hooks. -- call zap_global_init() to initialize the stack -- call zap_add_io_iface() to add the I/O iface. -- iterate over all SBM spans configured for BRI or any boost-managed signaling and: - * call zap_span_create(NBE I/O mod, in_ptrSpan, SMB span name) - * Fill in some members like: - span->trunk_type = E1/T1/J1/FXO/FXS etc ... - * iterate over all channels in SMB span and: - * zap_span_add_channel(zap_span, sock, type:CAS|BCHAN|DCHAN|ETC) - * call zap_configure_span("sangoma_boost", span, sigmsg_callback, "param1", value1, "param2", value1 ...) - * zap_span_start(span); - - -At this point, NBE would receive signaling msgs via sigmsg_callback registered when configuring -and NBE would request hangup or making calls throug openzap API, like zap_set_state_* and zap_channel_outgoing_call() to place calls. - -When NBE wants to check for link status. - - zap_get_siglink_state() which would return - ZAP_SIG_STATE_UP (D-chan UP, R2 bits in IDLE, ss7?) - ZAP_SIG_STATE_SUSPENDED (D-chan in power saving mode?) - ZAP_SIG_STATE_DOWN (D-chan down, R2 bits in blocked, ss7?) - - Whenever a state in sig link changes, the sigmsg_callback will be used to notify NBE or any other user. - -NOTE: right now hardware alarms notification in openzap is seriously broken, -see ozmod_libpri.c process_event ... reads an event from hardware (zap_event_t *), -then checks the event type, if its ZAP_OOB_ALARM_TRAP prepares a zap_sigmsg_t -(signaling event) setting its event_id to ZAP_OOB_ALARM_TRAP, which is *WRONG* -because event_id is of type zap_signal_event_t and not zap_oob_event_t! -this means on alarm the user will get ZAP_SIGEVENT_PROGRESS_MEDIA!! which is -value 7 that is in conflict with ZAP_OOB_ALARM_TRAP, I think a separate -callback should be used if the outside user wants to be notified about -hardware events like HW DTMF or so. Currently there is alreadya generic DTMF -listener. - -== Tasks Stage 1 / OpenZAP and Boost changes (To be tested with FreeSWITCH) == - -- Change malloc and other mem functions in openzap - to use internal hooks provided via zap_global_set_memhandler() - which would be called before zap_global_init(), this is - already done for the logger via zap_global_set_logger() - - question: should the mem routines allow for memory pool ptr? - this could be useful to provide a memory pool to - the whole module. - - question: should we allow hooks for threads and locking? - I think we can skip this one unless needed. They already - use their own threading abstraction which is working for - Linux and Windows. If we ever need to profile threading - we can add profiling hooks. - - question: I had to add openzap calls to the hash table and libteletone implementations, is that acceptable? - -- Modify zap_global_init() API - - This API must just initialize vars, mutexes etc. - and NOT DO ANY CONFIGURATION LOADING, PARSING, SPAN CREATION and I/O - configuration, which is what is currently doing. - We don't want zap_global_init() to create the spans based on that configuration - since NBE will have its own configuration and will take care of creating - the needed data structures on its own. - -- Add new zap_std_io_config() API - - This API will parse the standard openzap.conf module and create the spans. - This will be used by FS but not by NBE, which will create the openzap spans by itself. - The NBE flow to initialize openzap will be: - -- Add new API zap_global_add_io_iface(), - - This API will add a new I/O interface structure to the internal openzap hash of I/O structs. - This is needed because NBE I/O structure will NOT be loaded from an openzap module (.so/.dll) - but rather just registered on runtime (probably from a static structure in NBE code). - This openzap hash is used by zap_api_execute() for example, to find the module that can - handle a given API, ie (oz libpri status). This is an example of how an openzap I/O interface - can decide to implement just the ->api() member to handle commands and NOTHING else, - so I/O interfaces not necessary are hardware-related. - -- Add new zap_channel_get_siglink_state(zap_channel, zap_siglink_status_t &status) - -- Modify mod_openzap.c to read proto= setting in boost spans, this will determine wich boost sig - module will handle the configuration and those channels. - - - - Then as first config arg to zap_config_span() the boost proto module name would be included as "sigmod" which will be used - by ozmod_sangoma_boost to decide which sig module must handle that span configuration - -- Create minimal boost mod interface. - - ozmod_boost_ss7 should load sig boost mods and get interface via dlsym(boost_get_interface) boost_get_interface(boost_iface); - The boost interface will have - * const char *name // boost sigmod name (brid,ss7d) - * set_write_boost_msg_cb(callback) // tell the stack how to send us boost messages - * set_sig_status_cb(callback); // tell the stack how to notify us about link status changes - * write_boost_msg(struct boost_msg) // send a boost msg to the stack - * configure_span(zap_span_t span, "configuration", value, "configuration", value) // configure a given span - * get_sig_status(openzap_sigstatus_t status) - * start(span) // to start a given openzap span - * stop(span) // to stop the stack on a given openzap span - -- Migrate current sangoma_brid sig module to openzap - * Make sangoma_brid a library - * Move from using malloc, threading, locking, logging and I/O to openzap functions. Export the boost sigmod interface and its supporting code. - -== State 2 Tasks == - -- Create the I/O NBE interface and supporting functions. It must be possible to poll over the span - given that ozmod_sangoma_boost BRI module and others may need to *wait* for data. The poll() - function in I/O NBE interface would wait on a pthread condition or Windows event, which would - be triggered by some external NBE component registered with Sangoma Board Manager (SMB) for d-chan - data, whenever d-chan data arrives, saves the data in a buffer and triggers the condition to wakeup - any waiter, then the waiter (sangoma_brid or any other boost client) calls zap_channel_read which calls - our own I/O NBE interface read method and retrieves the data from the buffer. - - Dropped alternative design: - Another option is to add a new API zap_span_push_incoming_data(span/chan, data); However this changes - the model openzap has followed and I don't think fits that well, since now we have 2 different models - to support in openzap. - -== TODO == - -- how about logging specific modules, like, just ozmod_boost, or just the BRI stack? - more work to be done so the BRI module uses zap_log instead of current syslog - then work to be done to be able to filter logs from specific openzap code? is it worth it? - -- remove FORCE_SEGFAULT from sprid - - -=== Shortcomings == - -- we had to drop smg support in the branch where we work on sangoma prid. - After all, most people using sangoma_prid is using freeswitch/openzap and not Sangoma Media Gateway - The problem is in freeswitch/openzap mode, sangoma_boost ozmod takes care of span events (POLLPRI) - where in SMG and Netborder POLLPRI is done typically by sangoma board manager. - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h deleted file mode 100644 index 6fbf272d07..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2007, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FTDM_SANGOMA_BOOST_H -#define FTDM_SANGOMA_BOOST_H -#include "sangoma_boost_client.h" -#include "freetdm.h" - -#define MAX_CHANS_PER_TRUNKGROUP 1024 - -typedef enum { - FTDM_SANGOMA_BOOST_RUNNING = (1 << 0), - FTDM_SANGOMA_BOOST_RESTARTING = (1 << 1), - FTDM_SANGOMA_BOOST_EVENTS_RUNNING = (1 << 2), -} ftdm_sangoma_boost_flag_t; - -typedef struct ftdm_sangoma_boost_data { - sangomabc_connection_t mcon; - sangomabc_connection_t pcon; - int iteration; - uint32_t flags; - boost_sigmod_interface_t *sigmod; - ftdm_queue_t *boost_queue; -} ftdm_sangoma_boost_data_t; - -typedef struct ftdm_sangoma_boost_trunkgroup { - ftdm_mutex_t *mutex; - ftdm_size_t size; /* Number of b-channels in group */ - unsigned int last_used_index; /* index of last b-channel used */ - ftdm_channel_t* ftdmchans[MAX_CHANS_PER_TRUNKGROUP]; - //TODO need to merge congestion timeouts to this struct -} ftdm_sangoma_boost_trunkgroup_t; -#endif - -/* 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/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2008.vcproj deleted file mode 100644 index 73e421818f..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2008.vcproj +++ /dev/null @@ -1,373 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj deleted file mode 100644 index 684e4326cb..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj +++ /dev/null @@ -1,206 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - ftmod_sangoma_boost - {D021EF2A-460D-4827-A0F7-41FDECF46F1B} - ftmod_sangoma_boost - Win32Proj - - - - DynamicLibrary - Unicode - true - - - DynamicLibrary - Unicode - - - DynamicLibrary - Unicode - true - - - DynamicLibrary - Unicode - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(SolutionDir)$(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(SolutionDir)$(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(SolutionDir)$(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - Disabled - ..\..\include;..\..\isdn\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level4 - true - EditAndContinue - 4100;%(DisableSpecificWarnings) - - - %(AdditionalDependencies) - $(OutDir);%(AdditionalLibraryDirectories) - true - Windows - MachineX86 - - - - - MaxSpeed - true - ..\..\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level4 - true - ProgramDatabase - 4100;%(DisableSpecificWarnings) - - - true - Windows - true - true - MachineX86 - - - - - X64 - - - Disabled - ..\..\include;..\..\isdn\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level4 - true - ProgramDatabase - 4100;%(DisableSpecificWarnings) - - - %(AdditionalDependencies) - $(OutDir);%(AdditionalLibraryDirectories) - true - Windows - MachineX64 - - - - - X64 - - - MaxSpeed - true - ..\..\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level4 - false - ProgramDatabase - 4100;%(DisableSpecificWarnings) - - - true - Windows - true - true - MachineX64 - - - - - - - - - - - - - - - {93b8812c-3ec4-4f78-8970-ffbfc99e167d} - false - - - - - - \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj.filters deleted file mode 100644 index 2aeed155cd..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj.filters +++ /dev/null @@ -1,35 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c deleted file mode 100644 index d0bc14c8d8..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ /dev/null @@ -1,2730 +0,0 @@ -/* - * Copyright (c) 2007, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Moises Silva - * David Yat Sin - * Nenad Corbic - * - */ - -/* NOTE: -On __WINDOWS__ platform this code works with sigmod ONLY, don't try to make sense of any socket code for win -I basically ifdef out everything that the compiler complained about -*/ - -#include "private/ftdm_core.h" -#include "sangoma_boost_client.h" -#include "ftdm_sangoma_boost.h" -#ifdef HAVE_SYS_SELECT_H -#include -#endif - -/* Boost signaling modules global hash and its mutex */ -ftdm_mutex_t *g_boost_modules_mutex = NULL; -ftdm_hash_t *g_boost_modules_hash = NULL; - -#define MAX_TRUNK_GROUPS 64 -//TODO need to merge congestion_timeouts with ftdm_sangoma_boost_trunkgroups -static time_t congestion_timeouts[MAX_TRUNK_GROUPS]; - -static ftdm_sangoma_boost_trunkgroup_t *g_trunkgroups[MAX_TRUNK_GROUPS]; - -static ftdm_io_interface_t ftdm_sangoma_boost_interface; -static ftdm_status_t ftdm_sangoma_boost_list_sigmods(ftdm_stream_handle_t *stream); - -#define BOOST_QUEUE_SIZE 500 - -/* get freetdm span and chan depending on the span mode */ -#define BOOST_SPAN(ftdmchan) ((ftdm_sangoma_boost_data_t*)(ftdmchan)->span->signal_data)->sigmod ? ftdmchan->physical_span_id : ftdmchan->physical_span_id-1 -#define BOOST_CHAN(ftdmchan) ((ftdm_sangoma_boost_data_t*)(ftdmchan)->span->signal_data)->sigmod ? ftdmchan->physical_chan_id : ftdmchan->physical_chan_id-1 - -/** - * \brief SANGOMA boost notification flag - */ -typedef enum { - SFLAG_SENT_FINAL_MSG = (1 << 0), - SFLAG_SENT_ACK = (1 << 1), - SFLAG_RECVD_ACK = (1 << 2), - SFLAG_HANGUP = (1 << 3), - SFLAG_TERMINATING = (1 << 4) -} sflag_t; - -typedef uint16_t sangoma_boost_request_id_t; - -/** - * \brief SANGOMA boost request status - */ -typedef enum { - BST_FREE, - BST_WAITING, - BST_READY, - BST_FAIL -} sangoma_boost_request_status_t; - -/** - * \brief SANGOMA boost request structure - */ -typedef struct { - sangoma_boost_request_status_t status; - sangomabc_short_event_t event; - ftdm_span_t *span; - ftdm_channel_t *ftdmchan; - int hangup_cause; - int flags; -} sangoma_boost_request_t; - -typedef struct { - int call_setup_id; - int last_event_id; -} sangoma_boost_call_t; - -#define CALL_DATA(ftdmchan) ((sangoma_boost_call_t*)((ftdmchan)->call_data)) - -//#define MAX_REQ_ID FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN * FTDM_MAX_CHANNELS_PHYSICAL_SPAN -#define MAX_REQ_ID 6000 - -static uint16_t SETUP_GRID[FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN+1][FTDM_MAX_CHANNELS_PHYSICAL_SPAN+1] = {{ 0 }}; - -static sangoma_boost_request_t OUTBOUND_REQUESTS[MAX_REQ_ID+1] = {{ 0 }}; - -static ftdm_mutex_t *request_mutex = NULL; - -static uint8_t req_map[MAX_REQ_ID+1] = { 0 }; -static uint8_t nack_map[MAX_REQ_ID+1] = { 0 }; - -/** - * \brief Releases span and channel from setup grid - * - * \note This is ALWAYS based on freetdm span/chan numbers! not boost event numbers - * is totally brain damaged to use event->span or event->chan to release the request - * use BOOST_SPAN_EVENT and BOOST_SPAN_CHAN to get the right index!! - * - * \param span Span number - * \param chan Channel number - * \param func Calling function - * \param line Line number on request - * \return NULL if not found, channel otherwise - */ -static void __release_request_id_span_chan(int span, int chan, const char *func, int line) -{ - int id; - - ftdm_mutex_lock(request_mutex); - if ((id = SETUP_GRID[span][chan])) { - ftdm_assert(id <= MAX_REQ_ID, "Invalid request id\n"); - req_map[id] = 0; - SETUP_GRID[span][chan] = 0; - } - ftdm_mutex_unlock(request_mutex); -} -#define release_request_id_span_chan(s, c) __release_request_id_span_chan(s, c, __FUNCTION__, __LINE__) - -/** - * \brief Releases request ID - * \param func Calling function - * \param line Line number on request - * \return NULL if not found, channel otherwise - */ -static void __release_request_id(sangoma_boost_request_id_t r, const char *func, int line) -{ - ftdm_assert(r <= MAX_REQ_ID, "Invalid request id\n"); - ftdm_mutex_lock(request_mutex); - req_map[r] = 0; - ftdm_mutex_unlock(request_mutex); -} -#define release_request_id(r) __release_request_id(r, __FUNCTION__, __LINE__) - -static sangoma_boost_request_id_t last_req = 0; - -/** - * \brief Gets the first available tank request ID - * \param func Calling function - * \param line Line number on request - * \return 0 on failure, request ID on success - */ -static sangoma_boost_request_id_t __next_request_id(const char *func, int line) -{ - sangoma_boost_request_id_t r = 0, i = 0; - int found=0; - - ftdm_mutex_lock(request_mutex); - //r = ++last_req; - //while(!r || req_map[r]) { - - for (i=1; i<= MAX_REQ_ID; i++){ - r = ++last_req; - - if (r >= MAX_REQ_ID) { - r = last_req = 1; - } - - if (req_map[r]) { - /* Busy find another */ - continue; - - } - - req_map[r] = 1; - found=1; - break; - - } - - ftdm_mutex_unlock(request_mutex); - - if (!found) { - return 0; - } - - return r; -} -#define next_request_id() __next_request_id(__FUNCTION__, __LINE__) - - -static void print_request_ids(void) -{ - sangoma_boost_request_id_t i = 0; - int cnt=0; - - ftdm_mutex_lock(request_mutex); - - for (i=1; i<= MAX_REQ_ID; i++){ - if (req_map[i]) { - ftdm_log(FTDM_LOG_CRIT, "Used Request ID=%i\n",i); - cnt++; - } - } - - ftdm_mutex_unlock(request_mutex); - ftdm_log(FTDM_LOG_CRIT, "Total Request IDs=%i\n",cnt); - - return; -} - - -/** - * \brief Finds the channel that triggered an event - * \param span Span where to search the channel - * \param event SANGOMA event - * \param force Do not wait for the channel to be available if in use - * \return NULL if not found, channel otherwise - */ -static ftdm_channel_t *find_ftdmchan(ftdm_span_t *span, sangomabc_short_event_t *event, int force) -{ - uint32_t i; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - uint32_t targetspan = BOOST_EVENT_SPAN(sangoma_boost_data->sigmod, event); - uint32_t targetchan = BOOST_EVENT_CHAN(sangoma_boost_data->sigmod, event); - - /* NC: Sanity check in case the call setup id does not relate - to span. This can happen if RESTART is received on a - full load. Where stray ACK messages can arrive after - a RESTART has taken place. - */ - if (!span) { - ftdm_log(FTDM_LOG_CRIT, "No Span for Event=%s s%dc%d cid=%d\n", - BOOST_DECODE_EVENT_ID(event->event_id), - targetspan, - targetchan, - event->call_setup_id); - return NULL; - } - - - for(i = 1; i <= span->chan_count; i++) { - if (span->channels[i]->physical_span_id == targetspan && span->channels[i]->physical_chan_id == targetchan) { - ftdmchan = span->channels[i]; - if (force || (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE))) { - break; - } else { - ftdmchan = NULL; - ftdm_log(FTDM_LOG_DEBUG, "Channel %d:%d ~ %d:%d is already in use in state %s\n", - span->channels[i]->span_id, - span->channels[i]->chan_id, - span->channels[i]->physical_span_id, - span->channels[i]->physical_chan_id, - ftdm_channel_state2str(span->channels[i]->state)); - break; - } - } - } - - return ftdmchan; -} - -static int check_congestion(int trunk_group) -{ - if (congestion_timeouts[trunk_group]) { - time_t now = time(NULL); - - if (now >= congestion_timeouts[trunk_group]) { - congestion_timeouts[trunk_group] = 0; - } else { - return 1; - } - } - - return 0; -} - - -/** - * \brief Requests an sangoma boost channel on a span (outgoing call) - * \param span Span where to get a channel - * \param chan_id Specific channel to get (0 for any) - * \param direction Call direction - * \param caller_data Caller information - * \param ftdmchan Channel to initialise - * \return Success or failure - */ -static FIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - ftdm_status_t status = FTDM_FAIL; - sangoma_boost_request_id_t r; - sangomabc_event_t event = {0}; - /* sanity has to be more than 8 seconds. - * In PRI specs, timeout is 4 seconds for remote switch to respond to a SETUP, - * and PRI stack will retransmit a second SETUP after the first timeout, so - * we should allow for at least 8 seconds. - */ - - int boost_request_timeout = 10000; - sangoma_boost_request_status_t st; - char dnis[128] = ""; - char *gr = NULL; - uint32_t count = 0; - int tg=0; - - /* NC: On large number of calls 10 seconds is not enough. - Resetting to 30 seconds. Especially on ss7 when - links are reset during large call volume */ - if (!sangoma_boost_data->sigmod) { - boost_request_timeout = 30000; - } - - if (sangoma_boost_data->sigmod) { - ftdm_log(FTDM_LOG_CRIT, "This function should not be called when sigmod was configured in boost\n"); - *ftdmchan = NULL; - return FTDM_FAIL; - } - - if (ftdm_test_flag(span, FTDM_SPAN_SUSPENDED)) { - ftdm_log(FTDM_LOG_CRIT, "SPAN is Suspended.\n"); - *ftdmchan = NULL; - return FTDM_FAIL; - } - - if (check_congestion(tg)) { - ftdm_log(FTDM_LOG_CRIT, "All circuits are busy. Trunk Group=%i (CONGESTION)\n",tg+1); - *ftdmchan = NULL; - return FTDM_FAIL; - } - - if (count >= span->chan_count) { - ftdm_log(FTDM_LOG_CRIT, "All circuits are busy.\n"); - *ftdmchan = NULL; - return FTDM_FAIL; - } - - r = next_request_id(); - if (r == 0) { - ftdm_log(FTDM_LOG_CRIT, "All tanks ids are busy.\n"); - *ftdmchan = NULL; - return FTDM_FAIL; - } - - /* After this point we must release request id before we leave the function - in case of an error. */ - - ftdm_set_string(dnis, caller_data->dnis.digits); - - if ((gr = strchr(dnis, '@'))) { - *gr++ = '\0'; - } - - if (gr && *(gr+1)) { - tg = atoi(gr+1); - if (tg > 0) { - tg--; - } - } - - sangomabc_call_init(&event, caller_data->cid_num.digits, dnis, r); - - event.trunk_group = tg; - - - ftdm_span_channel_use_count(span, &count); - - if (gr && *(gr+1)) { - switch(*gr) { - case 'g': - event.hunt_group = SIGBOOST_HUNTGRP_SEQ_ASC; - break; - case 'G': - event.hunt_group = SIGBOOST_HUNTGRP_SEQ_DESC; - break; - case 'r': - event.hunt_group = SIGBOOST_HUNTGRP_RR_ASC; - break; - case 'R': - event.hunt_group = SIGBOOST_HUNTGRP_RR_DESC; - break; - default: - ftdm_log(FTDM_LOG_WARNING, "Failed to determine huntgroup (%s)\n", gr); - event.hunt_group = SIGBOOST_HUNTGRP_SEQ_ASC; - } - } - - ftdm_set_string(event.calling_name, caller_data->cid_name); - ftdm_set_string(event.rdnis.digits, caller_data->rdnis.digits); - if (strlen(caller_data->rdnis.digits)) { - event.rdnis.digits_count = (uint8_t)strlen(caller_data->rdnis.digits)+1; - event.rdnis.ton = caller_data->rdnis.type; - event.rdnis.npi = caller_data->rdnis.plan; - } - - event.calling.screening_ind = caller_data->screen; - event.calling.presentation_ind = caller_data->pres; - - event.calling.ton = caller_data->cid_num.type; - event.calling.npi = caller_data->cid_num.plan; - - event.called.ton = caller_data->dnis.type; - event.called.npi = caller_data->dnis.plan; - - /* we're making a contract now that FreeTDM values for capability, layer 1 and such will be the same as for boost */ - event.bearer.capability = caller_data->bearer_capability; - event.bearer.uil1p = caller_data->bearer_layer1; - - if (caller_data->raw_data_len) { - ftdm_set_string(event.custom_data, caller_data->raw_data); - event.custom_data_size = (uint16_t)caller_data->raw_data_len; - } - - OUTBOUND_REQUESTS[r].status = BST_WAITING; - OUTBOUND_REQUESTS[r].span = span; - - if (sangomabc_connection_write(&sangoma_boost_data->mcon, &event) <= 0) { - ftdm_log(FTDM_LOG_CRIT, "Failed to tx boost event [%s]\n", strerror(errno)); - status = OUTBOUND_REQUESTS[r].status = FTDM_FAIL; - if (!sangoma_boost_data->sigmod) { - *ftdmchan = NULL; - } - goto done; - } - - while(ftdm_running() && OUTBOUND_REQUESTS[r].status == BST_WAITING) { - ftdm_sleep(1); - if (--boost_request_timeout <= 0) { - status = FTDM_FAIL; - if (!sangoma_boost_data->sigmod) { - *ftdmchan = NULL; - } - ftdm_log(FTDM_LOG_CRIT, "Csid:%d Timed out waiting for boost channel request response, current status: BST_WAITING\n", r); - goto done; - } - } - - if (OUTBOUND_REQUESTS[r].status == BST_READY && OUTBOUND_REQUESTS[r].ftdmchan) { - *ftdmchan = OUTBOUND_REQUESTS[r].ftdmchan; - status = FTDM_SUCCESS; - } else { - status = FTDM_FAIL; - if (!sangoma_boost_data->sigmod) { - *ftdmchan = NULL; - } - } - - done: - - st = OUTBOUND_REQUESTS[r].status; - OUTBOUND_REQUESTS[r].status = BST_FREE; - - if (status == FTDM_FAIL) { - if (st == BST_FAIL) { - caller_data->hangup_cause = OUTBOUND_REQUESTS[r].hangup_cause; - } else { - caller_data->hangup_cause = FTDM_CAUSE_RECOVERY_ON_TIMER_EXPIRE; - } - } - - if (st == BST_FAIL) { - release_request_id(r); - } else if (st != BST_READY) { - ftdm_assert_return(r <= MAX_REQ_ID, FTDM_FAIL, "Invalid index\n"); - nack_map[r] = 1; - if (sangoma_boost_data->sigmod) { - sangomabc_exec_command(&sangoma_boost_data->mcon, - BOOST_SPAN((*ftdmchan)), - BOOST_CHAN((*ftdmchan)), - r, - SIGBOOST_EVENT_CALL_START_NACK, - 0, 0); - } else { - sangomabc_exec_command(&sangoma_boost_data->mcon, - 0, - 0, - r, - SIGBOOST_EVENT_CALL_START_NACK, - 0, 0); - } - } - - return status; -} - -/** - * \brief Starts an sangoma boost channel (outgoing call) - * \param ftdmchan Channel to initiate call on - * \return Success - */ -static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(sangoma_boost_outgoing_call) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - - if (!sangoma_boost_data->sigmod) { - return FTDM_SUCCESS; - } - - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND); - - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DIALING); - - return FTDM_SUCCESS; -} - -/** - * \brief Handler for call start ack no media event - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_call_progress(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan; - - - if ((ftdmchan = find_ftdmchan(span, event, 1))) { - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - ftdm_mutex_lock(ftdmchan->mutex); - if (!sangoma_boost_data->sigmod && ftdmchan->state == FTDM_CHANNEL_STATE_HOLD) { - if ((event->flags & SIGBOOST_PROGRESS_MEDIA)) { - ftdmchan->init_state = FTDM_CHANNEL_STATE_PROGRESS_MEDIA; - ftdm_log(FTDM_LOG_DEBUG, "Channel init state updated to PROGRESS_MEDIA [Csid:%d]\n", event->call_setup_id); - } else if ((event->flags & SIGBOOST_PROGRESS_RING)) { - ftdmchan->init_state = FTDM_CHANNEL_STATE_PROGRESS; - ftdm_log(FTDM_LOG_DEBUG, "Channel init state updated to PROGRESS [Csid:%d]\n", event->call_setup_id); - } else { - ftdmchan->init_state = FTDM_CHANNEL_STATE_IDLE; - ftdm_log(FTDM_LOG_DEBUG, "Channel init state updated to IDLE [Csid:%d]\n", event->call_setup_id); - } - } else { - if ((event->flags & SIGBOOST_PROGRESS_MEDIA)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } else if ((event->flags & SIGBOOST_PROGRESS_RING)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); - } else { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); - } - } - ftdm_mutex_unlock(ftdmchan->mutex); - } -} - -/** - * \brief Handler for call start ack event - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_call_start_ack(sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - - ftdm_channel_t *ftdmchan = NULL; - uint32_t event_span = BOOST_EVENT_SPAN(mcon->sigmod, event); - uint32_t event_chan = BOOST_EVENT_CHAN(mcon->sigmod, event); - - - if (nack_map[event->call_setup_id]) { - /* In this scenario outgoing call was alrady stopped - via NACK and now we are expecting an NACK_ACK. - If we receive an ACK its a race condition thus - ignor it */ - return; - } - - if (mcon->sigmod) { - ftdmchan = OUTBOUND_REQUESTS[event->call_setup_id].ftdmchan; - } else { - ftdmchan = find_ftdmchan(OUTBOUND_REQUESTS[event->call_setup_id].span, event, 0); - } - - - if (ftdmchan) { - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - if (!mcon->sigmod && ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to open FTDM channel [%s]\n", ftdmchan->last_error); - } else { - - /* Only bind the setup id to GRID when we are sure that channel is ready - otherwise we could overwite the original call */ - OUTBOUND_REQUESTS[event->call_setup_id].event = *event; - SETUP_GRID[event_span][event_chan] = event->call_setup_id; - - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND); - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_INUSE); - ftdmchan->sflags = SFLAG_RECVD_ACK; - - if ((event->flags & SIGBOOST_PROGRESS_MEDIA)) { - if (sangoma_boost_data->sigmod) { - ftdm_log(FTDM_LOG_DEBUG, "Channel state changing to PROGRESS_MEDIA [Csid:%d]\n", event->call_setup_id); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } else { - ftdmchan->init_state = FTDM_CHANNEL_STATE_PROGRESS_MEDIA; - ftdm_log(FTDM_LOG_DEBUG, "Channel init state changed to PROGRESS_MEDIA [Csid:%d]\n", event->call_setup_id); - } - } else if ((event->flags & SIGBOOST_PROGRESS_RING)) { - if (sangoma_boost_data->sigmod) { - ftdm_log(FTDM_LOG_DEBUG, "Channel state changing to PROGRESS [Csid:%d]\n", event->call_setup_id); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); - } else { - ftdmchan->init_state = FTDM_CHANNEL_STATE_PROGRESS; - ftdm_log(FTDM_LOG_DEBUG, "Channel init state changed to PROGRESS [Csid:%d]\n", event->call_setup_id); - } - } else { - if (sangoma_boost_data->sigmod) { - /* should we set a state here? */ - } else { - ftdmchan->init_state = FTDM_CHANNEL_STATE_IDLE; - ftdm_log(FTDM_LOG_DEBUG, "Channel init state changed to IDLE [Csid:%d]\n", event->call_setup_id); - } - } - if (!sangoma_boost_data->sigmod) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HOLD); - ftdm_log(FTDM_LOG_DEBUG, "Assigned chan %d:%d (%d:%d) to CSid=%d\n", - ftdmchan->span_id, ftdmchan->chan_id, event_span, event_chan, event->call_setup_id); - OUTBOUND_REQUESTS[event->call_setup_id].ftdmchan = ftdmchan; - } - OUTBOUND_REQUESTS[event->call_setup_id].flags = event->flags; - OUTBOUND_REQUESTS[event->call_setup_id].status = BST_READY; - return; - } - - } else { - - ftdm_assert(!mcon->sigmod, "CALL STOP ACK: Invalid Sigmod Path"); - - if ((ftdmchan = find_ftdmchan(OUTBOUND_REQUESTS[event->call_setup_id].span, (sangomabc_short_event_t*)event, 1))) { - int r; - /* NC: If we get CALL START ACK and channel is in active state - then we are completely out of sync with the other end. - Treat CALL START ACK as CALL STOP and hangup the current call. - */ - - if (ftdmchan->state == FTDM_CHANNEL_STATE_UP || - ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA || - ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS) { - ftdm_log(FTDM_LOG_CRIT, "FTDMCHAN CALL ACK STATE UP -> Changed to TERMINATING %d:%d\n", event_span, event_chan); - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r); - } else if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP || ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) { - ftdm_log(FTDM_LOG_CRIT, "FTDMCHAN CALL ACK STATE HANGUP -> Changed to HANGUP COMPLETE %d:%d\n", event_span, event_chan); - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, r); - } else { - ftdm_log(FTDM_LOG_CRIT, "FTDMCHAN STATE INVALID State %s on IN CALL ACK %d:%d\n", - ftdm_channel_state2str(ftdmchan->state), event_span, event_chan); - } - ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG); - ftdmchan=NULL; - } - } - - - if (!ftdmchan) { - ftdm_log(FTDM_LOG_CRIT, "START ACK CANT FIND A CHAN %d:%d\n", event_span, event_chan); - } else { - /* only reason to be here is failed to open channel when we we're in sigmod */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG); - } - - sangomabc_exec_command(mcon, - event->span, - event->chan, - event->call_setup_id, - SIGBOOST_EVENT_CALL_STOPPED, - FTDM_CAUSE_DESTINATION_OUT_OF_ORDER, 0); - OUTBOUND_REQUESTS[event->call_setup_id].status = BST_FAIL; - OUTBOUND_REQUESTS[event->call_setup_id].hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER; -} - -/** - * \brief Handler for call done event - * \param span Span where event was fired - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_call_done(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan; - int r = 0; - - if ((ftdmchan = find_ftdmchan(span, event, 1))) { - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - ftdm_mutex_lock(ftdmchan->mutex); - - if (sangoma_boost_data->sigmod) { - /* not really completely done, but if we ever get an incoming call before moving to HANGUP_COMPLETE - * handle_incoming_call() will take care of moving the state machine to release the channel */ - sangomabc_exec_command(&sangoma_boost_data->mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_RELEASED, - 0, 0); - } - - if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN || ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP_COMPLETE || ftdm_test_sflag(ftdmchan, SFLAG_TERMINATING)) { - goto done; - } - - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, r); - if (r) { - ftdm_mutex_unlock(ftdmchan->mutex); - return; - } - } - - done: - - if (ftdmchan) { - ftdm_mutex_unlock(ftdmchan->mutex); - } - - if (event->call_setup_id) { - release_request_id(event->call_setup_id); - } else { - release_request_id_span_chan(BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - } -} - - -/** - * \brief Handler for call start nack event - * \param span Span where event was fired - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_call_start_nack(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { - uint32_t count = 0; - int delay = 0; - int tg=event->trunk_group; - - ftdm_span_channel_use_count(span, &count); - - delay = (int) (count / 100) * 2; - - if (delay > 10) { - delay = 10; - } else if (delay < 1) { - delay = 1; - } - - if (tg < 0 || tg >= MAX_TRUNK_GROUPS) { - ftdm_log(FTDM_LOG_CRIT, "Invalid All Ckt Busy trunk group number %i\n", tg); - tg=0; - } - - congestion_timeouts[tg] = time(NULL) + delay; - event->release_cause = 17; - - } else if (event->release_cause == SIGBOOST_CALL_SETUP_CSUPID_DBL_USE) { - event->release_cause = 17; - } - - if (event->call_setup_id) { - if (sangoma_boost_data->sigmod) { - ftdmchan = OUTBOUND_REQUESTS[event->call_setup_id].ftdmchan; - CALL_DATA(ftdmchan)->last_event_id = event->event_id; - CALL_DATA(ftdmchan)->call_setup_id = event->call_setup_id; - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - ftdm_clear_sflag_locked(ftdmchan, SFLAG_SENT_FINAL_MSG); - } else { - sangomabc_exec_command(mcon, - 0, - 0, - event->call_setup_id, - SIGBOOST_EVENT_CALL_START_NACK_ACK, - 0, 0); - OUTBOUND_REQUESTS[event->call_setup_id].event = *event; - OUTBOUND_REQUESTS[event->call_setup_id].status = BST_FAIL; - OUTBOUND_REQUESTS[event->call_setup_id].hangup_cause = event->release_cause; - ftdm_log(FTDM_LOG_DEBUG, "setting outbound request status %d to BST_FAIL\n", event->call_setup_id); - } - return; - } else { - if ((ftdmchan = find_ftdmchan(span, event, 1))) { - int r = 0; - - /* if there is no call setup id this should not be an outbound channel for sure */ - ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND), "Yay, outbound flag should not be set here!\n"); - - CALL_DATA(ftdmchan)->last_event_id = event->event_id; - ftdm_mutex_lock(ftdmchan->mutex); - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r); - if (r == FTDM_SUCCESS) { - ftdmchan->caller_data.hangup_cause = event->release_cause; - } - ftdm_mutex_unlock(ftdmchan->mutex); - if (r) { - return; - } - } - } - - if (ftdmchan) { - ftdm_set_sflag_locked(ftdmchan, SFLAG_SENT_FINAL_MSG); - } - - /* nobody else will do it so we have to do it ourselves */ - sangomabc_exec_command(mcon, - event->span, - event->chan, - event->call_setup_id, - SIGBOOST_EVENT_CALL_START_NACK_ACK, - 0, 0); -} - -static void handle_call_released(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan; - - if ((ftdmchan = find_ftdmchan(span, event, 1))) { - ftdm_log(FTDM_LOG_DEBUG, "Releasing completely chan s%dc%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), - BOOST_EVENT_CHAN(mcon->sigmod, event)); - ftdm_channel_close(&ftdmchan); - } else { - ftdm_log(FTDM_LOG_CRIT, "Odd, We could not find chan: s%dc%d to release the call completely!!\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - } -} - -/** - * \brief Handler for call stop event - * \param span Span where event was fired - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_call_stop(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan; - - if ((ftdmchan = find_ftdmchan(span, event, 1))) { - int r = 0; - - ftdm_mutex_lock(ftdmchan->mutex); - - if (ftdm_test_sflag(ftdmchan, SFLAG_HANGUP) || - ftdmchan->state == FTDM_CHANNEL_STATE_DOWN || - ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - - /* NC: Checking for state DOWN because ss7box can - send CALL_STOP twice in a row. If we do not check for - STATE_DOWN we will set the state back to termnating - and block the channel forever - */ - - /* racing condition where both sides initiated a hangup - * Do not change current state as channel is already clearing - * itself through local initiated hangup */ - - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_STOPPED_ACK, - 0, 0); - ftdm_mutex_unlock(ftdmchan->mutex); - return; - } else if (ftdmchan->state == FTDM_CHANNEL_STATE_HOLD) { - ftdmchan->init_state = FTDM_CHANNEL_STATE_TERMINATING; - ftdm_log(FTDM_LOG_DEBUG, "Channel init state updated to TERMINATING [Csid:%d]\n", event->call_setup_id); - OUTBOUND_REQUESTS[event->call_setup_id].hangup_cause = event->release_cause; - ftdmchan->caller_data.hangup_cause = event->release_cause; - ftdm_mutex_unlock(ftdmchan->mutex); - return; - } else { - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r); - } - - if (r == FTDM_SUCCESS) { - ftdmchan->caller_data.hangup_cause = event->release_cause; - } - - ftdm_mutex_unlock(ftdmchan->mutex); - - if (r) { - return; - } - } else { /* we have to do it ourselves.... */ - ftdm_log(FTDM_LOG_CRIT, "Odd, We could not find chan: s%dc%d\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - release_request_id_span_chan(BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - } -} - -/** - * \brief Handler for call answer event - * \param span Span where event was fired - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_call_answer(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan; - - if ((ftdmchan = find_ftdmchan(span, event, 1))) { - ftdm_mutex_lock(ftdmchan->mutex); - - if (ftdm_test_sflag(ftdmchan, SFLAG_HANGUP) || - ftdmchan->state == FTDM_CHANNEL_STATE_DOWN || - ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - - /* NC: Do nothing here because we are in process - of stopping the call. So ignore the ANSWER. */ - ftdm_log(FTDM_LOG_DEBUG, "Got answer but call is already hangup %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), - BOOST_EVENT_CHAN(mcon->sigmod, event)); - - } else if (ftdmchan->state == FTDM_CHANNEL_STATE_HOLD) { - ftdmchan->init_state = FTDM_CHANNEL_STATE_UP; - - } else { - int r = 0; - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_UP, r); - } - ftdm_mutex_unlock(ftdmchan->mutex); - } else { - ftdm_log(FTDM_LOG_CRIT, "Could not find channel %d:%d on answer message!\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - sangomabc_exec_command(mcon, - event->span, - event->chan, - event->call_setup_id, - SIGBOOST_EVENT_CALL_STOPPED, - FTDM_CAUSE_DESTINATION_OUT_OF_ORDER, 0); - } -} - -static __inline__ void stop_loop(ftdm_channel_t *ftdmchan); - -/** - * \brief Handler for call start event - * \param span Span where event was fired - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_event_t *event) -{ - ftdm_channel_t *ftdmchan = NULL; - int hangup_cause = FTDM_CAUSE_CALL_REJECTED; - int retry = 1; - -tryagain: - - if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 0))) { - if ((ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 1))) { - int r; - - /* NC: If we get CALL START and channel is in active state - then we are completely out of sync with the other end. - Treat CALL START as CALL STOP and hangup the current call. - The incoming call will also be NACKed. - */ - - if (ftdmchan->state == FTDM_CHANNEL_STATE_UP || - ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA || - ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS) { - ftdm_log(FTDM_LOG_CRIT, "s%dc%d: FTDMCHAN STATE UP -> Changed to TERMINATING\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r); - } else if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP || ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) { - ftdm_log(FTDM_LOG_CRIT, "s%dc%d: FTDMCHAN STATE HANGUP -> Changed to HANGUP COMPLETE\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, r); - } else if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) { - ftdm_log(FTDM_LOG_WARNING, "s%dc%d: Collision, hanging up incoming call\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - /* dont hangup the outgoing call, the other side will send a call start nack too - * and there we will move to terminating. If we move to terminating here. We used to move - * to terminating here, but that introduces a problem in handle_call_start_nack where - * when receiving call start nack we move the channel from DOWN to TERMINATING ( cuz we already - * hangup here ) and the channel gets stuck in terminating forever. So at this point we're trusting - * the other side to send the call start nack ( or proceed with the call ) - * ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r); - */ - } else if (ftdmchan->state == FTDM_CHANNEL_STATE_IN_LOOP && retry) { - retry = 0; - stop_loop(ftdmchan); - ftdm_channel_advance_states(ftdmchan); - goto tryagain; - } else { - ftdm_log(FTDM_LOG_ERROR, "s%dc%d: rejecting incoming call in channel state %s\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event), - ftdm_channel_state2str(ftdmchan->state)); - } - ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG); - ftdmchan = NULL; - } else { - ftdm_log(FTDM_LOG_CRIT, "s%dc%d: incoming call in invalid channel (channel not found)!\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - } - goto error; - } - - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "s%dc%d: failed to open channel on incoming call, rejecting!\n", - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - goto error; - } - - ftdm_log(FTDM_LOG_DEBUG, "Got call start from s%dc%d mapped to freetdm logical s%dc%d, physical s%dc%d\n", - event->span, event->chan, - ftdmchan->span_id, ftdmchan->chan_id, - ftdmchan->physical_span_id, ftdmchan->physical_chan_id); - - ftdmchan->sflags = 0; - ftdm_set_string(ftdmchan->caller_data.cid_num.digits, (char *)event->calling.digits); - ftdm_set_string(ftdmchan->caller_data.cid_name, (char *)event->calling.digits); - ftdm_set_string(ftdmchan->caller_data.ani.digits, (char *)event->calling.digits); - ftdm_set_string(ftdmchan->caller_data.dnis.digits, (char *)event->called.digits); - ftdm_set_string(ftdmchan->caller_data.rdnis.digits, (char *)event->rdnis.digits); - if (event->custom_data_size) { - ftdm_set_string(ftdmchan->caller_data.raw_data, event->custom_data); - ftdmchan->caller_data.raw_data_len = event->custom_data_size; - } - - if (strlen(event->calling_name)) { - ftdm_set_string(ftdmchan->caller_data.cid_name, (char *)event->calling_name); - } - - ftdmchan->caller_data.cid_num.plan = event->calling.npi; - ftdmchan->caller_data.cid_num.type = event->calling.ton; - - ftdmchan->caller_data.ani.plan = event->calling.npi; - ftdmchan->caller_data.ani.type = event->calling.ton; - - ftdmchan->caller_data.dnis.plan = event->called.npi; - ftdmchan->caller_data.dnis.type = event->called.ton; - - ftdmchan->caller_data.rdnis.plan = event->rdnis.npi; - ftdmchan->caller_data.rdnis.type = event->rdnis.ton; - - ftdmchan->caller_data.screen = event->calling.screening_ind; - ftdmchan->caller_data.pres = event->calling.presentation_ind; - - ftdmchan->caller_data.bearer_capability = event->bearer.capability; - ftdmchan->caller_data.bearer_layer1 = event->bearer.uil1p; - - /* more info about custom data: http://www.ss7box.com/smg_manual.html#ISUP-IN-RDNIS-NEW */ - if (event->custom_data_size) { - char* p = NULL; - - p = strstr((char*)event->custom_data,"PRI001-ANI2-"); - if (p!=NULL) { - int ani2 = 0; - sscanf(p, "PRI001-ANI2-%d", &ani2); - snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", ani2); - } - } - - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING); - return; - - error: - hangup_cause = ftdmchan ? ftdmchan->caller_data.hangup_cause : FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL; - sangomabc_exec_command(mcon, - event->span, - event->chan, - event->call_setup_id, - SIGBOOST_EVENT_CALL_START_NACK, - hangup_cause, 0); - -} - -static void handle_call_loop_start(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_status_t res = FTDM_FAIL; - ftdm_channel_t *ftdmchan; - - if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 0))) { - ftdm_log(FTDM_LOG_CRIT, "CANNOT START LOOP, CHAN NOT AVAILABLE %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - return; - } - - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "CANNOT START LOOP, CANT OPEN CHAN %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - return; - } - - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP, res); - if (res != FTDM_SUCCESS) { - ftdm_channel_t *toclose = ftdmchan; - ftdm_log(FTDM_LOG_CRIT, "yay, could not set the state of the channel to IN_LOOP, loop will fail\n"); - ftdm_channel_close(&toclose); - return; - } - ftdm_log(FTDM_LOG_DEBUG, "%d:%d starting loop\n", ftdmchan->span_id, ftdmchan->chan_id); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_LOOP, NULL); -} - -static __inline__ void stop_loop(ftdm_channel_t *ftdmchan) -{ - ftdm_status_t res = FTDM_FAIL; - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); - /* even when we did not sent a msg we set this flag to avoid sending call stop in the DOWN state handler */ - ftdm_set_flag(ftdmchan, SFLAG_SENT_FINAL_MSG); - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_DOWN, res); - if (res != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "yay, could not set the state of the channel from IN_LOOP to DOWN\n"); - } -} - -static void handle_call_loop_stop(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan; - if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 1))) { - ftdm_log(FTDM_LOG_CRIT, "CANNOT STOP LOOP, INVALID CHAN REQUESTED %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - return; - } - if (ftdmchan->state != FTDM_CHANNEL_STATE_IN_LOOP) { - ftdm_log(FTDM_LOG_WARNING, "Got stop loop request in a channel that is not in loop, ignoring ...\n"); - return; - } - stop_loop(ftdmchan); -} - -/** - * \brief Handler for heartbeat event - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static void handle_heartbeat(sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - int err; - - err = sangomabc_connection_writep(mcon, (sangomabc_event_t*)event); - - if (err <= 0) { - ftdm_log(FTDM_LOG_CRIT, "Failed to tx on boost connection [%s]: %s\n", strerror(errno)); - } - return; -} - -/** - * \brief Handler for restart ack event - * \param mcon sangoma boost connection - * \param span Span where event was fired - * \param event Event to handle - */ -static void handle_restart_ack(sangomabc_connection_t *mcon, ftdm_span_t *span, sangomabc_short_event_t *event) -{ - ftdm_log(FTDM_LOG_DEBUG, "RECV RESTART ACK\n"); -} - -/** - * \brief Handler for restart event - * \param mcon sangoma boost connection - * \param span Span where event was fired - * \param event Event to handle - */ -static void handle_restart(sangomabc_connection_t *mcon, ftdm_span_t *span, sangomabc_short_event_t *event) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - mcon->rxseq_reset = 0; - ftdm_set_flag((&sangoma_boost_data->mcon), MSU_FLAG_DOWN); - ftdm_set_flag_locked(span, FTDM_SPAN_SUSPENDED); - ftdm_set_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RESTARTING); - -} - -/** - * \brief Handler for incoming digit event - * \param mcon sangoma boost connection - * \param span Span where event was fired - * \param event Event to handle - */ -static void handle_incoming_digit(sangomabc_connection_t *mcon, ftdm_span_t *span, sangomabc_event_t *event) -{ - ftdm_channel_t *ftdmchan = NULL; - char digits[MAX_DIALED_DIGITS + 2] = ""; - - if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t *)event, 1))) { - ftdm_log(FTDM_LOG_ERROR, "Invalid channel\n"); - return; - } - - if (event->called_number_digits_count == 0) { - ftdm_log(FTDM_LOG_WARNING, "Error Incoming digit with len %s %d [w%dg%d]\n", - event->called_number_digits, - event->called_number_digits_count, - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - return; - } - - ftdm_log(FTDM_LOG_WARNING, "Incoming digit with len %s %d [w%dg%d]\n", - event->called_number_digits, - event->called_number_digits_count, - BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - - memcpy(digits, event->called_number_digits, event->called_number_digits_count); - ftdm_channel_queue_dtmf(ftdmchan, digits); - - return; -} - - -/** - * \brief Checks if span has state changes pending and processes - * \param span Span where event was fired - * \param event Event to handle - * \return The locked FTDM channel associated to the event if any, NULL otherwise - */ -static ftdm_channel_t* event_process_states(ftdm_span_t *span, sangomabc_short_event_t *event) -{ - ftdm_channel_t *ftdmchan = NULL; - ftdm_sangoma_boost_data_t *signal_data = span->signal_data; - - switch (event->event_id) { - case SIGBOOST_EVENT_CALL_START_NACK: - case SIGBOOST_EVENT_CALL_START_NACK_ACK: - if (event->call_setup_id && !signal_data->sigmod) { - return NULL; - } - //if event->span and event->chan is valid, fall-through - case SIGBOOST_EVENT_CALL_START: - case SIGBOOST_EVENT_CALL_START_ACK: - case SIGBOOST_EVENT_CALL_STOPPED: - case SIGBOOST_EVENT_CALL_PROGRESS: - case SIGBOOST_EVENT_CALL_ANSWERED: - case SIGBOOST_EVENT_CALL_STOPPED_ACK: - case SIGBOOST_EVENT_DIGIT_IN: - case SIGBOOST_EVENT_INSERT_CHECK_LOOP: - case SIGBOOST_EVENT_REMOVE_CHECK_LOOP: - case SIGBOOST_EVENT_CALL_RELEASED: - if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 1))) { - ftdm_log(FTDM_LOG_CRIT, "could not find channel %d:%d to process pending state changes!\n", - BOOST_EVENT_SPAN(signal_data->sigmod, event), - BOOST_EVENT_CHAN(signal_data->sigmod, event)); - return NULL; - } - break; - case SIGBOOST_EVENT_HEARTBEAT: - case SIGBOOST_EVENT_SYSTEM_RESTART_ACK: - case SIGBOOST_EVENT_SYSTEM_RESTART: - case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE: - return NULL; - default: - ftdm_log(FTDM_LOG_CRIT, "Unhandled event id: %d\n", event->event_id); - return NULL; - } - - ftdm_mutex_lock(ftdmchan->mutex); - ftdm_channel_advance_states(ftdmchan); - return ftdmchan; -} - -/** - * \brief Handler for sangoma boost event - * \param span Span where event was fired - * \param mcon sangoma boost connection - * \param event Event to handle - */ -static int parse_sangoma_event(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_short_event_t *event) -{ - ftdm_channel_t* ftdmchan = NULL; - - if (!ftdm_running()) { - ftdm_log(FTDM_LOG_WARNING, "System is shutting down.\n"); - return -1; - } - - ftdm_assert_return(event->call_setup_id <= MAX_REQ_ID, -1, "Unexpected call setup id\n"); - - /* process all pending state changes for that channel before - * processing the new boost event */ - ftdmchan = event_process_states(span, event); - - switch(event->event_id) { - case SIGBOOST_EVENT_CALL_START: - handle_call_start(span, mcon, (sangomabc_event_t*)event); - break; - case SIGBOOST_EVENT_CALL_STOPPED: - handle_call_stop(span, mcon, event); - break; - case SIGBOOST_EVENT_CALL_RELEASED: - handle_call_released(span, mcon, event); - break; - case SIGBOOST_EVENT_CALL_START_ACK: - handle_call_start_ack(mcon, event); - break; - case SIGBOOST_EVENT_CALL_PROGRESS: - handle_call_progress(span, mcon, event); - break; - case SIGBOOST_EVENT_CALL_START_NACK: - handle_call_start_nack(span, mcon, event); - break; - case SIGBOOST_EVENT_CALL_ANSWERED: - handle_call_answer(span, mcon, event); - break; - case SIGBOOST_EVENT_HEARTBEAT: - handle_heartbeat(mcon, event); - break; - case SIGBOOST_EVENT_CALL_STOPPED_ACK: - handle_call_done(span, mcon, event); - break; - case SIGBOOST_EVENT_CALL_START_NACK_ACK: - /* On NACK ack span chan are always invalid - All there is to do is to clear the id */ - if (event->call_setup_id) { - nack_map[event->call_setup_id] = 0; - release_request_id(event->call_setup_id); - } else { - handle_call_done(span, mcon, event); - } - break; - case SIGBOOST_EVENT_INSERT_CHECK_LOOP: - handle_call_loop_start(span, mcon, event); - break; - case SIGBOOST_EVENT_REMOVE_CHECK_LOOP: - handle_call_loop_stop(span, mcon, event); - break; - case SIGBOOST_EVENT_SYSTEM_RESTART_ACK: - handle_restart_ack(mcon, span, event); - break; - case SIGBOOST_EVENT_SYSTEM_RESTART: - handle_restart(mcon, span, event); - break; - case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE: - //handle_gap_abate(event); - break; - case SIGBOOST_EVENT_DIGIT_IN: - handle_incoming_digit(mcon, span, (sangomabc_event_t*)event); - break; - default: - ftdm_log(FTDM_LOG_WARNING, "No handler implemented for [%s]\n", sangomabc_event_id_name(event->event_id)); - break; - } - - if(ftdmchan != NULL) { - ftdm_channel_advance_states(ftdmchan); - ftdm_mutex_unlock(ftdmchan->mutex); - } - - return 0; - -} - -/** - * \brief Handler for channel state change - * \param ftdmchan Channel to handle - */ -static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - sangomabc_connection_t *mcon = &sangoma_boost_data->mcon; - ftdm_sigmsg_t sig; - ftdm_status_t status; - - - ftdm_assert_return(ftdmchan->last_state != ftdmchan->state, FTDM_FAIL, "Channel state already processed\n"); - - ftdm_log(FTDM_LOG_DEBUG, "%d:%d PROCESSING STATE [%s]\n", ftdmchan->span_id, ftdmchan->chan_id, ftdm_channel_state2str(ftdmchan->state)); - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = ftdmchan->chan_id; - sig.span_id = ftdmchan->span_id; - sig.channel = ftdmchan; - - ftdm_channel_complete_state(ftdmchan); - - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_DOWN: - { - int call_stopped_ack_sent = 0; - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_IN_LOOP) { - ftdm_log(FTDM_LOG_DEBUG, "%d:%d terminating loop\n", ftdmchan->span_id, ftdmchan->chan_id); - } else { - release_request_id_span_chan(ftdmchan->physical_span_id, ftdmchan->physical_chan_id); - - if (!ftdm_test_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG)) { - ftdm_set_sflag_locked(ftdmchan, SFLAG_SENT_FINAL_MSG); - - if (ftdmchan->call_data && CALL_DATA(ftdmchan)->last_event_id == SIGBOOST_EVENT_CALL_START_NACK) { - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - CALL_DATA(ftdmchan)->call_setup_id, - SIGBOOST_EVENT_CALL_START_NACK_ACK, - 0, 0); - - } else { - /* we got a call stop msg, time to reply with call stopped ack */ - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_STOPPED_ACK, - 0, 0); - call_stopped_ack_sent = 1; - } - } - } - - ftdmchan->sflags = 0; - memset(ftdmchan->call_data, 0, sizeof(sangoma_boost_call_t)); - if (sangoma_boost_data->sigmod && call_stopped_ack_sent) { - /* we dont want to call ftdm_channel_close just yet until call released is received */ - ftdm_log(FTDM_LOG_DEBUG, "Waiting for call release confirmation before declaring chan %d:%d as available \n", - ftdmchan->span_id, ftdmchan->chan_id); - } else { - ftdm_channel_t *toclose = ftdmchan; - ftdm_channel_close(&toclose); - } - } - break; - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA; - if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } - } else { - if (!ftdm_test_sflag(ftdmchan, SFLAG_SENT_ACK)) { - ftdm_set_sflag(ftdmchan, SFLAG_SENT_ACK); - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_START_ACK, - 0, 0); - } - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_PROGRESS, - 0, SIGBOOST_PROGRESS_MEDIA); - } - } - break; - case FTDM_CHANNEL_STATE_PROGRESS: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_PROGRESS; - if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } - } else { - if (!ftdm_test_sflag(ftdmchan, SFLAG_SENT_ACK)) { - ftdm_set_sflag(ftdmchan, SFLAG_SENT_ACK); - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_START_ACK, - 0, SIGBOOST_PROGRESS_RING); - } - } - } - break; - case FTDM_CHANNEL_STATE_IDLE: - case FTDM_CHANNEL_STATE_HOLD: - { - /* twiddle */ - } - break; - case FTDM_CHANNEL_STATE_RING: - { - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_START; - if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } - } - } - break; - case FTDM_CHANNEL_STATE_RESTART: - { - sig.event_id = FTDM_SIGEVENT_RESTART; - status = ftdm_span_send_signal(ftdmchan->span, &sig); - ftdm_set_sflag_locked(ftdmchan, SFLAG_SENT_FINAL_MSG); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - break; - case FTDM_CHANNEL_STATE_UP: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_UP; - if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } - } else { - if (!(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_PROGRESS) || ftdm_test_flag(ftdmchan, FTDM_CHANNEL_MEDIA))) { - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_START_ACK, - 0, 0); - } - - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_ANSWERED, - 0, 0); - } - } - break; - case FTDM_CHANNEL_STATE_DIALING: - { - char dnis[128] = ""; - sangoma_boost_request_id_t r; - sangomabc_event_t event = {0}; - - ftdm_assert(sangoma_boost_data->sigmod != NULL, "We should be in sigmod here!\n"); - - ftdm_set_string(dnis, ftdmchan->caller_data.dnis.digits); - - r = next_request_id(); - if (r == 0) { - ftdm_log(FTDM_LOG_CRIT, "All boost request ids are busy.\n"); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - } - - sangomabc_call_init(&event, ftdmchan->caller_data.cid_num.digits, dnis, r); - - event.span = (uint8_t)ftdmchan->physical_span_id; - event.chan = (uint8_t)ftdmchan->physical_chan_id; - /* because we already have a span/chan here we bind to the SETUP_GRID now and not on call start ack */ - SETUP_GRID[event.span][event.chan] = event.call_setup_id; - - ftdm_set_string(event.calling_name, ftdmchan->caller_data.cid_name); - ftdm_set_string(event.rdnis.digits, ftdmchan->caller_data.rdnis.digits); - if (strlen(ftdmchan->caller_data.rdnis.digits)) { - event.rdnis.digits_count = (uint8_t)strlen(ftdmchan->caller_data.rdnis.digits)+1; - event.rdnis.ton = ftdmchan->caller_data.rdnis.type; - event.rdnis.npi = ftdmchan->caller_data.rdnis.plan; - } - - event.calling.screening_ind = ftdmchan->caller_data.screen; - event.calling.presentation_ind = ftdmchan->caller_data.pres; - - event.calling.ton = ftdmchan->caller_data.cid_num.type; - event.calling.npi = ftdmchan->caller_data.cid_num.plan; - - event.called.ton = ftdmchan->caller_data.dnis.type; - event.called.npi = ftdmchan->caller_data.dnis.plan; - - if (ftdmchan->caller_data.raw_data_len) { - ftdm_set_string(event.custom_data, ftdmchan->caller_data.raw_data); - event.custom_data_size = (uint16_t)ftdmchan->caller_data.raw_data_len; - } - - OUTBOUND_REQUESTS[r].status = BST_WAITING; - OUTBOUND_REQUESTS[r].span = ftdmchan->span; - OUTBOUND_REQUESTS[r].ftdmchan = ftdmchan; - - ftdm_log(FTDM_LOG_DEBUG, "Dialing number %s over boost channel with request id %d\n", event.called_number_digits, r); - if (sangomabc_connection_write(&sangoma_boost_data->mcon, &event) <= 0) { - release_request_id(r); - ftdm_log(FTDM_LOG_CRIT, "Failed to tx boost event [%s]\n", strerror(errno)); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - } - - } - break; - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - break; - case FTDM_CHANNEL_STATE_HANGUP: - { - ftdm_set_sflag_locked(ftdmchan, SFLAG_HANGUP); - - if (ftdm_test_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG) || ftdm_test_sflag(ftdmchan, SFLAG_TERMINATING)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - } else { - ftdm_set_sflag_locked(ftdmchan, SFLAG_SENT_FINAL_MSG); - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_ANSWERED) || - ftdm_test_flag(ftdmchan, FTDM_CHANNEL_PROGRESS) || - ftdm_test_flag(ftdmchan, FTDM_CHANNEL_MEDIA) || - ftdm_test_sflag(ftdmchan, SFLAG_RECVD_ACK)) { - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_STOPPED, - ftdmchan->caller_data.hangup_cause, 0); - } else { - sangomabc_exec_command(mcon, - BOOST_SPAN(ftdmchan), - BOOST_CHAN(ftdmchan), - 0, - SIGBOOST_EVENT_CALL_START_NACK, - ftdmchan->caller_data.hangup_cause, 0); - } - } - } - break; - case FTDM_CHANNEL_STATE_TERMINATING: - { - ftdm_set_sflag_locked(ftdmchan, SFLAG_TERMINATING); - sig.event_id = FTDM_SIGEVENT_STOP; - status = ftdm_span_send_signal(ftdmchan->span, &sig); - } - break; - case FTDM_CHANNEL_STATE_IN_LOOP: - { - /* nothing to do, we sent the FTDM_COMMAND_ENABLE_LOOP command in handle_call_loop_start() right away */ - } - break; - default: - break; - } - return FTDM_SUCCESS; -} - -/** - * \brief Initialises outgoing requests array - */ -static __inline__ void init_outgoing_array(void) -{ - memset(&OUTBOUND_REQUESTS, 0, sizeof(OUTBOUND_REQUESTS)); -} - -/** - * \brief Checks current state on a span - * \param span Span to check status on - */ -static __inline__ void check_state(ftdm_span_t *span) -{ - ftdm_channel_t *ftdmchan = NULL; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - int susp = ftdm_test_flag(span, FTDM_SPAN_SUSPENDED); - - if (susp && ftdm_check_state_all(span, FTDM_CHANNEL_STATE_DOWN)) { - susp = 0; - } - - if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE) || susp) { - uint32_t j; - ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE); - if (susp) { - for(j = 1; j <= span->chan_count; j++) { - if (ftdm_test_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE) || susp) { - ftdm_mutex_lock(span->channels[j]->mutex); - ftdm_clear_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE); - if (susp && span->channels[j]->state != FTDM_CHANNEL_STATE_DOWN) { - ftdm_set_state(span->channels[j], FTDM_CHANNEL_STATE_RESTART); - } - ftdm_channel_advance_states(span->channels[j]); - ftdm_mutex_unlock(span->channels[j]->mutex); - } - } - } else { - while ((ftdmchan = ftdm_queue_dequeue(span->pendingchans))) { - /* it can happen that someone else processed the chan states - * but without taking the chan out of the queue, so check th - * flag before advancing the state */ - ftdm_mutex_lock(ftdmchan->mutex); - ftdm_channel_advance_states(ftdmchan); - ftdm_mutex_unlock(ftdmchan->mutex); - } - } - } - - if (ftdm_test_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RESTARTING)) { - if (ftdm_check_state_all(span, FTDM_CHANNEL_STATE_DOWN)) { - sangomabc_exec_command(&sangoma_boost_data->mcon, - 0, - 0, - -1, - SIGBOOST_EVENT_SYSTEM_RESTART_ACK, - 0, 0); - ftdm_clear_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RESTARTING); - ftdm_clear_flag_locked(span, FTDM_SPAN_SUSPENDED); - ftdm_clear_flag((&sangoma_boost_data->mcon), MSU_FLAG_DOWN); - init_outgoing_array(); - } - } -} - - -/** - * \brief Checks for events on a span - * \param span Span to check for events - */ -static __inline__ ftdm_status_t check_events(ftdm_span_t *span, int ms_timeout) -{ - ftdm_status_t status; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - status = ftdm_span_poll_event(span, ms_timeout, NULL); - - switch(status) { - case FTDM_SUCCESS: - { - ftdm_event_t *event; - while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) { - switch (event->enum_id) { - case FTDM_OOB_ALARM_TRAP: - if (sangoma_boost_data->sigmod) { - sangoma_boost_data->sigmod->on_hw_link_status_change(event->channel, FTDM_HW_LINK_DISCONNECTED); - } - break; - case FTDM_OOB_ALARM_CLEAR: - if (sangoma_boost_data->sigmod) { - sangoma_boost_data->sigmod->on_hw_link_status_change(event->channel, FTDM_HW_LINK_CONNECTED); - } - break; - } - } - } - break; - case FTDM_FAIL: - { - if (!ftdm_running()) { - break; - } - ftdm_log(FTDM_LOG_ERROR, "Boost Check Event Failure Failure: %s\n", span->last_error); - return FTDM_FAIL; - } - break; - default: - break; - } - - return FTDM_SUCCESS; -} - -/** - * \brief Main thread function for sangoma boost span (monitor) - * \param me Current thread - * \param obj Span to run in this thread - */ -static void *ftdm_sangoma_events_run(ftdm_thread_t *me, void *obj) -{ - ftdm_span_t *span = (ftdm_span_t *) obj; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - unsigned errs = 0; - - while (ftdm_test_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_EVENTS_RUNNING) && ftdm_running()) { - if (check_events(span, 100) != FTDM_SUCCESS) { - if (errs++ > 50) { - ftdm_log(FTDM_LOG_ERROR, "Too many event errors, quitting sangoma events thread\n"); - return NULL; - } - } - } - - ftdm_log(FTDM_LOG_DEBUG, "Sangoma Boost Events thread ended.\n"); - - ftdm_clear_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_EVENTS_RUNNING); - - return NULL; -} - -static ftdm_status_t ftdm_boost_connection_open(ftdm_span_t *span) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - if (sangoma_boost_data->sigmod) { - if (sangoma_boost_data->sigmod->start_span(span) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - ftdm_clear_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RESTARTING); - ftdm_clear_flag_locked(span, FTDM_SPAN_SUSPENDED); - ftdm_clear_flag((&sangoma_boost_data->mcon), MSU_FLAG_DOWN); - } - - sangoma_boost_data->pcon = sangoma_boost_data->mcon; - - /* when sigmod is present, all arguments: local_ip etc, are ignored by sangomabc_connection_open */ - if (sangomabc_connection_open(&sangoma_boost_data->mcon, - sangoma_boost_data->mcon.cfg.local_ip, - sangoma_boost_data->mcon.cfg.local_port, - sangoma_boost_data->mcon.cfg.remote_ip, - sangoma_boost_data->mcon.cfg.remote_port) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Error: Opening MCON Socket [%d] %s\n", sangoma_boost_data->mcon.socket, strerror(errno)); - return FTDM_FAIL; - } - - if (sangomabc_connection_open(&sangoma_boost_data->pcon, - sangoma_boost_data->pcon.cfg.local_ip, - ++sangoma_boost_data->pcon.cfg.local_port, - sangoma_boost_data->pcon.cfg.remote_ip, - ++sangoma_boost_data->pcon.cfg.remote_port) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Error: Opening PCON Socket [%d] %s\n", sangoma_boost_data->pcon.socket, strerror(errno)); - return FTDM_FAIL; - } - - /* try to create the boost sockets interrupt objects */ - if (ftdm_interrupt_create(&sangoma_boost_data->pcon.sock_interrupt, sangoma_boost_data->pcon.socket) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Span %s could not create its boost msock interrupt!\n", span->name); - return FTDM_FAIL; - } - - if (ftdm_interrupt_create(&sangoma_boost_data->mcon.sock_interrupt, sangoma_boost_data->mcon.socket) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Span %s could not create its boost psock interrupt!\n", span->name); - return FTDM_FAIL; - } - - return FTDM_SUCCESS; -} - -/*! - \brief wait for a boost event - \return -1 on error, 0 on timeout, 1 when there are events - */ -static int ftdm_boost_wait_event(ftdm_span_t *span) -{ - ftdm_status_t res; - ftdm_interrupt_t *ints[3]; - int numints; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - ftdm_queue_get_interrupt(span->pendingchans, &ints[0]); - numints = 1; - /* if in queue mode wait for both the pendingchans queue and the boost msg queue */ - if (sangoma_boost_data->sigmod) { - ftdm_queue_get_interrupt(sangoma_boost_data->boost_queue, &ints[1]); - numints = 2; - } -#ifndef __WINDOWS__ - else { - /* socket mode ... */ - ints[1] = sangoma_boost_data->mcon.sock_interrupt; - ints[2] = sangoma_boost_data->pcon.sock_interrupt; - numints = 3; - sangoma_boost_data->iteration = 0; - } -#endif - res = ftdm_interrupt_multiple_wait(ints, numints, 100); - if (FTDM_SUCCESS != res && FTDM_TIMEOUT != res) { - ftdm_log(FTDM_LOG_CRIT, "Unexpected return value from interrupt waiting: %d\n", res); - return -1; - } - return 0; -} - - -static sangomabc_event_t *ftdm_boost_read_event(ftdm_span_t *span) -{ - sangomabc_event_t *event = NULL; - sangomabc_connection_t *mcon, *pcon; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - mcon = &sangoma_boost_data->mcon; - pcon = &sangoma_boost_data->pcon; - - event = sangomabc_connection_readp(pcon, sangoma_boost_data->iteration); - - /* if there is no event and this is not a sigmod-driven span it's time to try the other connection for events */ - if (!event && !sangoma_boost_data->sigmod) { - event = sangomabc_connection_read(mcon, sangoma_boost_data->iteration); - } - - return event; -} - -/** - * \brief Main thread function for sangoma boost span (monitor) - * \param me Current thread - * \param obj Span to run in this thread - */ -static void *ftdm_sangoma_boost_run(ftdm_thread_t *me, void *obj) -{ - ftdm_span_t *span = (ftdm_span_t *) obj; - sangomabc_connection_t *mcon, *pcon; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - mcon = &sangoma_boost_data->mcon; - pcon = &sangoma_boost_data->pcon; - - /* sigmod overrides socket functionality if not null */ - if (sangoma_boost_data->sigmod) { - mcon->span = span; - pcon->span = span; - /* everything could be retrieved through span, but let's use shortcuts */ - mcon->sigmod = sangoma_boost_data->sigmod; - pcon->sigmod = sangoma_boost_data->sigmod; - mcon->boost_queue = sangoma_boost_data->boost_queue; - pcon->boost_queue = sangoma_boost_data->boost_queue; - } - - if (ftdm_boost_connection_open(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "ftdm_boost_connection_open failed\n"); - goto end; - } - - init_outgoing_array(); - if (!sangoma_boost_data->sigmod) { - sangomabc_exec_commandp(pcon, - 0, - 0, - -1, - SIGBOOST_EVENT_SYSTEM_RESTART, - 0); - ftdm_set_flag(mcon, MSU_FLAG_DOWN); - } - - while (ftdm_test_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING)) { - sangomabc_event_t *event = NULL; - - if (!ftdm_running()) { - if (!sangoma_boost_data->sigmod) { - sangomabc_exec_commandp(pcon, - 0, - 0, - -1, - SIGBOOST_EVENT_SYSTEM_RESTART, - 0); - ftdm_set_flag(mcon, MSU_FLAG_DOWN); - } - ftdm_log(FTDM_LOG_DEBUG, "ftdm is no longer running\n"); - break; - } - - if (ftdm_boost_wait_event(span) < 0) { - ftdm_log(FTDM_LOG_ERROR, "ftdm_boost_wait_event failed\n"); - } - - while ((event = ftdm_boost_read_event(span))) { - parse_sangoma_event(span, pcon, (sangomabc_short_event_t*)event); - sangoma_boost_data->iteration++; - } - - check_state(span); - } - -end: - if (!sangoma_boost_data->sigmod) { - sangomabc_connection_close(&sangoma_boost_data->mcon); - sangomabc_connection_close(&sangoma_boost_data->pcon); - } - - ftdm_clear_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING); - - ftdm_log(FTDM_LOG_DEBUG, "Sangoma Boost thread ended.\n"); - return NULL; -} - -#if 0 -static int sigmod_ss7box_isup_exec_cmd(ftdm_stream_handle_t *stream, char *cmd) -{ - FILE *fp; - int status=0; - char path[1024]; - - fp = popen(cmd, "r"); - if (fp == NULL) { - stream->write_function(stream, "%s: -ERR failed to execute cmd: %s\n", - __FILE__,cmd); - return -1; - } - - while (fgets(path, sizeof(path)-1, fp) != NULL) { - path[sizeof(path)-1]='\0'; - stream->write_function(stream,"%s", path); - } - - - status = pclose(fp); - if (status == -1) { - /* Error reported by pclose() */ - } else { - /* Use macros described under wait() to inspect `status' in order - to determine success/failure of command executed by popen() */ - } - - return status; -} -#endif - -static void ftdm_cli_span_state_cmd(ftdm_span_t *span, char *state) -{ - unsigned int j; - int cnt=0; - ftdm_channel_state_t state_e = ftdm_str2ftdm_channel_state(state); - if (state_e == FTDM_CHANNEL_STATE_INVALID) { - ftdm_log(FTDM_LOG_CRIT, "Checking for channels not in the INVALID state is probably not what you want\n"); - } - for(j = 1; j <= span->chan_count; j++) { - if (span->channels[j]->state != state_e) { - ftdm_channel_t *ftdmchan = span->channels[j]; - ftdm_log(FTDM_LOG_CRIT, "Channel %i s%dc%d State=%s\n", - j, ftdmchan->physical_span_id-1, ftdmchan->physical_chan_id-1, ftdm_channel_state2str(ftdmchan->state)); - cnt++; - } - } - ftdm_log(FTDM_LOG_CRIT, "Total Channel Cnt %i\n",cnt); -} - -#define FTDM_BOOST_SYNTAX "list sigmods | | tracelevel " -/** - * \brief API function to kill or debug a sangoma_boost span - * \param stream API stream handler - * \param data String containing argurments - * \return Flags - */ -static FIO_API_FUNCTION(ftdm_sangoma_boost_api) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - - if (data) { - mycmd = ftdm_strdup(data); - argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (argc > 1) { - if (!strcasecmp(argv[0], "list")) { - if (!strcasecmp(argv[1], "sigmods")) { - if (ftdm_sangoma_boost_list_sigmods(stream) != FTDM_SUCCESS) { - stream->write_function(stream, "-ERR failed to list sigmods\n"); - goto done; - } - goto done; - } - - if (!strcasecmp(argv[1], "ids")) { - print_request_ids(); - goto done; - } - } else if (!strcasecmp(argv[0], "tracelevel")) { - ftdm_status_t status; - const char *levelname = NULL; - int dbglevel; - ftdm_sangoma_boost_data_t *sangoma_boost_data; - ftdm_span_t *span; - - if (argc <= 2) { - stream->write_function(stream, "-ERR usage: tracelevel \n"); - goto done; - } - - status = ftdm_span_find_by_name(argv[1], &span); - if (FTDM_SUCCESS != status) { - stream->write_function(stream, "-ERR failed to find span by name %s\n", argv[1]); - goto done; - } - - if (span->signal_type != FTDM_SIGTYPE_SANGOMABOOST) { - stream->write_function(stream, "-ERR span %s is not of boost type\n", argv[1]); - goto done; - } - - for (dbglevel = 0; (levelname = FTDM_LEVEL_NAMES[dbglevel]); dbglevel++) { - if (!strcasecmp(levelname, argv[2])) { - break; - } - } - - if (!levelname) { - stream->write_function(stream, "-ERR invalid log level %s\n", argv[2]); - goto done; - } - - sangoma_boost_data = span->signal_data; - sangoma_boost_data->pcon.debuglevel = dbglevel; - sangoma_boost_data->mcon.debuglevel = dbglevel; - stream->write_function(stream, "+OK span %s has now trace level %s\n", argv[1], FTDM_LEVEL_NAMES[dbglevel]); - goto done; -#ifndef __WINDOWS__ -#if 0 -/* NC: This code crashes the kernel due to fork on heavy fs load */ - } else if (!strcasecmp(argv[0], "ss7box_isupd_ckt")) { - - if (!strcasecmp(argv[1], "used")) { - stream->write_function(stream, "ss7box_isupd: in use\n", FTDM_BOOST_SYNTAX); - sigmod_ss7box_isup_exec_cmd(stream, (char*) "ckt_report.sh inuse"); - } else if (!strcasecmp(argv[1], "reset")) { - stream->write_function(stream, "ss7box_isupd: in reset\n", FTDM_BOOST_SYNTAX); - sigmod_ss7box_isup_exec_cmd(stream, (char*) "ckt_report.sh reset"); - } else if (!strcasecmp(argv[1], "ready")) { - stream->write_function(stream, "ss7box_isupd: ready \n", FTDM_BOOST_SYNTAX); - sigmod_ss7box_isup_exec_cmd(stream, (char*) "ckt_report.sh free"); - } else { - stream->write_function(stream, "ss7box_isupd: list\n", FTDM_BOOST_SYNTAX); - sigmod_ss7box_isup_exec_cmd(stream, (char*) "ckt_report.sh"); - } - - goto done; -#endif -#endif - - } else if (!strcasecmp(argv[0], "span")) { - int err; - sangomabc_connection_t *pcon; - ftdm_sangoma_boost_data_t *sangoma_boost_data; - ftdm_span_t *span; - - if (argc <= 2) { - stream->write_function(stream, "-ERR invalid span usage: span \n"); - goto done; - } - - err = ftdm_span_find_by_name(argv[1], &span); - if (FTDM_SUCCESS != err) { - stream->write_function(stream, "-ERR failed to find span by name %s\n",argv[1]); - goto done; - } - - if (!strcasecmp(argv[2], "restart")) { - sangoma_boost_data = span->signal_data; - pcon = &sangoma_boost_data->pcon; - - /* No need to set any span flags because - our RESTART will generate a RESTART from the sig daemon */ - sangomabc_exec_commandp(pcon, - 0, - 0, - -1, - SIGBOOST_EVENT_SYSTEM_RESTART, - 0); - } else if (!strcasecmp(argv[2], "state")) { - if (argc <= 3) { - stream->write_function(stream, "-ERR invalid span state: span state \n"); - goto done; - } - ftdm_cli_span_state_cmd(span,argv[3]); - } - - goto done; - - } else { - boost_sigmod_interface_t *sigmod_iface = NULL; - sigmod_iface = hashtable_search(g_boost_modules_hash, argv[0]); - if (sigmod_iface) { - char *p = strchr(data, ' '); - if (++p) { - char* mydup = strdup(p); - if(sigmod_iface->exec_api == NULL) { - stream->write_function(stream, "%s does not support api functions\n", sigmod_iface->name); - goto done; - } - //stream->write_function(stream, "sigmod:%s command:%s\n", sigmod_iface->name, mydup); - if (sigmod_iface->exec_api(stream, mydup) != FTDM_SUCCESS) { - stream->write_function(stream, "-ERR:failed to execute command:%s\n", mydup); - } - free(mydup); - } - - goto done; - } else { - stream->write_function(stream, "-ERR: Could not find sigmod %s\n", argv[0]); - } - } - } - stream->write_function(stream, "-ERR: Usage: %s\n", FTDM_BOOST_SYNTAX); -done: - ftdm_safe_free(mycmd); - return FTDM_SUCCESS; -} - -/** - * \brief Loads sangoma_boost IO module - * \param fio FreeTDM IO interface - * \return Success - */ -static FIO_IO_LOAD_FUNCTION(ftdm_sangoma_boost_io_init) -{ - ftdm_assert(fio != NULL, "fio is NULL"); - memset(&ftdm_sangoma_boost_interface, 0, sizeof(ftdm_sangoma_boost_interface)); - - ftdm_sangoma_boost_interface.name = "boost"; - ftdm_sangoma_boost_interface.api = ftdm_sangoma_boost_api; - - *fio = &ftdm_sangoma_boost_interface; - - return FTDM_SUCCESS; -} - -/** - * \brief Loads sangoma boost signaling module - * \param fio FreeTDM IO interface - * \return Success - */ -static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_boost_init) -{ - g_boost_modules_hash = create_hashtable(10, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - if (!g_boost_modules_hash) { - return FTDM_FAIL; - } - ftdm_mutex_create(&request_mutex); - ftdm_mutex_create(&g_boost_modules_mutex); - memset(&g_trunkgroups[0], 0, sizeof(g_trunkgroups)); - return FTDM_SUCCESS; -} - -static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_boost_destroy) -{ - ftdm_hash_iterator_t *i = NULL; - boost_sigmod_interface_t *sigmod = NULL; - const void *key = NULL; - void *val = NULL; - ftdm_dso_lib_t lib; - ftdm_log(FTDM_LOG_DEBUG, "Destroying sangoma boost module\n"); - for (i = hashtable_first(g_boost_modules_hash); i; i = hashtable_next(i)) { - hashtable_this(i, &key, NULL, &val); - if (key && val) { - sigmod = val; - lib = sigmod->pvt; - ftdm_log(FTDM_LOG_DEBUG, "destroying sigmod %s\n", sigmod->name); - sigmod->on_unload(); - ftdm_dso_destroy(&lib); - } - } - - hashtable_destroy(g_boost_modules_hash); - ftdm_mutex_destroy(&request_mutex); - ftdm_mutex_destroy(&g_boost_modules_mutex); - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_sangoma_boost_start(ftdm_span_t *span) -{ - int err; - - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - ftdm_set_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING); - err = ftdm_thread_create_detached(ftdm_sangoma_boost_run, span); - if (err) { - ftdm_clear_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING); - return err; - } - - // launch the events thread to handle HW DTMF and possibly - // other events in the future - ftdm_set_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_EVENTS_RUNNING); - err = ftdm_thread_create_detached(ftdm_sangoma_events_run, span); - if (err) { - ftdm_clear_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_EVENTS_RUNNING); - ftdm_clear_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING); - } - - return err; -} - -static ftdm_status_t ftdm_sangoma_boost_stop(ftdm_span_t *span) -{ - int cnt = 50; - ftdm_status_t status = FTDM_SUCCESS; - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - - if (sangoma_boost_data->sigmod) { - /* I think stopping the span before destroying the queue makes sense - otherwise may be boost events would still arrive when the queue is already destroyed! */ - status = sangoma_boost_data->sigmod->stop_span(span); - if (status != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to stop span %s boost signaling\n", span->name); - return FTDM_FAIL; - } - ftdm_queue_enqueue(sangoma_boost_data->boost_queue, NULL); - } - - while (ftdm_test_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING) && cnt-- > 0) { - ftdm_log(FTDM_LOG_DEBUG, "Waiting for boost thread\n"); - ftdm_sleep(100); - } - - if (!cnt) { - ftdm_log(FTDM_LOG_CRIT, "it seems boost thread in span %s may be stuck, we may segfault :-(\n", span->name); - return FTDM_FAIL; - } - - cnt = 50; - while (ftdm_test_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_EVENTS_RUNNING) && cnt-- > 0) { - ftdm_log(FTDM_LOG_DEBUG, "Waiting for boost events thread\n"); - ftdm_sleep(100); - } - - if (!cnt) { - ftdm_log(FTDM_LOG_CRIT, "it seems boost events thread in span %s may be stuck, we may segfault :-(\n", span->name); - return FTDM_FAIL; - } - - if (sangoma_boost_data->sigmod) { - ftdm_queue_destroy(&sangoma_boost_data->boost_queue); - } - - return status; -} - -static ftdm_state_map_t boost_state_map = { - { - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_ANY_STATE}, - {FTDM_CHANNEL_STATE_RESTART, FTDM_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESTART, FTDM_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_IDLE, FTDM_CHANNEL_STATE_HOLD, FTDM_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HOLD, FTDM_END}, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, - FTDM_CHANNEL_STATE_IDLE, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_HANGUP, FTDM_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_IDLE, FTDM_CHANNEL_STATE_DIALING, FTDM_END}, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_IDLE, FTDM_CHANNEL_STATE_DIALING, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_HANGUP, FTDM_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END} - }, - - /****************************************/ - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_ANY_STATE}, - {FTDM_CHANNEL_STATE_RESTART, FTDM_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESTART, FTDM_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN}, - {FTDM_CHANNEL_STATE_IN_LOOP, FTDM_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_IN_LOOP}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, - {FTDM_CHANNEL_STATE_RING, FTDM_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RING, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,FTDM_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_HANGUP, FTDM_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}, - }, - - - } -}; - -static BOOST_WRITE_MSG_FUNCTION(ftdm_boost_write_msg) -{ - sangomabc_short_event_t *shortmsg = NULL; - ftdm_sangoma_boost_data_t *sangoma_boost_data = NULL; - sangomabc_queue_element_t *element = NULL; - - ftdm_assert_return(msg != NULL, FTDM_FAIL, "Boost message to write was null"); - - if (!span) { - shortmsg = msg; - ftdm_log(FTDM_LOG_ERROR, "Unexpected boost message %d\n", shortmsg->event_id); - return FTDM_FAIL; - } - /* duplicate the event and enqueue it */ - element = ftdm_calloc(1, sizeof(*element)); - if (!element) { - return FTDM_FAIL; - } - memcpy(element->boostmsg, msg, msglen); - element->size = msglen; - - sangoma_boost_data = span->signal_data; - return ftdm_queue_enqueue(sangoma_boost_data->boost_queue, element); -} - -static BOOST_SIG_STATUS_CB_FUNCTION(ftdm_boost_sig_status_change) -{ - ftdm_sigmsg_t sig; - ftdm_log(FTDM_LOG_NOTICE, "%d:%d Signaling link status changed to %s\n", ftdmchan->span_id, ftdmchan->chan_id, ftdm_signaling_status2str(status)); - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = ftdmchan->chan_id; - sig.span_id = ftdmchan->span_id; - sig.channel = ftdmchan; - sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.ev_data.sigstatus.status = status; - ftdm_span_send_signal(ftdmchan->span, &sig); - return; -} - -static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(sangoma_boost_set_channel_sig_status) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - if (!sangoma_boost_data->sigmod) { - ftdm_log(FTDM_LOG_ERROR, "Cannot set signaling status in boost channel with no signaling module configured\n"); - return FTDM_FAIL; - } - if (!sangoma_boost_data->sigmod->set_channel_sig_status) { - ftdm_log(FTDM_LOG_ERROR, "Cannot set signaling status in boost channel: method not implemented\n"); - return FTDM_NOTIMPL; - } - return sangoma_boost_data->sigmod->set_channel_sig_status(ftdmchan, status); -} - -static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(sangoma_boost_get_channel_sig_status) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - if (!sangoma_boost_data->sigmod) { - return FTDM_FAIL; - } - if (!sangoma_boost_data->sigmod->get_channel_sig_status) { - return FTDM_NOTIMPL; - } - return sangoma_boost_data->sigmod->get_channel_sig_status(ftdmchan, status); -} - -static FIO_SPAN_SET_SIG_STATUS_FUNCTION(sangoma_boost_set_span_sig_status) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - if (!sangoma_boost_data->sigmod) { - ftdm_log(FTDM_LOG_ERROR, "Cannot set signaling status in boost span with no signaling module configured\n"); - return FTDM_FAIL; - } - if (!sangoma_boost_data->sigmod->set_span_sig_status) { - ftdm_log(FTDM_LOG_ERROR, "Cannot set signaling status in boost span: method not implemented\n"); - return FTDM_NOTIMPL; - } - return sangoma_boost_data->sigmod->set_span_sig_status(span, status); -} - -static FIO_SPAN_GET_SIG_STATUS_FUNCTION(sangoma_boost_get_span_sig_status) -{ - ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; - if (!sangoma_boost_data->sigmod) { - return FTDM_FAIL; - } - if (!sangoma_boost_data->sigmod->get_span_sig_status) { - ftdm_log(FTDM_LOG_ERROR, "Cannot get signaling status in boost span: method not implemented\n"); - return FTDM_NOTIMPL; - } - return sangoma_boost_data->sigmod->get_span_sig_status(span, status); -} - -/** - * \brief Initialises an sangoma boost span from configuration variables - * \param span Span to configure - * \param sig_cb Callback function for event signals - * \param ap List of configuration variables - * \return Success or failure - */ -static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_boost_configure_span) -{ -#define FAIL_CONFIG_RETURN(retstatus) \ - if (sangoma_boost_data) \ - ftdm_safe_free(sangoma_boost_data); \ - if (err) \ - ftdm_safe_free(err) \ - if (hash_locked) \ - ftdm_mutex_unlock(g_boost_modules_mutex); \ - if (lib) \ - ftdm_dso_destroy(&lib); \ - return retstatus; - - boost_sigmod_interface_t *sigmod_iface = NULL; - ftdm_sangoma_boost_data_t *sangoma_boost_data = NULL; - const char *local_ip = "127.0.0.65", *remote_ip = "127.0.0.66"; - const char *sigmod = NULL; - int local_port = 53000, remote_port = 53000; - const char *var = NULL, *val = NULL; - int hash_locked = 0; - ftdm_dso_lib_t lib = NULL; - char path[255] = ""; - char *err = NULL; - unsigned int j = 0; - unsigned paramindex = 0; - ftdm_status_t rc = FTDM_SUCCESS; - - for (; ftdm_parameters[paramindex].var; paramindex++) { - var = ftdm_parameters[paramindex].var; - val = ftdm_parameters[paramindex].val; - if (!strcasecmp(var, "sigmod")) { - sigmod = val; - } else if (!strcasecmp(var, "local_ip")) { - local_ip = val; - } else if (!strcasecmp(var, "remote_ip")) { - remote_ip = val; - } else if (!strcasecmp(var, "local_port")) { - local_port = atoi(val); - } else if (!strcasecmp(var, "remote_port")) { - remote_port = atoi(val); - } else if (!strcasecmp(var, "outbound-called-ton")) { - ftdm_set_ton(val, &span->default_caller_data.dnis.type); - } else if (!strcasecmp(var, "outbound-called-npi")) { - ftdm_set_npi(val, &span->default_caller_data.dnis.plan); - } else if (!strcasecmp(var, "outbound-calling-ton")) { - ftdm_set_ton(val, &span->default_caller_data.cid_num.type); - } else if (!strcasecmp(var, "outbound-calling-npi")) { - ftdm_set_npi(val, &span->default_caller_data.cid_num.plan); - } else if (!strcasecmp(var, "outbound-rdnis-ton")) { - ftdm_set_ton(val, &span->default_caller_data.rdnis.type); - } else if (!strcasecmp(var, "outbound-rdnis-npi")) { - ftdm_set_npi(val, &span->default_caller_data.rdnis.plan); - } else if (!sigmod) { - snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var); - FAIL_CONFIG_RETURN(FTDM_FAIL); - } - } - - if (!sigmod) { -#ifndef HAVE_NETINET_SCTP_H - ftdm_log(FTDM_LOG_CRIT, "No sigmod attribute in span %s, you must either specify a sigmod or re-compile with SCTP available to use socket mode boost!\n", span->name); - ftdm_set_string(span->last_error, "No sigmod configuration was set and there is no SCTP available!"); - FAIL_CONFIG_RETURN(FTDM_FAIL); -#else - if (!local_ip && local_port && remote_ip && remote_port && sig_cb) { - ftdm_set_string(span->last_error, "missing Sangoma boost IP parameters"); - FAIL_CONFIG_RETURN(FTDM_FAIL); - } -#endif - } - - sangoma_boost_data = ftdm_calloc(1, sizeof(*sangoma_boost_data)); - if (!sangoma_boost_data) { - FAIL_CONFIG_RETURN(FTDM_FAIL); - } - - /* WARNING: be sure to release this mutex on errors inside this if() */ - ftdm_mutex_lock(g_boost_modules_mutex); - hash_locked = 1; - if (sigmod && !(sigmod_iface = hashtable_search(g_boost_modules_hash, (void *)sigmod))) { - ftdm_build_dso_path(sigmod, path, sizeof(path)); - lib = ftdm_dso_open(path, &err); - if (!lib) { - ftdm_log(FTDM_LOG_ERROR, "Error loading Sangoma boost signaling module '%s': %s\n", path, err); - snprintf(span->last_error, sizeof(span->last_error), "Failed to load sangoma boost signaling module %s", path); - - FAIL_CONFIG_RETURN(FTDM_FAIL); - } - if (!(sigmod_iface = (boost_sigmod_interface_t *)ftdm_dso_func_sym(lib, BOOST_INTERFACE_NAME_STR, &err))) { - ftdm_log(FTDM_LOG_ERROR, "Failed to read Sangoma boost signaling module interface '%s': %s\n", path, err); - snprintf(span->last_error, sizeof(span->last_error), "Failed to read Sangoma boost signaling module interface '%s': %s", path, err); - - FAIL_CONFIG_RETURN(FTDM_FAIL); - } - rc = sigmod_iface->on_load(); - if (rc != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to load Sangoma boost signaling module interface '%s': on_load method failed (%d)\n", path, rc); - FAIL_CONFIG_RETURN(FTDM_FAIL); - } - sigmod_iface->pvt = lib; - sigmod_iface->set_write_msg_cb(ftdm_boost_write_msg); - sigmod_iface->set_sig_status_cb(ftdm_boost_sig_status_change); - hashtable_insert(g_boost_modules_hash, (void *)sigmod_iface->name, sigmod_iface, HASHTABLE_FLAG_NONE); - lib = NULL; /* destroying the lib will be done when going down and NOT on FAIL_CONFIG_RETURN */ - } - ftdm_mutex_unlock(g_boost_modules_mutex); - hash_locked = 0; - - if (sigmod_iface) { - /* try to create the boost queue */ - if (ftdm_queue_create(&sangoma_boost_data->boost_queue, BOOST_QUEUE_SIZE) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Span %s could not create its boost queue!\n", span->name); - FAIL_CONFIG_RETURN(FTDM_FAIL); - } - ftdm_log(FTDM_LOG_NOTICE, "Span %s will use Sangoma Boost Signaling Module %s\n", span->name, sigmod_iface->name); - sangoma_boost_data->sigmod = sigmod_iface; - sigmod_iface->configure_span(span, ftdm_parameters); - } else { - ftdm_log(FTDM_LOG_NOTICE, "Span %s will use boost socket mode\n", span->name); - ftdm_set_string(sangoma_boost_data->mcon.cfg.local_ip, local_ip); - sangoma_boost_data->mcon.cfg.local_port = local_port; - ftdm_set_string(sangoma_boost_data->mcon.cfg.remote_ip, remote_ip); - sangoma_boost_data->mcon.cfg.remote_port = remote_port; - } - - for (j = 1; j <= span->chan_count; j++) { - span->channels[j]->call_data = ftdm_calloc(1, sizeof(sangoma_boost_call_t)); - if (!span->channels[j]->call_data) { - FAIL_CONFIG_RETURN(FTDM_FAIL); - } - } - - span->signal_cb = sig_cb; - span->start = ftdm_sangoma_boost_start; - span->stop = ftdm_sangoma_boost_stop; - span->signal_data = sangoma_boost_data; - span->signal_type = FTDM_SIGTYPE_SANGOMABOOST; - span->outgoing_call = sangoma_boost_outgoing_call; - span->channel_request = sangoma_boost_channel_request; - span->get_channel_sig_status = sangoma_boost_get_channel_sig_status; - span->set_channel_sig_status = sangoma_boost_set_channel_sig_status; - span->get_span_sig_status = sangoma_boost_get_span_sig_status; - span->set_span_sig_status = sangoma_boost_set_span_sig_status; - span->state_map = &boost_state_map; - span->state_processor = state_advance; - sangoma_boost_data->mcon.debuglevel = FTDM_LOG_LEVEL_DEBUG; - sangoma_boost_data->pcon.debuglevel = FTDM_LOG_LEVEL_DEBUG; - ftdm_clear_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID); - ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE); - if (sigmod_iface) { - /* the core will do the hunting */ - span->channel_request = NULL; - } - ftdm_set_flag_locked(span, FTDM_SPAN_SUSPENDED); - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_sangoma_boost_list_sigmods(ftdm_stream_handle_t *stream) -{ - ftdm_hash_iterator_t *i = NULL; - boost_sigmod_interface_t *sigmod_iface = NULL; - const void *key = NULL; - void *val = NULL; - - stream->write_function(stream, "List of loaded sigmod modules:\n"); - for (i = hashtable_first(g_boost_modules_hash); i; i = hashtable_next(i)) { - hashtable_this(i, &key, NULL, &val); - if (key && val) { - sigmod_iface = val; - stream->write_function(stream, " %s\n", sigmod_iface->name); - } - } - stream->write_function(stream, "\n"); - return FTDM_SUCCESS; -} - -/** - * \brief FreeTDM sangoma boost signaling module definition - */ -EX_DECLARE_DATA ftdm_module_t ftdm_module = { - /*.name =*/ "sangoma_boost", - /*.io_load =*/ ftdm_sangoma_boost_io_init, - /*.io_unload =*/ NULL, - /*.sig_load = */ ftdm_sangoma_boost_init, - /*.sig_configure =*/ NULL, - /*.sig_unload = */ftdm_sangoma_boost_destroy, - /*.configure_span_signaling = */ ftdm_sangoma_boost_configure_span -}; - -/* 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/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.c deleted file mode 100644 index 6ddb74d253..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Copyright (c) 2007, Anthony Minessale II, Nenad Corbic - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _GNU_SOURCE - -#if HAVE_NETDB_H -#include -#endif - -#include "freetdm.h" -#include "sangoma_boost_client.h" - -#ifndef HAVE_GETHOSTBYNAME_R -extern int gethostbyname_r (const char *__name, - struct hostent *__result_buf, - char *__buf, size_t __buflen, - struct hostent **__result, - int *__h_errnop); -#endif - -struct sangomabc_map { - uint32_t event_id; - const char *name; -}; - -static struct sangomabc_map sangomabc_table[] = { - {SIGBOOST_EVENT_CALL_START, "CALL_START"}, - {SIGBOOST_EVENT_CALL_START_ACK, "CALL_START_ACK"}, - {SIGBOOST_EVENT_CALL_START_NACK, "CALL_START_NACK"}, - {SIGBOOST_EVENT_CALL_PROGRESS, "CALL PROGRESS"}, - {SIGBOOST_EVENT_CALL_START_NACK_ACK, "CALL_START_NACK_ACK"}, - {SIGBOOST_EVENT_CALL_ANSWERED, "CALL_ANSWERED"}, - {SIGBOOST_EVENT_CALL_STOPPED, "CALL_STOPPED"}, - {SIGBOOST_EVENT_CALL_STOPPED_ACK, "CALL_STOPPED_ACK"}, - {SIGBOOST_EVENT_CALL_RELEASED, "CALL_RELEASED"}, - {SIGBOOST_EVENT_SYSTEM_RESTART, "SYSTEM_RESTART"}, - {SIGBOOST_EVENT_SYSTEM_RESTART_ACK, "SYSTEM_RESTART_ACK"}, - {SIGBOOST_EVENT_HEARTBEAT, "HEARTBEAT"}, - {SIGBOOST_EVENT_INSERT_CHECK_LOOP, "LOOP START"}, - {SIGBOOST_EVENT_REMOVE_CHECK_LOOP, "LOOP STOP"}, - {SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE, "AUTO_CALL_GAP_ABATE"}, - {SIGBOOST_EVENT_DIGIT_IN, "DIGIT_IN"} -}; - - - -static void sangomabc_print_event_call(sangomabc_connection_t *mcon, sangomabc_event_t *event, int priority, int dir, const char *file, const char *func, int line) -{ - if (event->event_id == SIGBOOST_EVENT_HEARTBEAT) - return; - - ftdm_log(file, func, line, mcon->debuglevel, "%s EVENT (%s): %s:(%X) [w%dg%d] CSid=%i Seq=%i Cn=[%s] Cd=[%s] Ci=[%s] Rdnis=[%s]\n", - dir ? "TX":"RX", - priority ? "P":"N", - sangomabc_event_id_name(event->event_id), - event->event_id, - BOOST_EVENT_SPAN(mcon->sigmod, event), - BOOST_EVENT_CHAN(mcon->sigmod, event), - event->call_setup_id, - event->fseqno, - strlen(event->calling_name)?event->calling_name:"N/A", - (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), - (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"), - event->isup_in_rdnis); - -} -static void sangomabc_print_event_short(sangomabc_connection_t *mcon, sangomabc_short_event_t *event, int priority, int dir, const char *file, const char *func, int line) -{ - if (event->event_id == SIGBOOST_EVENT_HEARTBEAT) - return; - ftdm_log(file, func, line, mcon->debuglevel, "%s EVENT (%s): %s:(%X) [s%dc%d] Rc=%i CSid=%i Seq=%i \n", - dir ? "TX":"RX", - priority ? "P":"N", - sangomabc_event_id_name(event->event_id), - event->event_id, - BOOST_EVENT_SPAN(mcon->sigmod, event), - BOOST_EVENT_CHAN(mcon->sigmod, event), - event->release_cause, - event->call_setup_id, - event->fseqno); -} - - -static int create_conn_socket(sangomabc_connection_t *mcon, char *local_ip, int local_port, char *ip, int port) -{ -#ifndef WIN32 - int rc; - struct hostent *result, *local_result; - char buf[512], local_buf[512]; - int err = 0, local_err = 0; - - if (mcon->sigmod) { - ftdm_log(FTDM_LOG_WARNING, "I should not be called on a sigmod-managed connection!\n"); - return 0; - } - - memset(&mcon->remote_hp, 0, sizeof(mcon->remote_hp)); - memset(&mcon->local_hp, 0, sizeof(mcon->local_hp)); -#ifdef HAVE_NETINET_SCTP_H - ftdm_log(FTDM_LOG_DEBUG, "Creating SCTP socket L=%s:%d R=%s:%d\n", - local_ip, local_port, ip, port); - mcon->socket = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); -#else - ftdm_log(FTDM_LOG_DEBUG, "Creating UDP socket L=%s:%d R=%s:%d\n", - local_ip, local_port, ip, port); - mcon->socket = socket(AF_INET, SOCK_DGRAM, 0); -#endif - - if (mcon->socket >= 0) { - int flag; - - flag = 1; -#ifdef HAVE_GETHOSTBYNAME_R_FIVE - gethostbyname_r(ip, &mcon->remote_hp, buf, sizeof(buf), &err); - gethostbyname_r(local_ip, &mcon->local_hp, local_buf, sizeof(local_buf), &local_err); - if (!err && !local_err) { -#else - gethostbyname_r(ip, &mcon->remote_hp, buf, sizeof(buf), &result, &err); - gethostbyname_r(local_ip, &mcon->local_hp, local_buf, sizeof(local_buf), &local_result, &local_err); - if (result && local_result) { -#endif - mcon->remote_addr.sin_family = mcon->remote_hp.h_addrtype; - memcpy((char *) &mcon->remote_addr.sin_addr.s_addr, mcon->remote_hp.h_addr_list[0], mcon->remote_hp.h_length); - mcon->remote_addr.sin_port = htons(port); - - mcon->local_addr.sin_family = mcon->local_hp.h_addrtype; - memcpy((char *) &mcon->local_addr.sin_addr.s_addr, mcon->local_hp.h_addr_list[0], mcon->local_hp.h_length); - mcon->local_addr.sin_port = htons(local_port); - -#ifdef HAVE_NETINET_SCTP_H - setsockopt(mcon->socket, IPPROTO_SCTP, SCTP_NODELAY, - (char *)&flag, sizeof(int)); -#endif - - if ((rc = bind(mcon->socket, - (struct sockaddr *) &mcon->local_addr, - sizeof(mcon->local_addr))) < 0) { - close(mcon->socket); - mcon->socket = -1; - } else { -#ifdef HAVE_NETINET_SCTP_H - rc=listen(mcon->socket, 100); - if (rc) { - close(mcon->socket); - mcon->socket = -1; - } -#endif - } - } - } - - return mcon->socket; -#else - return 0; -#endif // ifndef WIN32 -} - -int sangomabc_connection_close(sangomabc_connection_t *mcon) -{ -#ifndef WIN32 - if (mcon->sigmod) { - ftdm_log(FTDM_LOG_WARNING, "I should not be called on a sigmod-managed connection!\n"); - return 0; - } - if (mcon->socket > -1) { - close(mcon->socket); - } - - if (mcon->mutex) { - ftdm_mutex_lock(mcon->mutex); - ftdm_mutex_unlock(mcon->mutex); - ftdm_mutex_destroy(&mcon->mutex); - } - memset(mcon, 0, sizeof(*mcon)); - mcon->socket = -1; -#endif - return 0; -} - -int sangomabc_connection_open(sangomabc_connection_t *mcon, char *local_ip, int local_port, char *ip, int port) -{ - ftdm_mutex_create(&mcon->mutex); - if (mcon->sigmod) { - /*value of mcon->socket will be ignored in sigmod mode */ - return 0; - } -#ifndef WIN32 - create_conn_socket(mcon, local_ip, local_port, ip, port); - return mcon->socket; -#else - return 0; -#endif -} - - -int sangomabc_exec_command(sangomabc_connection_t *mcon, int span, int chan, int id, int cmd, int cause, int flags) -{ - sangomabc_event_t *oevent; - sangomabc_short_event_t sevent; - sangomabc_event_t fevent; - int retry = 5; - - if (boost_full_event(cmd)) { - sangomabc_event_init((void *)&fevent, cmd, chan, span); - oevent = &fevent; - } else { - sangomabc_event_init(&sevent, cmd, chan, span); - sevent.release_cause = (uint8_t)cause; - oevent = (sangomabc_event_t *)&sevent; - } - oevent->flags = flags; - - if (cmd == SIGBOOST_EVENT_SYSTEM_RESTART || cmd == SIGBOOST_EVENT_SYSTEM_RESTART_ACK) { - mcon->rxseq_reset = 1; - mcon->txseq = 0; - mcon->rxseq = 0; - mcon->txwindow = 0; - } - - if (id >= 0) { - oevent->call_setup_id = (uint16_t)id; - } - - while (sangomabc_connection_write(mcon, (sangomabc_event_t*)oevent) <= 0) { - if (--retry <= 0) { - ftdm_log(FTDM_LOG_CRIT, "Failed to tx on boost socket: %s\n", strerror(errno)); - return -1; - } else { - ftdm_log(FTDM_LOG_WARNING, "Failed to tx on boost socket: %s :retry %i\n", strerror(errno), retry); - ftdm_sleep(1); - } - } - - return 0; -} - - -int sangomabc_exec_commandp(sangomabc_connection_t *pcon, int span, int chan, int id, int cmd, int cause) -{ - sangomabc_short_event_t oevent; - int retry = 5; - - sangomabc_event_init(&oevent, cmd, chan, span); - oevent.release_cause = (uint8_t)cause; - - if (id >= 0) { - oevent.call_setup_id = (uint16_t)id; - } - - while (sangomabc_connection_writep(pcon, (sangomabc_event_t*)&oevent) <= 0) { - if (--retry <= 0) { - ftdm_log(FTDM_LOG_CRIT, "Failed to tx on boost socket: %s\n", strerror(errno)); - return -1; - } else { - ftdm_log(FTDM_LOG_WARNING, "Failed to tx on boost socket: %s :retry %i\n", strerror(errno), retry); - ftdm_sleep(1); - } - } - - return 0; -} - -sangomabc_event_t *__sangomabc_connection_read(sangomabc_connection_t *mcon, int iteration, const char *file, const char *func, int line) -{ -#ifndef WIN32 - unsigned int fromlen = sizeof(struct sockaddr_in); -#endif - int bytes = 0; - int msg_ok = 0; - sangomabc_queue_element_t *e = NULL; - - if (mcon->sigmod) { - e = ftdm_queue_dequeue(mcon->boost_queue); - if (e) { - bytes = (int)e->size; - memcpy(&mcon->event, e->boostmsg, bytes); - ftdm_safe_free(e); - } - } -#ifndef WIN32 - else { - bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, - (struct sockaddr *) &mcon->local_addr, &fromlen); - } -#endif - if (bytes <= 0) { - return NULL; - } - - if (mcon->event.version != SIGBOOST_VERSION) { - ftdm_log(FTDM_LOG_CRIT, "Invalid Boost Version %i Expecting %i\n",mcon->event.version, SIGBOOST_VERSION); - } - - if ((bytes >= MIN_SIZE_CALLSTART_MSG) && boost_full_event(mcon->event.event_id)) { - msg_ok=1; - - } else if (bytes == sizeof(sangomabc_short_event_t)) { - msg_ok=1; - - } else { - msg_ok=0; - } - - if (msg_ok) { - if (sangomabc_test_flag(mcon, MSU_FLAG_DOWN)) { - if (mcon->event.event_id != SIGBOOST_EVENT_SYSTEM_RESTART && - mcon->event.event_id != SIGBOOST_EVENT_SYSTEM_RESTART_ACK && - mcon->event.event_id != SIGBOOST_EVENT_HEARTBEAT) { - ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "Not reading packets when connection is down. [%s]\n", - sangomabc_event_id_name(mcon->event.event_id)); - return NULL; - } - } - - if (boost_full_event(mcon->event.event_id)) { - sangomabc_print_event_call(mcon, &mcon->event, 0, 0, file, func, line); - } else { - sangomabc_print_event_short(mcon, (sangomabc_short_event_t*)&mcon->event, 0, 0, file, func, line); - } - -#if 0 -/* NC: NOT USED ANY MORE */ - if (mcon->rxseq_reset) { - //if (mcon->event.event_id == SIGBOOST_EVENT_SYSTEM_RESTART_ACK) { - ftdm_log(FTDM_LOG_DEBUG, "Rx sync ok\n"); - mcon->rxseq = mcon->event.fseqno; - return &mcon->event; - //} - errno=EAGAIN; - ftdm_log(FTDM_LOG_DEBUG, "Waiting for rx sync...\n"); - return NULL; - } -#endif - - mcon->txwindow = mcon->txseq - mcon->event.bseqno; - mcon->rxseq++; - -#if 0 - if (mcon->rxseq != mcon->event.fseqno) { - ftdm_log(FTDM_LOG_CRIT, "Invalid Sequence Number Expect=%i Rx=%i\n", mcon->rxseq, mcon->event.fseqno); - return NULL; - } -#endif - - return &mcon->event; - } else { - if (iteration == 0) { - ftdm_log(FTDM_LOG_CRIT, "NC - Invalid Event length from boost rxlen=%i evsz=%i\n", bytes, sizeof(mcon->event)); - return NULL; - } - } - - return NULL; -} - -sangomabc_event_t *__sangomabc_connection_readp(sangomabc_connection_t *mcon, int iteration, const char *file, const char *func, int line) -{ -#ifndef WIN32 - unsigned int fromlen = sizeof(struct sockaddr_in); -#endif - int bytes = 0; - - if (mcon->sigmod) { - /* priority stuff is handled just the same when there is a sigmod */ - return sangomabc_connection_read(mcon, iteration); - } -#ifndef WIN32 - else { - bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, (struct sockaddr *) &mcon->local_addr, &fromlen); - } -#endif - if (bytes <= 0) { - return NULL; - } - - if (mcon->event.version != SIGBOOST_VERSION) { - ftdm_log(FTDM_LOG_CRIT, "Invalid Boost Version %i Expecting %i\n",mcon->event.version, SIGBOOST_VERSION); - } - - if (bytes == sizeof(sangomabc_short_event_t)) { - - if (boost_full_event(mcon->event.event_id)) { - sangomabc_print_event_call(mcon, &mcon->event, 1, 0, file, func, line); - } else { - sangomabc_print_event_short(mcon, (sangomabc_short_event_t*)&mcon->event, 1, 0, file, func, line); - } - - return &mcon->event; - } else { - if (iteration == 0) { - ftdm_log(FTDM_LOG_CRIT, "Critical Error: PQ Invalid Event lenght from boost rxlen=%i evsz=%i\n", bytes, sizeof(mcon->event)); - return NULL; - } - } - - return NULL; -} - - -int __sangomabc_connection_write(sangomabc_connection_t *mcon, sangomabc_event_t *event, const char *file, const char *func, int line) -{ - int err = 0; - int event_size=MIN_SIZE_CALLSTART_MSG+event->isup_in_rdnis_size; - - ftdm_assert_return(event != NULL, -1, "No event!"); - ftdm_assert_return(mcon->socket >= 0, -1, "No mcon->socket!"); - ftdm_assert_return(mcon->mutex != NULL, -1, "No mcon->mutex!"); - - ftdm_assert_return(event->span <= FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN, -1, "Invalid span when writing boost event\n"); - ftdm_assert_return(event->chan <= FTDM_MAX_CHANNELS_PHYSICAL_SPAN, -1, "Invalid chan when writing boost event\n"); - - if (!boost_full_event(event->event_id)) { - event_size=sizeof(sangomabc_short_event_t); - } - - if (sangomabc_test_flag(mcon, MSU_FLAG_DOWN)) { - if (event->event_id != SIGBOOST_EVENT_SYSTEM_RESTART && - event->event_id != SIGBOOST_EVENT_SYSTEM_RESTART_ACK && - event->event_id != SIGBOOST_EVENT_HEARTBEAT) { - ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "Not writing packets when connection is down. [%s]\n", - sangomabc_event_id_name(event->event_id)); - return 0; - } - } - - ftdm_mutex_lock(mcon->mutex); - if (event->event_id == SIGBOOST_EVENT_SYSTEM_RESTART_ACK) { - mcon->txseq=0; - mcon->rxseq=0; - event->fseqno=0; - } else { - event->fseqno = mcon->txseq++; - } - event->bseqno = mcon->rxseq; - event->version = SIGBOOST_VERSION; - - if (boost_full_event(event->event_id)) { - sangomabc_print_event_call(mcon, event, 0, 1, file, func, line); - } else { - sangomabc_print_event_short(mcon, (sangomabc_short_event_t*)event, 0, 1, file, func, line); - } - - if (mcon->sigmod) { - mcon->sigmod->write_msg(mcon->span, event, event_size); - err = event_size; - } -#ifndef WIN32 - else { - err = sendto(mcon->socket, event, event_size, 0, (struct sockaddr *) &mcon->remote_addr, sizeof(mcon->remote_addr)); - } -#endif - - ftdm_mutex_unlock(mcon->mutex); - - ftdm_assert_return(err == event_size, -1, "Failed to send the boost message completely!"); - - return err; -} - - -int __sangomabc_connection_writep(sangomabc_connection_t *mcon, sangomabc_event_t *event, const char *file, const char *func, int line) -{ - int err = 0; - int event_size=sizeof(sangomabc_event_t); - - if (!mcon->sigmod) { - ftdm_assert_return(event != NULL, -1, "No event!"); - ftdm_assert_return(mcon->socket >= 0, -1, "No mcon->socket!"); - ftdm_assert_return(mcon->mutex != NULL, -1, "No mcon->mutex!"); - } - - if (!boost_full_event(event->event_id)) { - event_size=sizeof(sangomabc_short_event_t); - } - - ftdm_mutex_lock(mcon->mutex); - event->version = SIGBOOST_VERSION; - if (mcon->sigmod) { - mcon->sigmod->write_msg(mcon->span, event, event_size); - err = event_size; - - } -#ifndef WIN32 - else { - err = sendto(mcon->socket, event, event_size, 0, (struct sockaddr *) &mcon->remote_addr, sizeof(mcon->remote_addr)); - } -#endif - ftdm_mutex_unlock(mcon->mutex); - - ftdm_assert_return(err == event_size, -1, "Failed to send boost message completely!"); - - if (boost_full_event(event->event_id)) { - sangomabc_print_event_call(mcon, event, 1, 1, file, func, line); - } else { - sangomabc_print_event_short(mcon, (sangomabc_short_event_t*)event, 1, 1, file, func, line); - } - - return err; -} - - -void sangomabc_call_init(sangomabc_event_t *event, const char *calling, const char *called, int setup_id) -{ - memset(event, 0, sizeof(sangomabc_event_t)); - event->event_id = SIGBOOST_EVENT_CALL_START; - - if (calling) { - strncpy((char*)event->calling_number_digits, calling, sizeof(event->calling_number_digits)-1); - event->calling_number_digits_count = (uint8_t)strlen(calling); - } - - if (called) { - strncpy((char*)event->called_number_digits, called, sizeof(event->called_number_digits)-1); - event->called_number_digits_count = (uint8_t)strlen(called); - } - - event->call_setup_id = (uint16_t)setup_id; - -} - -void sangomabc_event_init(sangomabc_short_event_t *event, sangomabc_event_id_t event_id, int chan, int span) -{ - if (boost_full_event(event_id)) { - memset(event, 0, sizeof(sangomabc_event_t)); - } else { - memset(event, 0, sizeof(sangomabc_short_event_t)); - } - event->event_id = event_id; - event->chan = (uint8_t)chan; - event->span = (uint8_t)span; -} - -const char *sangomabc_event_id_name(uint32_t event_id) -{ - unsigned int x; - const char *ret = NULL; - - for (x = 0 ; x < sizeof(sangomabc_table)/sizeof(struct sangomabc_map); x++) { - if (sangomabc_table[x].event_id == event_id) { - ret = sangomabc_table[x].name; - break; - } - } - - return ret; -} - - -/* 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/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.h b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.h deleted file mode 100644 index e333c4aba3..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2007, Anthony Minessale II, Nenad Corbic - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _SANGOMABC_H -#define _SANGOMABC_H - -#include "sangoma_boost_interface.h" - -#include -#include -#ifndef WIN32 -#include -#include -#include -#ifdef HAVE_NETINET_SCTP_H -#include -#endif -#include -#include -#include -#endif -#include -#include -#include -#include -#include -#include -#include "sigboost.h" - -#define sangomabc_test_flag(p,flag) ((p)->flags & (flag)) - -#define sangomabc_set_flag(p,flag) do { \ - ((p)->flags |= (flag)); \ - } while (0) - -#define sangomabc_clear_flag(p,flag) do { \ - ((p)->flags &= ~(flag)); \ - } while (0) - -#define sangomabc_copy_flags(dest,src,flagz) do { \ - (dest)->flags &= ~(flagz); \ - (dest)->flags |= ((src)->flags & (flagz)); \ - } while (0) - -typedef t_sigboost_callstart sangomabc_event_t; -typedef t_sigboost_short sangomabc_short_event_t; -typedef uint32_t sangomabc_event_id_t; - -typedef struct sangomabc_ip_cfg -{ - char local_ip[25]; - int local_port; - char remote_ip[25]; - int remote_port; -}sangomabc_ip_cfg_t; - -typedef enum { - MSU_FLAG_EVENT = (1 << 0), - MSU_FLAG_DOWN = (1 << 1) -} sangomabc_flag_t; - - -struct sangomabc_connection { - ftdm_socket_t socket; - struct sockaddr_in local_addr; - struct sockaddr_in remote_addr; - sangomabc_event_t event; - struct hostent remote_hp; - struct hostent local_hp; - unsigned int flags; - ftdm_mutex_t *mutex; - FILE *log; - unsigned int txseq; - unsigned int rxseq; - unsigned int txwindow; - unsigned int rxseq_reset; - sangomabc_ip_cfg_t cfg; - /* boost signaling mod interface pointer (if not working in TCP mode) */ - boost_sigmod_interface_t *sigmod; - ftdm_queue_t *boost_queue; - ftdm_interrupt_t *sock_interrupt; - ftdm_span_t *span; - int debuglevel; -}; - -typedef struct sangomabc_connection sangomabc_connection_t; - -typedef struct sangomabc_queue_element { - unsigned char boostmsg[sizeof(sangomabc_event_t)]; - ftdm_size_t size; -} sangomabc_queue_element_t; - -/* disable nagle's algorythm */ -static __inline__ void sctp_no_nagle(int socket) -{ -#ifdef HAVE_NETINET_SCTP_H - int flag = 1; - setsockopt(socket, IPPROTO_SCTP, SCTP_NODELAY, (char *) &flag, sizeof(int)); -#endif -} - -int sangomabc_connection_close(sangomabc_connection_t *mcon); -int sangomabc_connection_open(sangomabc_connection_t *mcon, char *local_ip, int local_port, char *ip, int port); -sangomabc_event_t *__sangomabc_connection_read(sangomabc_connection_t *mcon, int iteration, const char *file, const char *func, int line); -sangomabc_event_t *__sangomabc_connection_readp(sangomabc_connection_t *mcon, int iteration, const char *file, const char *func, int line); -int __sangomabc_connection_write(sangomabc_connection_t *mcon, sangomabc_event_t *event, const char *file, const char *func, int line); -int __sangomabc_connection_writep(sangomabc_connection_t *mcon, sangomabc_event_t *event, const char *file, const char *func, int line); -#define sangomabc_connection_write(_m,_e) __sangomabc_connection_write(_m, _e, __FILE__, __FUNCTION__, __LINE__) -#define sangomabc_connection_writep(_m,_e) __sangomabc_connection_writep(_m, _e, __FILE__, __FUNCTION__, __LINE__) -#define sangomabc_connection_read(_m,_e) __sangomabc_connection_read(_m, _e, __FILE__, __FUNCTION__, __LINE__) -#define sangomabc_connection_readp(_m,_e) __sangomabc_connection_readp(_m, _e, __FILE__, __FUNCTION__, __LINE__) -void sangomabc_event_init(sangomabc_short_event_t *event, sangomabc_event_id_t event_id, int chan, int span); -void sangomabc_call_init(sangomabc_event_t *event, const char *calling, const char *called, int setup_id); -const char *sangomabc_event_id_name(uint32_t event_id); -int sangomabc_exec_command(sangomabc_connection_t *mcon, int span, int chan, int id, int cmd, int cause, int flags); -int sangomabc_exec_commandp(sangomabc_connection_t *pcon, int span, int chan, int id, int cmd, int cause); - -#define BOOST_EVENT_SPAN(sigmod, event) ((sigmod) ? event->span : event->span + 1) -#define BOOST_EVENT_CHAN(sigmod, event) ((sigmod) ? event->chan : event->chan + 1) - - -#endif - - -/* 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/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_interface.h b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_interface.h deleted file mode 100644 index f6130db444..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_interface.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2009, Sangoma Technologies - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SANGOMA_BOOST_INTERFACE_H -#define SANGOMA_BOOST_INTERFACE_H - -#include "private/ftdm_core.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - \brief Callback used to notify signaling status changes on a channel - \param ftdmchan The freetdm channel where the signaling status just changed - \param status The new signaling status - */ -#define BOOST_SIG_STATUS_CB_ARGS (ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status) -typedef void (*boost_sig_status_cb_func_t) BOOST_SIG_STATUS_CB_ARGS; -#define BOOST_SIG_STATUS_CB_FUNCTION(name) void name BOOST_SIG_STATUS_CB_ARGS - -/*! - \brief Write a boost msg to a boost endpoint - \param span The freetdm span where this msg was generated - \param msg The generic message pointer, owned by the caller - \param msglen The length of the provided structure pointed by msg - \return FTDM_SUCCESS or FTDM_FAIL - - The msg buffer is owned by the caller and it should - be either t_sigboost_callstart or t_sigboost_short - the endpoint receiving the msg will first cast to - t_sigboost_short, check the event type, and if needed. - */ -#define BOOST_WRITE_MSG_ARGS (ftdm_span_t *span, void *msg, ftdm_size_t msglen) -typedef ftdm_status_t (*boost_write_msg_func_t) BOOST_WRITE_MSG_ARGS; -#define BOOST_WRITE_MSG_FUNCTION(name) ftdm_status_t name BOOST_WRITE_MSG_ARGS - -/*! - \brief Set the callback to be used by a signaling module to write boost messages - \param callback The callback to be used by the signaling module - - The provided callback will be used for the signaling boost module to notify the - user with boost messages. - */ -#define BOOST_SET_WRITE_MSG_CB_ARGS (boost_write_msg_func_t callback) -typedef void (*boost_set_write_msg_cb_func_t) BOOST_SET_WRITE_MSG_CB_ARGS; -#define BOOST_SET_WRITE_MSG_CB_FUNCTION(name) void name BOOST_SET_WRITE_MSG_CB_ARGS - -/*! - \brief Notify hardware status change - \param ftdmchan The freetdm channel - \param status The hw status - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_ON_HW_LINK_STATUS_CHANGE_ARGS (ftdm_channel_t *ftdmchan, ftdm_channel_hw_link_status_t status) -typedef void (*boost_on_hw_link_status_change_func_t) BOOST_ON_HW_LINK_STATUS_CHANGE_ARGS; -#define BOOST_ON_HW_LINK_STATUS_CHANGE_FUNCTION(name) void name BOOST_ON_HW_LINK_STATUS_CHANGE_ARGS - -/*! - \brief Set signaling status callback used by the signaling module to report signaling status changes - \param callback The callback to be used by the signaling module - - The provided callback will be used for the signaling boost module to notify the - user with signaling link status changes. - */ -#define BOOST_SET_SIG_STATUS_CB_ARGS (boost_sig_status_cb_func_t callback) -typedef void (*boost_set_sig_status_cb_func_t) BOOST_SET_SIG_STATUS_CB_ARGS; -#define BOOST_SET_SIG_STATUS_CB_FUNCTION(name) void name BOOST_SET_SIG_STATUS_CB_ARGS - -/*! - \brief Get the signaling status on the given channel. - \param ftdmchan The freetdm channel - \param status The status pointer where the current signaling status will be set - */ -#define BOOST_GET_CHANNEL_SIG_STATUS_ARGS (ftdm_channel_t *ftdmchan, ftdm_signaling_status_t *status) -typedef ftdm_status_t (*boost_get_channel_sig_status_func_t) BOOST_GET_CHANNEL_SIG_STATUS_ARGS; -#define BOOST_GET_CHANNEL_SIG_STATUS_FUNCTION(name) ftdm_status_t name BOOST_GET_CHANNEL_SIG_STATUS_ARGS - -/*! - \brief Set the signaling status on the given channel. - \param ftdmchan The freetdm channel - \param status The new status for the channel - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_SET_CHANNEL_SIG_STATUS_ARGS (ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status) -typedef ftdm_status_t (*boost_set_channel_sig_status_func_t) BOOST_SET_CHANNEL_SIG_STATUS_ARGS; -#define BOOST_SET_CHANNEL_SIG_STATUS_FUNCTION(name) ftdm_status_t name BOOST_SET_CHANNEL_SIG_STATUS_ARGS - -/*! - \brief Get the signaling status on the given span. - \param span The freetdm span - \param status The status pointer where the current signaling status will be set - */ -#define BOOST_GET_SPAN_SIG_STATUS_ARGS (ftdm_span_t *span, ftdm_signaling_status_t *status) -typedef ftdm_status_t (*boost_get_span_sig_status_func_t) BOOST_GET_SPAN_SIG_STATUS_ARGS; -#define BOOST_GET_SPAN_SIG_STATUS_FUNCTION(name) ftdm_status_t name BOOST_GET_SPAN_SIG_STATUS_ARGS - -/*! - \brief Set the signaling status on the given span. - \param ftdmchan The freetdm span - \param status The new status for the span - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_SET_SPAN_SIG_STATUS_ARGS (ftdm_span_t *span, ftdm_signaling_status_t status) -typedef ftdm_status_t (*boost_set_span_sig_status_func_t) BOOST_SET_SPAN_SIG_STATUS_ARGS; -#define BOOST_SET_SPAN_SIG_STATUS_FUNCTION(name) ftdm_status_t name BOOST_SET_SPAN_SIG_STATUS_ARGS - -/*! - \brief Configure the given span signaling - \param span The freetdm span - \param parameters The array of configuration key,value pairs (must be null terminated) - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_CONFIGURE_SPAN_ARGS (ftdm_span_t *span, ftdm_conf_parameter_t *parameters) -typedef ftdm_status_t (*boost_configure_span_func_t) BOOST_CONFIGURE_SPAN_ARGS; -#define BOOST_CONFIGURE_SPAN_FUNCTION(name) ftdm_status_t name BOOST_CONFIGURE_SPAN_ARGS - -/*! - \brief Start the given span - \param span The freetdm span - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_START_SPAN_ARGS (ftdm_span_t *span) -typedef ftdm_status_t (*boost_start_span_func_t) BOOST_START_SPAN_ARGS; -#define BOOST_START_SPAN_FUNCTION(name) ftdm_status_t name BOOST_START_SPAN_ARGS - -/*! - \brief Stop the given span - \param span The freetdm span - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_STOP_SPAN_ARGS (ftdm_span_t *span) -typedef ftdm_status_t (*boost_stop_span_func_t) BOOST_START_SPAN_ARGS; -#define BOOST_STOP_SPAN_FUNCTION(name) ftdm_status_t name BOOST_STOP_SPAN_ARGS - -/*! - \brief Called when the module is being loaded BEFORE calling anything else - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_ON_LOAD_ARGS (void) -typedef ftdm_status_t (*boost_on_load_func_t) BOOST_ON_LOAD_ARGS; -#define BOOST_ON_LOAD_FUNCTION(name) ftdm_status_t name BOOST_ON_LOAD_ARGS - -/*! - \brief Called when the module is being unloaded, last chance to stop everything! - */ -#define BOOST_ON_UNLOAD_ARGS (void) -typedef ftdm_status_t (*boost_on_unload_func_t) BOOST_ON_UNLOAD_ARGS; -#define BOOST_ON_UNLOAD_FUNCTION(name) ftdm_status_t name BOOST_ON_UNLOAD_ARGS - -/*! - \brief Called when user wants to execute sigmod api function - \return FTDM_SUCCESS or FTDM_FAIL - */ -#define BOOST_API_ARGS (ftdm_stream_handle_t *stream, char *cmd) -typedef ftdm_status_t (*boost_api_func_t) BOOST_API_ARGS; -#define BOOST_API_FUNCTION(name) ftdm_status_t name BOOST_API_ARGS - - -/*! - \brief The boost signaling module interface - */ -typedef struct boost_sigmod_interface_s { - /*! \brief Module name */ - const char *name; - /*! \brief write boost message function */ - boost_write_msg_func_t write_msg; - /*! \brief set the user write boost message function */ - boost_set_write_msg_cb_func_t set_write_msg_cb; - /*! \brief set the user signaling status function */ - boost_set_sig_status_cb_func_t set_sig_status_cb; - /*! \brief get channel signaling status */ - boost_get_channel_sig_status_func_t get_channel_sig_status; - /*! \brief set channel signaling status */ - boost_set_channel_sig_status_func_t set_channel_sig_status; - /*! \brief get span signaling status */ - boost_get_span_sig_status_func_t get_span_sig_status; - /*! \brief set span signaling status */ - boost_set_span_sig_status_func_t set_span_sig_status; - /*! \brief set notify hardware link status change */ - boost_on_hw_link_status_change_func_t on_hw_link_status_change; - /*! \brief configure span signaling */ - boost_configure_span_func_t configure_span; - /*! \brief start freetdm span */ - boost_start_span_func_t start_span; - /*! \brief stop freetdm span */ - boost_stop_span_func_t stop_span; - /*! \brief the module was just loaded */ - boost_on_load_func_t on_load; - /*! \brief the module is about to be unloaded */ - boost_on_unload_func_t on_unload; - /*! \brief module api function */ - boost_api_func_t exec_api; - /*! \brief private pointer for the interface user */ - void *pvt; -} boost_sigmod_interface_t; - -#ifdef __cplusplus -} // extern C -#endif - -#define BOOST_INTERFACE_NAME boost_sigmod_interface -#define BOOST_INTERFACE_NAME_STR "boost_sigmod_interface" -/* use this in your sig boost module to declare your interface */ -#ifndef WIN32 -#define BOOST_INTERFACE boost_sigmod_interface_t BOOST_INTERFACE_NAME -#else -#define BOOST_INTERFACE __declspec(dllexport) boost_sigmod_interface_t BOOST_INTERFACE_NAME -#endif -#endif - - -/* 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/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sigboost.h b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sigboost.h deleted file mode 100644 index 7975dc5b93..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sigboost.h +++ /dev/null @@ -1,221 +0,0 @@ -/**************************************************************************** - * sigboost.h $Revision: 1.13 $ - * - * Definitions for the sigboost interface. - * - * WARNING WARNING WARNING - * - * This file is used by sangoma_mgd and perhaps other programs. Any changes - * to this file must be coordinated with other user programs, - * - * Copyright (C) 2005 Xygnada Technology, Inc. - * -****************************************************************************/ -#ifndef _SIGBOOST_H_ -#define _SIGBOOST_H_ - -#define SIGBOOST_VERSION 103 - -// handy to define integer types that actually work on both Lin and Win -#include - -enum e_sigboost_event_id_values -{ - SIGBOOST_EVENT_CALL_START = 0x80, /*128*/ - SIGBOOST_EVENT_CALL_START_ACK = 0x81, /*129*/ - SIGBOOST_EVENT_CALL_START_NACK = 0x82, /*130*/ - SIGBOOST_EVENT_CALL_START_NACK_ACK = 0x83, /*131*/ - SIGBOOST_EVENT_CALL_ANSWERED = 0x84, /*132*/ - SIGBOOST_EVENT_CALL_STOPPED = 0x85, /*133*/ - SIGBOOST_EVENT_CALL_STOPPED_ACK = 0x86, /*134*/ - SIGBOOST_EVENT_SYSTEM_RESTART = 0x87, /*135*/ - SIGBOOST_EVENT_SYSTEM_RESTART_ACK = 0x88, /*136*/ - /* CALL_RELEASED is aimed to fix a race condition that became obvious - * when the boost socket was replaced by direct function calls - * and the channel hunting was moved to freetdm, the problem is - * we can get CALL_STOPPED msg and reply with CALL_STOPPED_ACK - * but the signaling module will still (in PRI) send RELEASE and - * wait for RELEASE_COMPLETE from the isdn network before - * marking the channel as available, therefore freetdm should - * also not mark the channel as available until CALL_RELEASED - * is received, for socket mode we can continue working as usual - * with CALL_STOPPED being the last step because the hunting is - * done in the signaling module. - * */ - SIGBOOST_EVENT_CALL_RELEASED = 0x51, /* 81 */ - SIGBOOST_EVENT_CALL_PROGRESS = 0x50, /*decimal 80*/ - /* Following IDs are ss7boost to sangoma_mgd only. */ - SIGBOOST_EVENT_HEARTBEAT = 0x89, /*137*/ - SIGBOOST_EVENT_INSERT_CHECK_LOOP = 0x8a, /*138*/ - SIGBOOST_EVENT_REMOVE_CHECK_LOOP = 0x8b, /*139*/ - SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE = 0x8c, /*140*/ - SIGBOOST_EVENT_DIGIT_IN = 0x8d, /*141*/ -}; - -#define BOOST_DECODE_EVENT_ID(id) \ - (id==SIGBOOST_EVENT_CALL_START)?"SIGBOOST_EVENT_CALL_START": \ - (id==SIGBOOST_EVENT_CALL_START_ACK)?"SIGBOOST_EVENT_CALL_START_ACK": \ - (id==SIGBOOST_EVENT_CALL_START_NACK)?"SIGBOOST_EVENT_CALL_START_NACK": \ - (id==SIGBOOST_EVENT_CALL_ANSWERED)?"SIGBOOST_EVENT_CALL_ANSWERED": \ - (id==SIGBOOST_EVENT_CALL_STOPPED)?"SIGBOOST_EVENT_CALL_STOPPED": \ - (id==SIGBOOST_EVENT_CALL_STOPPED_ACK)?"SIGBOOST_EVENT_CALL_STOPPED_ACK": \ - (id==SIGBOOST_EVENT_SYSTEM_RESTART)?"SIGBOOST_EVENT_SYSTEM_RESTART": \ - (id==SIGBOOST_EVENT_SYSTEM_RESTART_ACK)?"SIGBOOST_EVENT_SYSTEM_RESTART_ACK": \ - (id==SIGBOOST_EVENT_CALL_RELEASED)?"SIGBOOST_EVENT_CALL_RELEASED": \ - (id==SIGBOOST_EVENT_CALL_PROGRESS)?"SIGBOOST_EVENT_CALL_PROGRESS": \ - (id==SIGBOOST_EVENT_HEARTBEAT)?"SIGBOOST_EVENT_HEARTBEAT": \ - (id==SIGBOOST_EVENT_INSERT_CHECK_LOOP)?"SIGBOOST_EVENT_INSERT_CHECK_LOOP": \ - (id==SIGBOOST_EVENT_REMOVE_CHECK_LOOP)?"SIGBOOST_EVENT_REMOVE_CHECK_LOOP": \ - (id==SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE)?"SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE": \ - (id==SIGBOOST_EVENT_DIGIT_IN)?"SIGBOOST_EVENT_DIGIT_IN": "Unknown" - -enum e_sigboost_release_cause_values -{ - SIGBOOST_RELEASE_CAUSE_UNDEFINED = 0, - SIGBOOST_RELEASE_CAUSE_NORMAL = 16, - /* probable elimination */ - //SIGBOOST_RELEASE_CAUSE_BUSY = 0x91, /* 145 */ - //SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST = 0x92, /* 146 */ - //SIGBOOST_RELEASE_CAUSE_CIRCUIT_RESET = 0x93, /* 147 */ - //SIGBOOST_RELEASE_CAUSE_NOANSWER = 0x94, /* 148 */ -}; - -enum e_sigboost_call_setup_ack_nack_cause_values -{ - //SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY = 34, /* Q.850 value - don't use */ - SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY = 117, /* non Q.850 value indicates local all ckt busy - causing sangoma_mgd to perform automatic call - gapping*/ - SIGBOOST_CALL_SETUP_NACK_TEST_CKT_BUSY = 17, /* Q.850 value */ - SIGBOOST_CALL_SETUP_NACK_INVALID_NUMBER = 28, /* Q.850 value */ - SIGBOOST_CALL_SETUP_CSUPID_DBL_USE = 200, /* unused Q.850 value */ -}; - - -enum e_sigboost_huntgroup_values -{ - SIGBOOST_HUNTGRP_SEQ_ASC = 0x00, /* sequential with lowest available first */ - SIGBOOST_HUNTGRP_SEQ_DESC = 0x01, /* sequential with highest available first */ - SIGBOOST_HUNTGRP_RR_ASC = 0x02, /* round-robin with lowest available first */ - SIGBOOST_HUNTGRP_RR_DESC = 0x03, /* round-robin with highest available first */ -}; - -enum e_sigboost_event_info_par_values -{ - SIGBOOST_EVI_SPARE = 0x00, - SIGBOOST_EVI_ALERTING = 0x01, - SIGBOOST_EVI_PROGRESS = 0x02, -}; - -enum e_sigboost_progress_flags -{ - SIGBOOST_PROGRESS_RING = (1 << 0), - SIGBOOST_PROGRESS_MEDIA = (1 << 1) -}; - -#define MAX_DIALED_DIGITS 31 - -/* Next two defines are used to create the range of values for call_setup_id - * in the t_sigboost structure. - * 0..((CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN) - 1) */ -#define CORE_MAX_SPANS 200 -#define CORE_MAX_CHAN_PER_SPAN 32 -#define MAX_PENDING_CALLS CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN -/* 0..(MAX_PENDING_CALLS-1) is range of call_setup_id below */ - -/* Should only be used by server */ -#define MAX_CALL_SETUP_ID 0xFFFF - -#define SIZE_CUSTOM 900 -#define SIZE_RDNIS SIZE_CUSTOM - - -#pragma pack(1) - -typedef struct -{ - uint8_t capability; - uint8_t uil1p; -} t_sigboost_bearer; - -typedef struct -{ - uint8_t digits_count; - char digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */ - uint8_t npi; - uint8_t ton; - uint8_t screening_ind; - uint8_t presentation_ind; -}t_sigboost_digits; - -typedef struct -{ - uint16_t version; - uint32_t event_id; - /* delete sequence numbers - SCTP does not need them */ - uint32_t fseqno; - uint32_t bseqno; - uint16_t call_setup_id; - uint32_t trunk_group; - uint8_t span; - uint8_t chan; - uint32_t flags; - /* struct timeval tv; */ - t_sigboost_digits called; - t_sigboost_digits calling; - t_sigboost_digits rdnis; - /* ref. Q.931 Table 4-11 and Q.951 Section 3 */ - char calling_name[MAX_DIALED_DIGITS + 1]; - t_sigboost_bearer bearer; - uint8_t hunt_group; - uint16_t custom_data_size; - char custom_data[SIZE_CUSTOM]; /* it's a null terminated string */ - -} t_sigboost_callstart; - -#define called_number_digits_count called.digits_count -#define called_number_digits called.digits -#define calling_number_digits_count calling.digits_count -#define calling_number_digits calling.digits -#define calling_number_screening_ind calling.screening_ind -#define calling_number_presentation calling.presentation_ind - -#define isup_in_rdnis_size custom_data_size -#define isup_in_rdnis custom_data - - -#define MIN_SIZE_CALLSTART_MSG sizeof(t_sigboost_callstart) - SIZE_CUSTOM - -typedef struct -{ - uint16_t version; - uint32_t event_id; - /* delete sequence numbers - SCTP does not need them */ - uint32_t fseqno; - uint32_t bseqno; - uint16_t call_setup_id; - uint32_t trunk_group; - uint8_t span; - uint8_t chan; - uint32_t flags; - /* struct timeval tv; */ - uint8_t release_cause; -} t_sigboost_short; -#pragma pack() - - -static __inline__ int boost_full_event(int event_id) -{ - switch (event_id) { - case SIGBOOST_EVENT_CALL_START: - case SIGBOOST_EVENT_DIGIT_IN: - case SIGBOOST_EVENT_CALL_PROGRESS: - return 1; - default: - break; - } - - return 0; -} - -#endif 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 80dc73f0fa..b369deae1f 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 @@ -80,6 +80,8 @@ typedef enum { FLAG_ACTIVATING = (1 << 10), /* Used when we receive an ALERT msg + inband tones ready */ FLAG_MEDIA_READY = (1 << 11), + /* Set when we already sent a Channel ID IE */ + FLAG_SENT_CHAN_ID = (1 << 12), } sngisdn_flag_t; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index 23fe08b983..08e5984a4f 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -821,9 +821,17 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId) { + sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data; if (!ftdmchan) { return FTDM_SUCCESS; } + + if (ftdm_test_flag(sngisdn_info, FLAG_SENT_CHAN_ID)) { + /* Indicate channel ID only in first response */ + return FTDM_SUCCESS; + } + ftdm_set_flag(sngisdn_info, FLAG_SENT_CHAN_ID); + chanId->eh.pres = PRSNT_NODEF; chanId->prefExc.pres = PRSNT_NODEF; chanId->prefExc.val = IN_PE_EXCLSVE; diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c index f77cdd3afa..13454c1a8e 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c +++ b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c @@ -8665,10 +8665,6 @@ void outgoing_destroy(nta_outgoing_t *orq) orq->orq_destroyed = 1; orq->orq_callback = outgoing_default_cb; orq->orq_magic = NULL; - - if (orq->orq_method != sip_method_invite && - orq->orq_method != sip_method_ack) - outgoing_terminate(orq); } /** @internal Outgoing transaction timer routine. 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 f104274ef4..e00d3912d8 100644 --- a/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c +++ b/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c @@ -1036,13 +1036,15 @@ int soa_sdp_mode_set(sdp_session_t const *user, assert(s2u); - for (j = 0, um = user->sdp_media; j != s2u[i]; um = um->m_next, j++) - assert(um); + for (j = 0, um = user->sdp_media; j != s2u[i]; um = um->m_next, j++) { + if (!um) break; + } + if (um == NULL) { if (dryrun) - return 1; + return 1; else - retval = 1; + retval = 1; sm->m_rejected = 1; sm->m_mode = sdp_inactive; sm->m_port = 0; diff --git a/scripts/perl/randomize-passwords.pl b/scripts/perl/randomize-passwords.pl new file mode 100755 index 0000000000..d792f2b293 --- /dev/null +++ b/scripts/perl/randomize-passwords.pl @@ -0,0 +1,179 @@ +#!/usr/bin/perl +# +# randomize-passwords.pl +# +# Randomizes the auth passwords for any file in the file spec given by the user +# Randomizes the vm passwords for the same files +# Creates a backup copy of each file altered; optionally will remove backups +# +# This program uses only pure Perl modules so it should be portable. +# +# Michael S. Collins +# 2009-11-11 +# +# Freely contributed to the FreeSWITCH project for use as the developers and community see fit + +use strict; +use warnings; +use Getopt::Long; +use File::Basename; +use File::Copy; + +$|++; + +## 'CHARACTERS' contains punctuation marks +use constant CHARACTERS => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=+?> 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; +my $numalphas = length(ALPHACHARS); + +my $vmlen = 4; # Length of VM password +my $authlen = 10; # Length of auth password +my $filespec; # File specification +my $delbak; # Flag - delete backups (default = keep backups) +my $nopunct; # Flag - set to true to disable punction marks (i.e. alphanumerics only) in auth passwords + +my $opts_ok = GetOptions ("h" => \&usage, + "help" => \&usage, + "vmlen=i" => \$vmlen, + "authlen=i" => \$authlen, + "files=s" => \$filespec, + "D" => \$delbak, + "nopunct" => \$nopunct, + ); + +## Confirm that a file spec was provided +if ( ! $filespec ) { + warn "\nPlease provide a file specification.\n"; + die "Example: --files=/usr/local/freeswitch/conf/directory/default/1*.xml\n\n"; +} + +## Collect the files +my @FILELIST = glob($filespec); +if ( ! @FILELIST ) { + print "\nNo files found matching this spec:\n$filespec\n"; + exit(0); +} else { + print "\nFound " . @FILELIST . " file(s).\n\n"; +} + +## Iterate through the list, process each file +foreach my $file ( @FILELIST ) { + print "Processing file: $file\n"; + my $bakfile = $file . '.bak'; + + if ( move($file,$bakfile) ) { + print " $file ===> $bakfile\n"; + } else { + print " Unable to backup $file to $bakfile. Skipping...\n"; + next; + } + + ## FILEIN is the backup file, FILEOUT is the updated file + open(FILEIN ,'<',$bakfile) or die "Could not open $bakfile - aborting operation.\n"; + open(FILEOUT,'>',$file ) or die "Could not open $file - aborting operation.\n"; + + ## Retrieve new passwords from random generators + my $newauth = &get_random_chars($authlen); + my $newvm = &get_random_digits($vmlen); + + ## Loop through "bak" file, replace passwords, write out to original file + while() { + ## Check for passwords; if found swap + if ( m/param name="password"/ ) { + # Found auth password, swap it + s/value="(.*?)"/value="$newauth"/; + print " Old/new auth pass: $1 ==> $newauth\n"; + } + + if ( m/param name="vm-password"/ ) { + # Found vm password, swap it + s/value="(.*?)"/value="$newvm"/; + print " Old/new vm pass: $1 ==> $newvm\n"; + } + + print FILEOUT $_; + + } ## while() + + close(FILEIN); + close(FILEOUT); + + ## Clear out the backup file if user asked for it + if ( $delbak ) { + print " Removing $bakfile...\n"; + unlink $bakfile; + } + print " Finished with $file.\n\n"; + +} ## foreach my $file ( @FILELIST ) + +exit(0); + +## Return random chars for auth password +sub get_random_chars () { + my $length = shift; + if ( ! $length ) { $length = $authlen; } + my $chars; + + if ( $nopunct ) { + foreach my $i (1 .. $length) { + my $nextchar = substr( ALPHACHARS,int(rand $numalphas),1 ); + $chars .= $nextchar; + } + + } else { + foreach my $i (1 .. $length) { + my $nextchar = substr( CHARACTERS,int(rand $numchars),1 ); + $chars .= $nextchar; + } + } + return $chars; +} + +## Return only digits for vm password +sub get_random_digits () { + my $length = shift; + if ( ! $length ) { $length = $vmlen; } + my $digits; + foreach my $i (1 .. $length) { + my $nextdigit = int(rand 10); + $digits .= $nextdigit; + } + return $digits; + +} + +sub usage () { +print < [-D] [--vmlen=] [--authlen=] + +Options: + + -h, --help Display this help page + + -D Delete backups (default is to save backups) + + --files Specify files to process. Use typical file globs. On a standard Linux install it would look like: + --files=/usr/local/freeswitch/conf/directory/default/1*.xml + + --vmlen Set length of voice mail password. (Default is 4 digits) + + --authlen Set length of auth password. (Default is 10 characters) + + --nopunct Disable punction marks in auth passwords, i.e. alphanumerics only + +Example: + To randomize all the passwords for a default Linux install, with 6 digit VM passwords, use this command: + + ./randomize-passwords.pl --files=/usr/local/freeswitch/conf/directory/default/1*.xml -D --vmlen=6 + +END_USAGE +; +exit(0); +} diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index f8c6a794b9..ab0777ed3b 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -248,6 +248,7 @@ struct switch_runtime { int max_sql_buffer_len; switch_dbtype_t odbc_dbtype; char hostname[256]; + int multiple_registrations; }; extern struct switch_runtime runtime; diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 27dacc7c18..2870bba3af 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -437,6 +437,8 @@ SWITCH_DECLARE(void) switch_rtp_set_private(switch_rtp_t *rtp_session, void *pri */ SWITCH_DECLARE(void) switch_rtp_set_telephony_event(switch_rtp_t *rtp_session, switch_payload_t te); SWITCH_DECLARE(void) switch_rtp_set_telephony_recv_event(switch_rtp_t *rtp_session, switch_payload_t te); +SWITCH_DECLARE(void) switch_rtp_set_recv_pt(switch_rtp_t *rtp_session, switch_payload_t pt); + /*! \brief Set the payload type for comfort noise \param rtp_session the RTP session to modify diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 6db8c046f6..1c2f009036 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -780,7 +780,7 @@ SWITCH_STANDARD_API(user_data_function) if ((domain = strchr(user, '@'))) { *domain++ = '\0'; } else { - if ((dup_domain = switch_core_get_variable("domain"))) { + if ((dup_domain = switch_core_get_variable_dup("domain"))) { domain = dup_domain; } else { domain = "cluecon.com"; diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 0aee35224c..5eeae5c781 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -266,6 +266,7 @@ typedef struct conference_obj { switch_thread_rwlock_t *rwlock; uint32_t count; int32_t energy_level; + int32_t agc_energy_level; uint8_t min; switch_speech_handle_t lsh; switch_speech_handle_t *sh; @@ -326,6 +327,7 @@ struct conference_member { uint32_t frame_size; uint8_t *mux_frame; uint32_t read; + uint32_t vol_period; int32_t energy_level; int32_t agc_volume_in_level; int32_t volume_in_level; @@ -345,7 +347,7 @@ struct conference_member { uint32_t verbose_events; uint32_t avg_score; uint32_t avg_itt; - uint32_t avg_tally; + uint32_t avg_tally; struct conference_member *next; switch_ivr_dmachine_t *dmachine; }; @@ -1940,6 +1942,17 @@ static void conference_loop_fn_hangup(conference_member_t *member, caller_contro switch_clear_flag_locked(member, MFLAG_RUNNING); } +static void clear_avg(conference_member_t *member) +{ + + member->agc_volume_in_level = 0; + member->avg_score = 0; + member->avg_itt = 0; + member->avg_tally = 0; + member->nt_tally = 0; +} + + /* marshall frames from the call leg to the conference thread for muxing to other call legs */ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *obj) { @@ -1948,7 +1961,7 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v switch_channel_t *channel; switch_status_t status; switch_frame_t *read_frame = NULL; - uint32_t hangover = 40, hangunder = 15, hangover_hits = 0, hangunder_hits = 0, energy_level = 0, diff_level = 400; + uint32_t hangover = 40, hangunder = 5, hangover_hits = 0, hangunder_hits = 0, energy_level = 0, diff_level = 400; switch_codec_implementation_t read_impl = { 0 }; switch_core_session_t *session = member->session; int check_floor_change; @@ -1991,6 +2004,7 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v if (++hangover_hits >= hangover) { hangover_hits = hangunder_hits = 0; switch_clear_flag_locked(member, MFLAG_TALKING); + clear_avg(member); if (test_eflag(member->conference, EFLAG_STOP_TALKING) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { @@ -2006,19 +2020,9 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v /* Check for input volume adjustments */ if (!member->conference->agc_level) { - member->agc_volume_in_level = 0; - member->avg_score = 0; - member->avg_itt = 0; - member->avg_tally = 0; - } - - if (member->conference->agc_level && member->agc_volume_in_level) { - switch_change_sln_volume(read_frame->data, read_frame->datalen / 2, member->agc_volume_in_level); - } else if (member->volume_in_level) { - switch_change_sln_volume(read_frame->data, read_frame->datalen / 2, member->volume_in_level); + clear_avg(member); } - energy_level = member->energy_level; /* if the member can speak, compute the audio energy level and */ @@ -2027,7 +2031,8 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v uint32_t energy = 0, i = 0, samples = 0, j = 0; int16_t *data; int divisor = 0; - int one_sec = (read_impl.actual_samples_per_second / read_impl.samples_per_packet); + int agc_period = (read_impl.actual_samples_per_second / read_impl.samples_per_packet) / 2; + int combined_vol = 0; data = read_frame->data; @@ -2037,77 +2042,62 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v member->score = 0; + combined_vol = member->agc_volume_in_level; + if (member->conference->agc_level) { + combined_vol += member->agc_volume_in_level; + } + + if (combined_vol) { + switch_change_sln_volume(read_frame->data, read_frame->datalen / 2, combined_vol); + } + if ((samples = read_frame->datalen / sizeof(*data))) { for (i = 0; i < samples; i++) { energy += abs(data[j]); j += read_impl.number_of_channels; } member->score = energy / (samples / divisor); - member->avg_tally += member->score; - member->avg_score = member->avg_tally / ++member->avg_itt; - if (!member->avg_itt) member->avg_tally = member->score; } + if (member->vol_period) { + member->vol_period--; + } + if (member->conference->agc_level && member->score && - switch_test_flag(member, MFLAG_TALKING) && switch_test_flag(member, MFLAG_CAN_SPEAK) && - member->score > member->energy_level + member->score > member->conference->agc_energy_level ) { - int diff = member->conference->agc_level - member->score; - if (abs(diff) >= 200) { - member->agc_concur++; - } else { - member->agc_concur = 0; - } - -#if 0 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG8, - "conf %s FOO %d %d %d %d %d\n", - member->conference->name, - member->id, diff, member->conference->agc_level, - member->score, member->agc_volume_in_level); -#endif + member->avg_tally += member->score; + member->avg_itt++; + if (!member->avg_itt) member->avg_itt++; + member->avg_score = member->avg_tally / member->avg_itt; - if (member->agc_concur >= one_sec) { - if (member->score < member->conference->agc_level) { - member->agc_volume_in_level++; - - switch_normalize_volume(member->agc_volume_in_level); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG7, - "conf %s AGC +++ %d %d %d %d %d\n", - member->conference->name, - member->id, diff, member->conference->agc_level, - member->score, member->agc_volume_in_level); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG7, + "conf %s AGC %d %d %d %d %d %d\n", + member->conference->name, + member->id, member->conference->agc_level - member->avg_score, member->conference->agc_level, + member->score, member->avg_score, member->agc_volume_in_level); - } else { - member->agc_volume_in_level--; - - switch_normalize_volume(member->agc_volume_in_level); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG7, - "conf %s AGC --- %d %d %d %d %d\n", - member->conference->name, - member->id, diff, member->conference->agc_level, - member->score, member->agc_volume_in_level); + + if (++member->nt_tally >= agc_period) { + if (!member->vol_period) { + if (member->avg_score < member->conference->agc_level) { + member->agc_volume_in_level++; + switch_normalize_volume(member->agc_volume_in_level); + member->vol_period = (read_impl.actual_samples_per_second / read_impl.samples_per_packet) * 2; + } + + if (member->avg_score > member->conference->agc_level) { + member->agc_volume_in_level--; + switch_normalize_volume(member->agc_volume_in_level); + member->vol_period = (read_impl.actual_samples_per_second / read_impl.samples_per_packet) * 2; + } } - member->agc_concur = 0; - } - member->nt_tally = 0; - } else { - member->nt_tally++; - member->agc_concur = 0; - - if (member->nt_tally > one_sec * 5) { - member->agc_volume_in_level = 0; member->nt_tally = 0; - member->avg_itt = 0; - member->avg_tally = 0; - member->avg_score = member->score; } - - } member->score_iir = (int) (((1.0 - SCORE_DECAY) * (float) member->score) + (SCORE_DECAY * (float) member->score_iir)); @@ -2162,6 +2152,7 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v if (++hangover_hits >= hangover) { hangover_hits = hangunder_hits = 0; switch_clear_flag_locked(member, MFLAG_TALKING); + clear_avg(member); if (test_eflag(member->conference, EFLAG_STOP_TALKING) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { @@ -3421,7 +3412,7 @@ static switch_status_t conf_api_sub_mute(conference_member_t *member, switch_str static switch_status_t conf_api_sub_agc(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) { - int level; + int level, energy_level; int on = 0; if (argc == 2) { @@ -3439,7 +3430,13 @@ static switch_status_t conf_api_sub_agc(conference_obj_t *conference, switch_str if (argc > 3) { level = atoi(argv[3]); } else { - level = 2000; + level = 650; + } + + if (argc > 4) { + energy_level = atoi(argv[4]); + } else { + energy_level = 100; } if (level > conference->energy_level) { @@ -3447,9 +3444,10 @@ static switch_status_t conf_api_sub_agc(conference_obj_t *conference, switch_str conference->avg_itt = 0; conference->avg_tally = 0; conference->agc_level = level; - + conference->agc_energy_level = energy_level; + if (stream) { - stream->write_function(stream, "OK AGC ENABLED %d\n", conference->agc_level); + stream->write_function(stream, "OK AGC ENABLED %d %d\n", conference->agc_level, conference->agc_energy_level); } } else { @@ -3823,7 +3821,7 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer if (conference->agc_level) { char tmp[30] = ""; - switch_snprintf(tmp, sizeof(tmp), "%d", conference->agc_level); + switch_snprintf(tmp, sizeof(tmp), "%d:%d", conference->agc_level, conference->agc_energy_level); switch_xml_set_attr_d_buf(x_conference, "agc", tmp); } @@ -4878,7 +4876,6 @@ static switch_status_t conference_outcall(conference_obj_t *conference, rdlock = 1; peer_channel = switch_core_session_get_channel(peer_session); - switch_channel_set_state(peer_channel, CS_SOFT_EXECUTE); /* make sure the conference still exists */ if (!switch_test_flag(conference, CFLAG_RUNNING)) { @@ -6392,16 +6389,30 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c if (!zstr(auto_gain_level)) { int level = 0; + int energy_level = 100; if (switch_true(auto_gain_level)) { - level = 2000; + level = 650; } else { + char *p; + int tmp = 0; + level = atoi(auto_gain_level); + if ((p = strchr(auto_gain_level, ':'))) { + p++; + if (p) tmp = atoi(p); + if (tmp > 0) { + energy_level = tmp; + } + } } if (level > 0 && level > conference->energy_level) { conference->agc_level = level; } + + conference->agc_energy_level = energy_level; + } if (!zstr(maxmember_sound)) { diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 894e49a511..5515f76b72 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1725,8 +1725,7 @@ static void update_mwi(vm_profile_t *profile, const char *id, const char *domain #define FREE_DOMAIN_ROOT() if (x_user) switch_xml_free(x_user); x_user = NULL - -static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *profile, const char *domain_name, const char *id, int auth) +static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *profile, const char *domain_name, const char *id, int auth, const char *uuid_in) { vm_check_state_t vm_check_state = VM_CHECK_START; switch_channel_t *channel = switch_core_session_get_channel(session); @@ -1900,6 +1899,9 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p cbt.type = play_msg_type; cbt.move = VM_MOVE_NEXT; vm_execute_sql_callback(profile, profile->mutex, sql, listen_callback, &cbt); + if (!zstr(uuid_in) && strcmp(cbt.uuid, uuid_in)) { + continue; + } status = listen_file(session, profile, &cbt); if (cbt.move == VM_MOVE_PREV) { if (cur_message <= 0) { @@ -3017,6 +3019,8 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p vm_email = switch_core_session_strdup(session, val); } else if (!strcasecmp(var, "vm-notify-mailto")) { vm_notify_email = switch_core_session_strdup(session, val); + } else if (!strcasecmp(var, "vm-skip-instructions")) { + skip_instructions = switch_true(val); } else if (!strcasecmp(var, "email-addr")) { email_addr = switch_core_session_strdup(session, val); } else if (!strcasecmp(var, "vm-email-all-messages") && (send_main = switch_true(val))) { @@ -3154,12 +3158,12 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p if (*buf != '\0') { greet_key_press: if (switch_stristr(buf, profile->login_keys)) { - voicemail_check_main(session, profile, domain_name, id, 0); + voicemail_check_main(session, profile, domain_name, id, 0, NULL); } else if ((!zstr(profile->operator_ext) || !zstr(operator_ext)) && !zstr(profile->operator_key) && !strcasecmp(buf, profile->operator_key) ) { int argc; char *argv[4]; char *mycmd; - + if ((!zstr(operator_ext) && (mycmd = switch_core_session_strdup(session, operator_ext))) || (!zstr(profile->operator_ext) && (mycmd = switch_core_session_strdup(session, profile->operator_ext)))) { argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); @@ -3292,7 +3296,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p #define VM_DESC "voicemail" -#define VM_USAGE "[check] [auth] []" +#define VM_USAGE "[check] [auth] [] [uuid]" SWITCH_STANDARD_APP(voicemail_function) { @@ -3304,6 +3308,7 @@ SWITCH_STANDARD_APP(voicemail_function) const char *domain_name = NULL; const char *id = NULL; const char *auth_var = NULL; + const char *uuid = NULL; int x = 0, check = 0, auth = 0; switch_channel_t *channel = switch_core_session_get_channel(session); @@ -3363,7 +3368,10 @@ SWITCH_STANDARD_APP(voicemail_function) } if (check) { - voicemail_check_main(session, profile, domain_name, id, auth); + if (argv[x]) { + uuid = argv[x++]; + } + voicemail_check_main(session, profile, domain_name, id, auth, uuid); } else { voicemail_leave_main(session, profile, domain_name, id); } diff --git a/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml b/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml index 79c00516b9..069792935c 100644 --- a/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml +++ b/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml @@ -272,6 +272,15 @@ a FXS branch. --> + + + +