Merge branch 'master' into smgmaster

This commit is contained in:
Moises Silva 2011-02-18 22:52:05 -05:00
commit f3d8dc8ad3
76 changed files with 1363 additions and 5256 deletions

View File

@ -52,6 +52,7 @@
<load module="mod_hash"/>
<load module="mod_voicemail"/>
<!--<load module="mod_directory"/>-->
<!--<load module="mod_distributor"/>-->
<!--<load module="mod_lcr"/>-->
<load module="mod_esf"/>
<load module="mod_fsv"/>

View File

@ -98,7 +98,9 @@
<!-- <param name="core-db-name" value="/dev/shm/core.db" /> -->
<!-- The system will create all the db schemas automatically, set this to false to avoid this behaviour-->
<!--<param name="auto-create-schemas" value="true"/>-->
<!-- <param name="core-dbtype" value="MSSQL"/> -->
<!-- <param name="core-dbtype" value="MSSQL"/> -->
<!-- Allow multiple registrations to the same account in the central registration table -->
<!-- <param name="multiple-registrations" value="true"/> -->
</settings>
</configuration>

View File

@ -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 &quot;park+&quot; 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)

View File

@ -27,6 +27,14 @@
# Maintainer(s): Michal Bielicki <michal.bielicki (at) ++nospam_please++ seventhsignal.de
#
######################################################################################################################
# Module build settings
%define build_sng_isdn 0
%define build_sng_ss7 0
%define build_sng_tc 0
%{?with_sang_tc:%define build_sng_tc 1 }
%{?with_sang_isdn:%define build_sng_isdn 1 }
%{?with_sang_ss7:%define build_sng_ss7 1 }
######################################################################################################################
#
# disable rpath checking
@ -54,7 +62,7 @@ Vendor: http://www.freeswitch.org/
#
######################################################################################################################
Source0: http://files.freeswitch.org/%{name}-%{version}.tar.bz2
Source1: http://files.freeswitch.org/downloads/libs/celt-0.7.1.tar.gz
Source1: http://files.freeswitch.org/downloads/libs/celt-0.10.0.tar.gz
Source2: http://files.freeswitch.org/downloads/libs/flite-1.3.99-latest.tar.gz
Source3: http://files.freeswitch.org/downloads/libs/lame-3.97.tar.gz
Source4: http://files.freeswitch.org/downloads/libs/libshout-2.2.2.tar.gz
@ -65,6 +73,8 @@ Source8: http://files.freeswitch.org/downloads/libs/soundtouch-1.3.1.tar.gz
Source9: http://files.freeswitch.org/downloads/libs/sphinxbase-0.4.99-20091212.tar.gz
Source10: http://files.freeswitch.org/downloads/libs/communicator_semi_6000_20080321.tar.gz
Source11: http://files.freeswitch.org/downloads/libs/libmemcached-0.32.tar.gz
Source12: http://files.freeswitch.org/downloads/libs/json-c-0.9.tar.gz
Source13: http://files.freeswitch.org/downloads/libs/opus-0.9.0.tar.gz
Prefix: %{prefix}
@ -109,6 +119,8 @@ BuildRequires: which
BuildRequires: zlib-devel
BuildRequires: e2fsprogs-devel
BuildRequires: libtheora-devel
BuildRequires: libxml2-devel
BuildRequires: bison
Requires: alsa-lib
Requires: libogg
Requires: libvorbis
@ -124,6 +136,7 @@ Requires: zlib
Requires: libtiff
Requires: python
Requires: libtheora
Requires: libxml2
%if %{?suse_version:1}0
%if 0%{?suse_version} > 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

View File

@ -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

View File

@ -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/*

View File

@ -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

View File

@ -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 *~

View File

@ -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

View File

@ -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])]

View File

@ -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;

View File

@ -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

View File

@ -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));
}

View File

@ -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)

View File

@ -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.
<boost_spans> <span sigmod="bri|ss7|blah"> <param="proto-specific-setting" value="setting"> </span> </boost_spans>
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.

View File

@ -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:
*/

View File

@ -1,373 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="ftmod_sangoma_boost"
ProjectGUID="{D021EF2A-460D-4827-A0F7-41FDECF46F1B}"
RootNamespace="ftmod_sangoma_boost"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
DebugInformationFormat="4"
DisableSpecificWarnings="4100"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="freetdm.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="&quot;$(OutDir)&quot;"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
DebugInformationFormat="3"
DisableSpecificWarnings="4100"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="freetdm.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="&quot;$(OutDir)&quot;"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
DebugInformationFormat="3"
DisableSpecificWarnings="4100"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="false"
DebugInformationFormat="3"
DisableSpecificWarnings="4100"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="ftmod_sangoma_boost.c"
>
</File>
<File
RelativePath="sangoma_boost_client.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="ftdm_sangoma_boost.h"
>
</File>
<File
RelativePath="sangoma_boost_client.h"
>
</File>
<File
RelativePath="sangoma_boost_interface.h"
>
</File>
<File
RelativePath="sigboost.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,206 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>ftmod_sangoma_boost</ProjectName>
<ProjectGuid>{D021EF2A-460D-4827-A0F7-41FDECF46F1B}</ProjectGuid>
<RootNamespace>ftmod_sangoma_boost</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\include;..\..\isdn\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\include;..\..\isdn\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>false</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="ftmod_sangoma_boost.c" />
<ClCompile Include="sangoma_boost_client.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ftdm_sangoma_boost.h" />
<ClInclude Include="sangoma_boost_client.h" />
<ClInclude Include="sangoma_boost_interface.h" />
<ClInclude Include="sigboost.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\msvc\freetdm.2010.vcxproj">
<Project>{93b8812c-3ec4-4f78-8970-ffbfc99e167d}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ftmod_sangoma_boost.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sangoma_boost_client.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ftdm_sangoma_boost.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="sangoma_boost_client.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="sangoma_boost_interface.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="sigboost.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -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 <netdb.h>
#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:
*/

View File

@ -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 <ctype.h>
#include <string.h>
#ifndef WIN32
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef HAVE_NETINET_SCTP_H
#include <netinet/sctp.h>
#endif
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/time.h>
#endif
#include <stdlib.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdarg.h>
#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:
*/

View File

@ -1,254 +0,0 @@
/*
* Copyright (c) 2009, Sangoma Technologies
* Moises Silva <moy@sangoma.com>
* 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:
*/

View File

@ -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 <freetdm.h>
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

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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-=+?></.,!@#$%^&*();:';
my $numchars = length(CHARACTERS);
## 'ALPHACHARS' contains upper and lower case letters and digits but no punctuation
use constant ALPHACHARS => '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(<FILEIN>) {
## 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(<FILEIN>)
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 <<END_USAGE
Randomize passwords for FreeSWITCH directory entries.
Usage: ./randomize-passwords.pl --files=<file spec> [-D] [--vmlen=<vm pass length>] [--authlen=<auth pass length>]
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);
}

View File

@ -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;

View File

@ -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

View File

@ -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";

View File

@ -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)) {

View File

@ -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] <profile_name> <domain_name> [<id>]"
#define VM_USAGE "[check] [auth] <profile_name> <domain_name> [<id>] [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);
}

View File

@ -272,6 +272,15 @@ a FXS branch.
<param name="fxs-bina" value="yes"/>
-->
<!--
Enables/disables the use of sharp (#) as an end-of-number digit on FXS
channels for instant dialing. This does not affect special numbers which
start on sharp, like #8 or #1.
(default = yes)
<param name="fxs-sharp-dial" value="yes" />
-->
<!--
This is the delay time to really disconnect a channel after the disconnect
event arrive. If a connect event comes up in this interval, then the
@ -312,6 +321,21 @@ you may need to set this option to 'no'.
<param name="ignore-letter-dtmfs" value="yes"/>
-->
<!--
When there is a request to indicate busy for an incoming KFXO call, the
ringing channel is taken off hook and then placed on hook, so it now goes
to answered state and we can send audio throught the line.
If the off/on hook time interval is too short, the PSTN may ignore it, and
keep the line in a ringing state. If it is too long, the call may be charged.
The option below defines the delay between the line being answered and being
disconnected, in miliseconds (from 50ms to 90000ms).
(default = 1250)
<param name="fxo-busy-disconnection" value="1250"/>
-->
<!--
For KFXO series boards, defines if audio will be allowed being sent into
outgoing calls before it has been connected.

View File

@ -69,6 +69,6 @@
#define COMMONS_VERSION_MINOR 1
#define COMMONS_AT_LEAST(x,y) \
(COMMONS_VERSION_MAJOR > x || (COMMONS_VERSION_MAJOR == x && COMMONS_VERSION_MINOR >= y))
((COMMONS_VERSION_MAJOR > x) || (COMMONS_VERSION_MAJOR == x && COMMONS_VERSION_MINOR >= y))
#endif /* _CONFIG_COMMONS_HPP_ */

View File

@ -690,6 +690,32 @@ namespace Config
iter->second.set(object, value);
}
template < typename Object >
Messages commit(Object * const object, const std::string & name)
{
Messages msgs;
OptionMap::iterator i = _map.find(name);
if (i != _map.end())
{
try
{
i->second.commit(object);
}
catch (Failure & e)
{
msgs.push_back(e.what());
}
}
else
{
msgs.push_back(STG(FMT("unable to find option: %s") % name));
};
return msgs;
}
template < typename Object >
Messages commit(Object * const object)
{
@ -718,7 +744,7 @@ namespace Config
}
template < typename Object >
bool loaded(Object * object, std::string name)
bool loaded(Object * object, const std::string & name)
{
OptionMap::iterator iter = find_option(name);

View File

@ -144,9 +144,8 @@ bool Configfile::deserialize(std::ifstream & fd)
if (adjust(section, opt, val))
continue;
_errors.push_back(STG(FMT("option '%s' does "
"not exist or '%s' is not a valid value (at section '%s')")
% opt % val % section->name()));
_errors.push_back(STG(FMT("option '%s' does not exist or '%s' is not "
"a valid value (at section '%s')") % opt % val % section->name()));
}
}

View File

@ -205,6 +205,15 @@ std::string K3LAPIBase::get_param(K3L_EVENT *ev, const char *name) const
return res;
}
std::string K3LAPIBase::get_param_optional(K3L_EVENT *ev, const char *name) const
{
std::string res;
(void)get_param(ev, name, res);
return res;
}
void K3LAPIBase::init(void)
{
if (_device_count != 0) return;

View File

@ -317,7 +317,9 @@ struct K3LAPIBase
/* pega valores em strings de eventos */
KLibraryStatus get_param(K3L_EVENT *ev, const char *name, std::string &res) const;
std::string get_param(K3L_EVENT *ev, const char *name) const;
std::string get_param_optional(K3L_EVENT *ev, const char *name) const;
/* inicializa valores em cache */

View File

@ -52,22 +52,16 @@
#include <refcounter.hpp>
#include <flagger.hpp>
#if defined(COMMONS_LIBRARY_USING_ASTERISK)
#if defined(COMMONS_LIBRARY_USING_ASTERISK) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
extern "C"
{
#include <asterisk.h>
#include <asterisk/localtime.h>
#include <time.h>
}
#elif defined(COMMONS_LIBRARY_USING_CALLWEAVER)
extern "C"
{
#include <callweaver/localtime.h>
}
#elif defined(COMMONS_LIBRARY_USING_FREESWITCH)
extern "C"
{
#include <time.h>
}
#endif
/*
@ -424,77 +418,26 @@ struct Logger
if (opt._flags[Option::DATETIME])
{
#if defined(COMMONS_LIBRARY_USING_ASTERISK)
#if ASTERISK_AT_LEAST(1,6,0)
struct timeval tv;
struct ast_tm lt;
gettimeofday(&tv, NULL);
#else
#if defined(COMMONS_LIBRARY_USING_ASTERISK) || defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
time_t tv;
struct tm lt;
time (&tv);
#endif
#if ASTERISK_AT_LEAST(1,4,5)
ast_localtime (&tv, &lt, NULL);
#else
localtime_r (&tv, &lt);
#endif
#elif defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
time_t tv;
struct tm lt;
time (&tv);
localtime_r (&tv, &lt);
#endif
out_msg += STG(FMT("[%02d-%02d-%02d %02d:%02d:%02d] ")
% (lt.tm_year % 100) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour
% lt.tm_min % lt.tm_sec);
#endif
}
if (opt._flags[Option::DATETIMEMS])
{
#if defined(COMMONS_LIBRARY_USING_ASTERISK)
#if ASTERISK_AT_LEAST(1,6,0)
struct timeval tv;
struct ast_tm lt;
gettimeofday(&tv, NULL);
#else
#if defined(COMMONS_LIBRARY_USING_ASTERISK) || defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
time_t tv;
struct tm lt;
time (&tv);
#endif
#if ASTERISK_AT_LEAST(1,4,5)
ast_localtime (&tv, &lt, NULL);
#else
localtime_r (&tv, &lt);
#endif
#if ASTERISK_AT_LEAST(1,6,0)
out_msg += STG(FMT("[%02d-%02d-%02d %02d:%02d:%02d:%04d] ")
% (lt.tm_year % 100) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour % lt.tm_min
% lt.tm_sec % (tv.tv_usec / 1000));
#else
out_msg += STG(FMT("[%02d-%02d-%02d %02d:%02d:%02d:%04d] ")
% (lt.tm_year % 100) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour % lt.tm_min
% lt.tm_sec % (tv * 1000));
#endif
#elif defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
time_t tv;
struct tm lt;
time (&tv);
localtime_r (&tv, &lt);
out_msg += STG(FMT("[%02d-%02d-%02d %02d:%02d:%02d:%04d] ")

View File

@ -52,7 +52,7 @@
/* This struct uses static polymorphism, and derived classes should implement *
* the "lock/trylock/unlock()" methods for correct code compilation. *
* The base class also features reference counting, so derived classes should *
* implement the "unreference()" method for releasing resources. */
* implement the "unreference_data()" method for releasing resources. */
template < typename Implementor >
struct SimpleLockCommon: COUNTER_SUPER( SimpleLockCommon < Implementor > )
@ -95,7 +95,7 @@ struct SimpleLockCommon: COUNTER_SUPER( SimpleLockCommon < Implementor > )
protected:
void unreference(void)
{
static_cast<Implementor*>(this)->unreference();
static_cast<Implementor*>(this)->unreference_data();
}
};

View File

@ -73,7 +73,7 @@ struct SimpleLockBasic: public SimpleLockCommon < Implementor >
/* do nothing */
};
void unreference()
void unreference_data()
{
switch_mutex_destroy(_mutex);

View File

@ -2505,9 +2505,11 @@ std::string Verbose::command(const int32 cmd_code, const int32 dev_idx, const in
case VerboseTraits::K_CM_LOG_REQUEST:
case VerboseTraits::K_CM_LOG_CREATE_DISPATCHER:
case VerboseTraits::K_CM_LOG_DESTROY_DISPATCHER:
case VerboseTraits::K_CM_PING:
#endif
//#if K3L_AT_LEAST(2,1,0)
// case VerboseTraits::K_CM_LOG_UPDATE:
//#endif
return show(buf, commandName(code), Target(NONE));
#if K3L_AT_LEAST(2,1,0)
case VerboseTraits::K_CM_START_FAX_TX:

View File

@ -29,7 +29,10 @@
</p>
<pre><b>Sintaxe:</b> &lt;param name="..." value="..."/&gt;
</pre>
<ul><li><b>dialplan</b>: Nome do módulo de <i>dialplan</i> em uso.
<p><br />
</p>
<ul><li><b>accountcode</b>: Define o account code padrão para chamadas no Endpoint. Esta opção pode ser qualquer string alfanumérica;
</li><li><b>dialplan</b>: Nome do módulo de <i>dialplan</i> em uso.
</li><li><b>auto-fax-adjustment</b>: Ativa ("yes") ou desativa ("no") o ajuste automático do canal (desabilitar o cancelador de eco e a supressão DTMF) ao detectar tom de FAX;
</li><li><b>auto-gain-control</b>: Ativa ("yes") ou desativa ("no") a ativação do controle automático de ganho (AGC) pelo Endpoint;
</li><li><b>context-digital</b>: Contexto de entrada para ligações em placas digitais (o padrão é "khomp-DD-LL", onde "DD" será substituído, no momento da ligação, pelo número do dispositivo, "LL" pelo número do link, "CCC" pelo número do canal e "SSSS" pelo número serial do dispositivo);
@ -49,6 +52,7 @@
</li><li><b>fxs-global-orig</b>: Número inicial para numeração seqüencial de ramais das placas <b>KFXS</b> que não estiverem listadas na seção <b>&lt;fxs-branches&gt;</b> (a numeração segue ordem crescente por número da placa e número do canal físico) (o padrão é "0");
</li><li><b>fxs-co-dialtone</b>: Seqüências de números, separados por vírgula, que disparam um tom contínuo (de central pública) em ramais FXS (ex: "0,99" faz com que, ao discar "0" ou "99", o usuário receba o tom de linha contínuo) (o padrão é vazio);
</li><li><b>fxs-bina</b>: Quando ativada ("yes"), ligações para ramais FXS enviarão os dígitos correspondentes ao telefone de origem em sinalização BINA DTMF (o valor padrão é "no");
</li><li><b>language</b>: Define idioma para ligações nas placas Khomp;
</li><li><b>ignore-letter-dtmfs</b>: Define se o canal deve ignorar DTMFs incomuns detectados pela placa (A, B, C e D). Entretanto, se você necessita passar esses dígitos pela placa, você deve ajustar esta opção para "no" (o valor padrão é "yes");
</li><li><b>input-volume</b>: Define o volume de entrada das ligações, varia de -10 a +10&nbsp;;
</li><li><b>kommuter-activation</b>: Define se a ativação de dispositivos kommuter encontrados no sistema será feita de forma automática ("auto"), ou de forma manual ("manual") pelo usuário, através do comando "khomp kommuter on/off";
@ -119,6 +123,8 @@
<ul><li>context;
</li><li>input-volume;
</li><li>output-volume;
</li><li>language;
</li><li>accountcode;
</li><li>calleridnum;
</li><li>calleridname;
</li><li>flash-to-digits.
@ -1011,7 +1017,7 @@ install: ** for knowing how to proceed with the installation. **
<p>Este configurador, por sua vez, mostra todas as opções possíveis de configuração da placa. Os parâmetros que não forem configurados assumem os valores padrão automaticamente, e são compatíveis com a maior parte dos sistemas. Maiores detalhes sobre este programa podem ser obtidos na seção de número '2'.
</p><p><br />
</p>
<ul><li> <b>IMPORTANTE</b>: Para o FreeSWITCH iniciar, é preciso que a placa da khomp esteja configurada e todos módulos estejam rodando (conforme mostrado acima). <b>Caso a placa não esteja configurada, o FreeSWITCH não iniciará</b>.<br /><br />Se você deseja rodar o sistema sem a placa da Khomp, é preciso configurar o FreeSWITCH para ele não carregar o módulo da Khomp. Para isso, abra o arquivo "<i>/usr/local/freeswitch/conf/autoload_configs/modules.conf.xml</i>", e comente a linha que carrega o módulo:<br />
<ul><li> <b>IMPORTANTE</b>: Para o FreeSWITCH iniciar, é preciso que a placa da khomp esteja configurada e todos módulos estejam rodando (conforme mostrado acima). <br /><br />Se você deseja rodar o sistema sem a placa da Khomp, é preciso configurar o FreeSWITCH para ele não carregar o módulo da Khomp. Para isso, abra o arquivo <b>/usr/local/freeswitch/conf/autoload_configs/modules.conf.xml</b>, e comente a linha que carrega o módulo:<br />
</li></ul>
<pre>
&lt;!-- &lt;load module=&quot;mod_khomp&quot; /&gt; --&gt;
@ -1080,4 +1086,6 @@ Por fim, para carregar o servidor de processos, basta executar o seguinte comand
O <i>script</i> <b>/etc/init.d/khompdrv</b> é responsável por carregar os módulos <i>kpci9030.ko</i> e <i>kpex8311.ko</i> no <i>kernel</i>, que deve ser realizada automaticamente na inicialização do sistema. Em caso de problemas, verifique a seção <a href="#Solu.C3.A7.C3.A3o_de_problemas" title="">Solução de problemas</a>.
<br />
</p><p><br />
Para mais detalhes: <a href="http://www.khomp.com.br" class="external free" title="http://www.khomp.com.br" rel="nofollow">http://www.khomp.com.br</a>
</p><p><br />
</p></body></html>

View File

@ -6,7 +6,7 @@
<a name="Utilizando_o_Endpoint_da_Khomp" id="Utilizando_o_Endpoint_da_Khomp"></a><h1> <span class="mw-headline"> Utilizando o <i>Endpoint</i> da Khomp </span></h1>
<p>Após a instalação e inicialização dos serviços necessários pela Khomp, o FreeSWITCH já pode ser carregado ou inicializado.
</p>
<ul><li> <b>AVISO</b>: É imprescindível que o <b>FreeSWITCH</b> não seja executado utilizando a opção que desabilita o escalonamento em tempo real (-nort), <b>especialmente</b> se este estiver sendo executado lado-a-lado com servidores <i>web</i> ou servidores de banco de dados. Não realizar este procedimento pode resultar em perda de qualidade do áudio, gerando um sério comprometimento no andamento das ligações do sistema.
<ul><li> <b>AVISO</b>: Evite usar a opção <b>-nort</b>, pois ela desabilita escalonamento em tempo real, é imprescindível que o <b>FreeSWITCH</b> esteja utilizando o escalonamento em tempo real, especialmente se este estiver sendo executado lado-a-lado com servidores <i>web</i> ou servidores de banco de dados. Utilizar a opção <b>-nort</b> pode resultar em perda de qualidade do áudio, gerando um sério comprometimento nas ligações do sistema.
</li></ul>
<p>Após a inicialização do FreeSWITCH, pode-se verificar se o módulo da Khomp foi carregado através do seguinte comando:<br />
</p>

View File

@ -6,10 +6,9 @@
<a name="Using_the_Khomp_Endpoint" id="Using_the_Khomp_Endpoint"></a><h1> <span class="mw-headline"> Using the Khomp Endpoint </span></h1>
<p>After installation and startup services required by Khomp, FreeSWITCH can now be loaded or initialized.
</p>
<ul><li><b>WARNING</b>: It is imperative that the<b>FreeSWITCH</b> is not executed using the option that disables the escalation in real time (-nort), <b>especially</b> if this is running side-by server-side with web servers or database. Failure to do so may result in loss of audio quality, causing a serious commitment on the progress of system connections.
<ul><li><b>WARNING</b>: Avoid using the <b>-nort</b>, as it disables real-time scheduling, it is essential that the <b>FreeSwitch</b> are using real-time scheduling, especially if it is running side-by-side with <i>web</i> servers or database . Use the <b>-nort</b> may result in loss of audio quality, causing a serious commitment on the progress of system connections.
</li></ul>
<p>After initialization of FreeSWITCH, you can verify that the module was loaded Khomp through the following command: <br />
</p><p><br />
</p>
<pre> freeswitch@hostname&gt; module_exists mod_khomp
</pre>

View File

@ -30,7 +30,8 @@ If you need to set advanced parameters of the board and/or signaling, the progra
</p>
<pre><b>Sintaxe:</b> &lt;param name="..." value="..."/&gt;
</pre>
<ul><li><b>dialplan</b>: Name of the dialplan module in use.
<ul><li><b>accountcode</b>: Sets the default account code to calls in the Endpoint. This option can be any alphanumeric string;
</li><li><b>dialplan</b>: Name of the dialplan module in use.
</li><li><b>auto-fax-adjustment</b>: Enable ("yes") or disables ("no") the automatic adjustment of the channel (disable the echo canceller and the suppression DTMF) tone to detect FAX (local option)&nbsp;;
</li><li><b>auto-gain-control</b>:Enable ("yes") or disables ("no") the activation of the automatic gain control (AGC) by the Endpoint (local option);
</li><li><b>context-digital</b>: Context for incoming connections on digital boards (the default is "khomp-DD-LL", where "DD" will be replaced at the time of connection by the device number, "LL" by the number of the link, "CCC" by channel number and "SSSS" for the device serial number);
@ -54,6 +55,7 @@ If you need to set advanced parameters of the board and/or signaling, the progra
</li><li><b>input-volume</b>: Sets the volume gain for incoming audio (entering the board), from -10 to +10 (local option);
</li><li><b>kommuter-activation</b>: Sets whether to activate devices kommuter found in the system will be done automatically ("auto") by the channel, or manually ("manual") by the user through the command "khomp kommuter on/off"
</li><li><b>kommuter-timeout</b>: Sets the timeout (in seconds) for initializing the kommuter devices. If this timeout is reached without receiving notification of the channel, the devices will switch back to "off" condition. The minimum value is "0", where the links will always remain switched "on", and the maximum is "255";
</li><li><b>language</b>: Set language to Khomp board calls;
</li><li><b>log-to-console</b>: Set log messages to be printed on the console;
</li><li><b>log-to-disk</b> (old "log"): Set log messages to be saved to disk;
</li><li><b>out-of-band-DTMF</b> (former <b>dtmfsuppression</b>): Activate ("yes") or disables ("no") the removal and DTMF sending these out-of-band (local option);
@ -125,6 +127,8 @@ For details, please refer to the configuration file for examples.
</li><li>output-volume;
</li><li>calleridnum;
</li><li>calleridname;
</li><li>language;
</li><li>accountcode;
</li><li>flash-to-digits.
</li></ul>
<p>Each option is separated from each other by a pipe "|" or a slash "/" and defined after the colon ":". Example:
@ -1018,7 +1022,7 @@ install: ** for knowing how to proceed with the installation. **
</pre>
<p>This configurator, in turn, shows all possible options for card configuration. The parameters that are not configured automatically assume the default values, and are compatible with most systems. More details about this program can be obtained from the section number '2 '.
</p>
<ul><li> <b>ATTENTION'<i>: To start FreeSWITCH&reg;, it is necessary that the board is configured Khomp and all modules are running (as shown above). </i></b><i>If the card is not configured, FreeSWITCH will not start<b>.<br /> <br /> If you want to run the system without the board Khomp, you need to configure FreeSWITCH for it does not load the module Khomp. To do this, open the "</b></i><b>/usr/local/freeswitch/conf/autoload_configs/modules.conf.xml</b> and comment the line:<br />
<ul><li> <b>ATTENTION</b>: To start FreeSWITCH&reg;, it is necessary that the Khomp board is configured and all modules are running (as shown above). <br /> <br /> If you want to run the system without the Khomp board, you need to configure FreeSWITCH for it does not load the module Khomp. To do this, open the <b>/usr/local/freeswitch/conf/autoload_configs/modules.conf.xml</b> and comment the line:<br />
</li></ul>
<pre>
&lt;!-- &lt;load module=&quot;mod_khomp&quot; /&gt; --&gt;
@ -1060,7 +1064,7 @@ install: ** for knowing how to proceed with the installation. **
<br />
</p>
<a name="Ap.C3.AAndice" id="Ap.C3.AAndice"></a><h1> <span class="mw-headline"> Apêndice </span></h1>
<p>Nesta seção, encontram-se informações úteis sobre o Endpoint e componentes relacionados.
<p>This section presents useful informations about Endpoint and related components.
</p>
<a name="Arrangement_of_installed_files" id="Arrangement_of_installed_files"></a><h2> <span class="mw-headline"> Arrangement of installed files </span></h2>
<p>The directories created/modified in this facility are:
@ -1084,5 +1088,6 @@ install: ** for knowing how to proceed with the installation. **
</pre>
<p>The script <b>/etc/init.d/khompdrv</b> is responsible for loading modules <b>kpci9030.ko</b> and <b>kpex8311.ko</b> in the kernel, which should be carried out automatically at system startup. In case of problems, check the <a href="#Troubleshooting" title="">Troubleshooting</a> section.
</p><p><br />
</p><p>For more details: <a href="http://www.khomp.com.br" class="external free" title="http://www.khomp.com.br" rel="nofollow">http://www.khomp.com.br</a>
</p><p><br />
</p></body></html>

View File

@ -733,17 +733,21 @@ struct Cli
options.push_back("fxs-global-orig");
options.push_back("fxs-co-dialtone");
options.push_back("fxs-bina");
options.push_back("fxs-sharp-dial");
options.push_back("disconnect-delay");
options.push_back("delay-ringback-co");
options.push_back("delay-ringback-pbx");
options.push_back("ignore-letter-dtmfs");
options.push_back("fxo-send-pre-audio");
options.push_back("fxo-busy-disconnection");
options.push_back("fxs-digit-timeout");
options.push_back("drop-collect-call");
options.push_back("kommuter-activation");
options.push_back("kommuter-timeout");
options.push_back("user-transfer-digits");
options.push_back("flash-to-digits");
options.push_back("accountcode");
options.push_back("audio-packet-length");
brief = "Get configuration options in the Khomp channel.";
@ -821,17 +825,21 @@ struct Cli
options.push_back("fxs-global-orig");
options.push_back("fxs-co-dialtone");
options.push_back("fxs-bina");
options.push_back("fxs-sharp-dial");
options.push_back("disconnect-delay");
options.push_back("delay-ringback-co");
options.push_back("delay-ringback-pbx");
options.push_back("ignore-letter-dtmfs");
options.push_back("fxo-send-pre-audio");
options.push_back("fxo-busy-disconnection");
options.push_back("fxs-digit-timeout");
options.push_back("drop-collect-call");
options.push_back("kommuter-activation");
options.push_back("kommuter-timeout");
options.push_back("user-transfer-digits");
options.push_back("flash-to-digits");
options.push_back("accountcode");
options.push_back("audio-packet-length");
brief = "Ajust configuration options in the Khomp channel.";
@ -933,6 +941,36 @@ struct Cli
bool execute(int argc, char *argv[]);
} KhompRevision;
/* khomp dump config */
static struct _KhompDumpConfig : public Command
{
_KhompDumpConfig()
{
complete_name = "dump config";
brief = "Dump configuration values on screen.";
usage = \
"\nUsage: khomp dump config\n\n" \
"Dump configuration values loaded on memory.\n ";
_commands.push_back(this);
}
/* just to hide unavaible options */
bool removeUnavaible(const std::string &s)
{
if(s == "atxfer" || s == "blindxfer" || s == "callgroup" ||
s == "mohclass" || s == "native-bridge" || s == "recording" ||
s == "record-prefix" || s == "transferdigittimeout" ||
s == "pickupgroup" || s == "has-ctbus" ||
s == "user-transfer-digits")
return true;
return false;
}
bool execute(int argc, char *argv[]);
} KhompDumpConfig;
/* khomp send command */
static struct _KhompSendCommand : public Command
{

View File

@ -231,6 +231,8 @@ struct KVoIPSeize
#define CM_USER_INFORMATION 0x0F
#define CM_USER_INFORMATION_EX 0x2B
#define CM_VOIP_SEIZE 0x23
@ -369,6 +371,8 @@ struct KVoIPSeize
#define EV_USER_INFORMATION 0x0F
#define EV_USER_INFORMATION_EX 0x1D
#define EV_DIALED_DIGIT 0x10
#define EV_SIP_REGISTER_INFO 0x11
@ -713,6 +717,8 @@ enum KH100CtbusFreq
#define CM_START_CADENCE 0xA1
#define CM_STOP_CADENCE 0xA2
#define CM_SET_INPUT_MODE 0xA3
#if !defined KR2D_H
#define KR2D_H
@ -925,6 +931,7 @@ enum KSignGroupII
#ifndef _KISDN_H_
#define _KISDN_H_
#define KMAX_USER_USER_LEN 32
#define KMAX_USER_USER_EX_LEN 254
#define KMAX_SUBADRESS_INFORMATION_LEN 20
enum KQ931Cause
@ -1845,6 +1852,12 @@ struct KUserInformation
int32 UserInfoLength;
byte UserInfo[ KMAX_USER_USER_LEN ];
};
struct KUserInformationEx
{
int32 ProtocolDescriptor;
int32 UserInfoLength;
byte UserInfo[ KMAX_USER_USER_EX_LEN ];
};
struct KISDNSubaddressInformation
{
KQ931TypeOfSubaddress TypeOfSubaddress;

View File

@ -305,8 +305,6 @@ struct KhompPvt
{
try
{
//std::string type((name == "input_volume")?"input":"output");
int i = Strings::tolong(value);
if (i < -10 || i > 10)
@ -614,6 +612,7 @@ public:
virtual bool indicateRinging();
virtual bool sendDtmf(std::string digit);
virtual void cleanupIndications(bool force);
/* Methods */
@ -849,7 +848,31 @@ public:
if(!name)
return NULL;
return switch_core_get_variable(name);
#if SWITCH_LESS_THAN(1,0,6)
const char * tmp = switch_core_get_variable(name);
if(!tmp) return NULL;
const char * val = strdup(tmp);
return val;
#else
return switch_core_get_variable_dup(name);
#endif
}
void freeFSGlobalVar(const char ** val)
{
if(!val || !*val) return;
#if SWITCH_LESS_THAN(1,0,6)
free((void *)*val);
*val = NULL;
#else
char * v = (char *)*val;
switch_safe_free(v);
*val=NULL;
#endif
}
bool mixer(const char *file, const char *func, int line,

View File

@ -138,7 +138,7 @@ struct KhompPvtFXO: public KhompPvt
TriState _var_fax_adjust;
//ChanTimer::Index _idx_disconnect;
ChanTimer::Index _busy_disconnect;
};
/******************************************************************************/
KhompPvtFXO(K3LAPIBase::GenericTarget & target) : KhompPvt(target)
@ -240,6 +240,7 @@ struct KhompPvtFXO: public KhompPvt
bool autoGainControl(bool enable);
void setAnswerInfo(int answer_info);
bool indicateBusyUnlocked(int cause, bool sent_signaling = false);
static void busyDisconnect(Board::KhompPvt * pvt);
void reportFailToReceive(int fail_code);
bool validContexts(MatchExtension::ContextListType & contexts,
std::string extra_context = "");
@ -266,13 +267,20 @@ struct KhompPvtFXO: public KhompPvt
virtual bool cleanup(CleanupType type = CLN_HARD)
{
//Board::board(_target.device)->_timers.del(callFXO()->_idx_disconnect);
//callFXO()->_idx_disconnect.reset();
try
{
Board::board(_target.device)->_timers.del(callFXO()->_busy_disconnect);
}
catch (K3LAPITraits::invalid_device & err)
{
LOG(ERROR, PVT_FMT(target(), "Unable to get device: %d!") % err.device);
}
call()->_flags.clear(Kflags::CALL_WAIT_SEIZE);
call()->_flags.clear(Kflags::EARLY_RINGBACK);
_transfer->clear();
callFXO()->_busy_disconnect.reset();
switch (type)
{
@ -312,6 +320,16 @@ struct KhompPvtFXO: public KhompPvt
// static void delayedDisconnect(Board::KhompPvt * pvt);
void cleanupIndications(bool force)
{
if (call()->_indication == INDICA_BUSY && !force)
{
DBG(FUNC, PVT_FMT(_target, "skipping busy indication cleanup on FXO channel."));
return;
}
KhompPvt::cleanupIndications(force);
}
};
/******************************************************************************/
/******************************************************************************/

View File

@ -272,24 +272,39 @@ struct KhompPvtISDN: public KhompPvtE1
bool process(std::string name, std::string value = "")
{
if (name == "uui")
if ((name == "uui" ) || (name == "uui_ex"))
{
Strings::vector_type values;
Strings::tokenize(value, values, "#", 2);
try
if(value.find("#") != std::string::npos)
{
std::string uui_proto_s = values[0];
std::string uui_data_s = values[1];
Strings::vector_type values;
Strings::tokenize(value, values, "#", 2);
_uui_descriptor = Strings::toulong(uui_proto_s);
_uui_information.append(uui_data_s);
try
{
std::string uui_proto_s = values[0];
_uui_extended = (name == "uui_ex");
_uui_descriptor = Strings::toulong(uui_proto_s);
_uui_information.clear();
DBG(FUNC, FMT("uui adjusted (%s, '%s')!") % uui_proto_s.c_str() % uui_data_s.c_str());
}
catch (...)
for (unsigned int i = 0; i < values[1].size(); ++i)
_uui_information += STG(FMT("%02hhx") % ((unsigned char)values[1][i]));
DBG(FUNC, FMT("uui adjusted (ex=%s, proto=%s, data='%s')!")
% (_uui_extended ? "true" : "false")
% uui_proto_s.c_str()
% _uui_information.c_str());
}
catch (...)
{
LOG(ERROR, FMT("invalid %s protocol descriptor: '%s' is not a number.")
% (_uui_extended ? "uui_ex" : "uui")
% value.c_str());
}
}
else
{
LOG(ERROR, FMT("invalid uui protocol descriptor: '%s' is not a number.") % value.c_str());
LOG(ERROR, FMT("invalid %s protocol descriptor, need a '#'.")
% (_uui_extended ? "uui_ex" : "uui"))
}
}
else if (name == "usr_xfer")
@ -306,6 +321,7 @@ struct KhompPvtISDN: public KhompPvtE1
bool clear()
{
_uui_extended = false;
_uui_descriptor = -1;
_uui_information.clear();
_isdn_cause = -1;
@ -322,6 +338,7 @@ struct KhompPvtISDN: public KhompPvtE1
long int _uui_descriptor;
std::string _uui_information;
long int _isdn_cause;
bool _uui_extended;
/* what should we dial to trigger an user-signaled transfer? */
/* used for xfer on user signaling */
@ -329,6 +346,13 @@ struct KhompPvtISDN: public KhompPvtE1
std::string _user_xfer_buffer;
std::string _digits_buffer;
std::string _qsig_number;
/* isdn information */
std::string _isdn_orig_type_of_number;
std::string _isdn_orig_numbering_plan;
std::string _isdn_dest_type_of_number;
std::string _isdn_dest_numbering_plan;
std::string _isdn_orig_presentation;
};
/******************************************************************************/
@ -429,12 +453,29 @@ struct KhompPvtISDN: public KhompPvtE1
std::string descriptor = STG(FMT("%d") % callISDN()->_uui_descriptor);
setFSChannelVar("KUserInfoExtended", (callISDN()->_uui_extended ? "true" : "false"));
setFSChannelVar("KUserInfoDescriptor", descriptor.c_str());
setFSChannelVar("KUserInfoData", callISDN()->_uui_information.c_str());
callISDN()->_uui_extended = false;
callISDN()->_uui_descriptor = -1;
callISDN()->_uui_information.clear();
}
if (!callISDN()->_isdn_orig_type_of_number.empty())
setFSChannelVar("KISDNOrigTypeOfNumber", callISDN()->_isdn_orig_type_of_number.c_str());
if (!callISDN()->_isdn_dest_type_of_number.empty())
setFSChannelVar("KISDNDestTypeOfNumber", callISDN()->_isdn_dest_type_of_number.c_str());
if (!callISDN()->_isdn_orig_numbering_plan.empty())
setFSChannelVar("KISDNOrigNumberingPlan", callISDN()->_isdn_orig_numbering_plan.c_str());
if (!callISDN()->_isdn_dest_numbering_plan.empty())
setFSChannelVar("KISDNDestNumberingPlan", callISDN()->_isdn_dest_numbering_plan.c_str());
if (!callISDN()->_isdn_orig_presentation.empty())
setFSChannelVar("KISDNOrigPresentation", callISDN()->_isdn_orig_presentation.c_str());
}
catch(Board::KhompPvt::InvalidSwitchChannel & err)
{
@ -444,8 +485,33 @@ struct KhompPvtISDN: public KhompPvtE1
KhompPvtE1::setSpecialVariables();
}
Transfer<CallISDN, false> * _transfer;
virtual void getSpecialVariables()
{
try
{
const char * isdn_orig_type = getFSChannelVar("KISDNOrigTypeOfNumber");
const char * isdn_dest_type = getFSChannelVar("KISDNDestTypeOfNumber");
const char * isdn_orig_numbering = getFSChannelVar("KISDNOrigNumberingPlan");
const char * isdn_dest_numbering = getFSChannelVar("KISDNDestNumberingPlan");
const char * isdn_orig_presentation = getFSChannelVar("KISDNOrigPresentation");
LOG(ERROR, PVT_FMT(_target,"ISDNORIG: %s") % (isdn_orig_type ? isdn_orig_type : ""));
callISDN()->_isdn_orig_type_of_number = (isdn_orig_type ? isdn_orig_type : "");
callISDN()->_isdn_dest_type_of_number = (isdn_dest_type ? isdn_dest_type : "");
callISDN()->_isdn_orig_numbering_plan = (isdn_orig_numbering ? isdn_orig_numbering : "");
callISDN()->_isdn_dest_numbering_plan = (isdn_dest_numbering ? isdn_dest_numbering : "");
callISDN()->_isdn_orig_presentation = (isdn_orig_presentation ? isdn_orig_presentation : "");
}
catch(Board::KhompPvt::InvalidSwitchChannel & err)
{
LOG(ERROR, PVT_FMT(_target, "(ISDN) %s") % err._msg.c_str());
}
KhompPvt::getSpecialVariables();
}
Transfer<CallISDN, false> * _transfer;
};
/******************************************************************************/
/********************************* R2 Channel *********************************/
@ -472,7 +538,6 @@ struct KhompPvtR2: public KhompPvtE1
{
LOG(ERROR, FMT("invalid r2 category: '%s' is not a number.") % value.c_str());
}
}
else
{
@ -554,7 +619,23 @@ struct KhompPvtR2: public KhompPvtE1
{
return (CallR2 *)call();
}
bool forceDisconnect(void)
{
char cmd[] = { 0x07, (char)(_target.object + 1) };
try
{
Globals::k3lapi.raw_command(_target.device, 0, cmd, sizeof(cmd));
}
catch(K3LAPI::failed_raw_command &e)
{
return false;
}
return true;
};
int makeCall(std::string params = "");
bool doChannelAnswer(CommandRequest &);
bool doChannelHangup(CommandRequest &);
@ -609,9 +690,9 @@ struct KhompPvtR2: public KhompPvtE1
/* r2 caller category */
if (callR2()->_r2_category != -1)
{
setFSChannelVar("KR2GotCategory",Verbose::signGroupII((KSignGroupII)callR2()->_r2_category).c_str());
setFSChannelVar("KR2GotCategory",STG(FMT("%d") % callR2()->_r2_category).c_str());
setFSChannelVar("KR2StrCategory",Verbose::signGroupII((KSignGroupII)callR2()->_r2_category).c_str());
}
}
catch(Board::KhompPvt::InvalidSwitchChannel & err)
{
@ -834,9 +915,9 @@ struct KhompPvtFXS: public KhompPvt
_ring_off_ext = -1;
_incoming_exten.clear();
_flash_transfer.clear();
//_flash_transfer.clear();
_uuid_other_session.clear();
//_uuid_other_session.clear();
return Call::clear();
}
@ -850,10 +931,10 @@ struct KhompPvtFXS: public KhompPvt
std::string _incoming_exten;
ChanTimer::Index _idx_transfer;
//ChanTimer::Index _idx_transfer;
std::string _flash_transfer;
std::string _uuid_other_session;
//std::string _flash_transfer;
//std::string _uuid_other_session;
};
@ -936,9 +1017,9 @@ struct KhompPvtFXS: public KhompPvt
std::string extra_context = "");
bool isOK(void);
bool startTransfer();
bool stopTransfer();
bool transfer(std::string & context, bool blind = false);
//bool startTransfer();
//bool stopTransfer();
//bool transfer(std::string & context, bool blind = false);
bool hasNumberDial() { return false; }
@ -996,7 +1077,7 @@ struct KhompPvtFXS: public KhompPvt
static OrigToNseqMapType generateNseqMap();
static void dialTimer(KhompPvt * pvt);
static void transferTimer(KhompPvt * pvt);
//static void transferTimer(KhompPvt * pvt);
static std::string padOrig(std::string orig_base, unsigned int padding)
{
@ -1015,21 +1096,16 @@ struct KhompPvtFXS: public KhompPvt
return STG(FMT(STG(FMT("%%0%dd") % orig_size)) % (orig_numb + padding));
}
/*
virtual void getSpecialVariables()
void cleanupIndications(bool force)
{
try
if (call()->_indication == INDICA_BUSY && !force)
{
}
catch(Board::KhompPvt::InvalidSwitchChannel & err)
{
LOG(ERROR, PVT_FMT(_target, "(FXS) %s") % err._msg.c_str());
DBG(FUNC, PVT_FMT(_target, "skipping busy indication cleanup on FXS channel."));
return;
}
KhompPvt::getSpecialVariables();
KhompPvt::cleanupIndications(force);
}
*/
};
/******************************************************************************/
/******************************************************************************/

View File

@ -108,10 +108,13 @@ struct Options
Config::Value< bool > _recording;
Config::Value< bool > _has_ctbus;
Config::Value< bool > _fxs_bina;
Config::Value< bool > _fxo_send_pre_audio;
Config::Value< bool > _fxs_sharp_dial;
Config::Value< bool > _drop_collect_call;
Config::Value< bool > _ignore_letter_dtmfs;
Config::Value< bool > _optimize_audio_path;
Config::Value< bool > _fxo_send_pre_audio;
Config::Value< unsigned int > _fxo_busy_disconnection;
Config::Value< bool > _auto_fax_adjustment;
Config::Value< unsigned int > _fax_adjustment_timeout;

View File

@ -1 +1 @@
#define MOD_KHOMP_VERSION "1.0 - (rev: 5891)"
#define MOD_KHOMP_VERSION "1.0 - (rev: 6034)"

View File

@ -75,6 +75,7 @@ void Cli::registerCommands(APIFunc func,switch_loadable_module_interface_t **mod
" khomp channels unblock {all | <board> all | <board> <channel>}\n" \
" khomp clear links [<board> [<link>]]\n" \
" khomp clear statistics [<board> [<channel>]]\n" \
" khomp dump config\n" \
" khomp get <option>\n" \
" khomp kommuter {on|off}\n" \
" khomp kommuter count\n" \
@ -128,6 +129,10 @@ void Cli::registerCommands(APIFunc func,switch_loadable_module_interface_t **mod
/* is responsible for parse and execute all commands */
bool Cli::parseCommands(int argc, char *argv[])
{
/*
* DEBUG_CLI_CMD();
*/
/* khomp summary */
if (ARG_CMP(0, "summary"))
return EXEC_CLI_CMD(Cli::KhompSummary);
@ -163,7 +168,15 @@ bool Cli::parseCommands(int argc, char *argv[])
if(ARG_CMP(1, "statistics"))
return EXEC_CLI_CMD(Cli::KhompClearStatistics);
}
/* khomp dump */
else if(ARG_CMP(0, "dump"))
{
/* khomp dump config */
if(ARG_CMP(1, "config"))
return EXEC_CLI_CMD(Cli::KhompDumpConfig);
}
/* khomp reset */
else if(ARG_CMP(0, "reset"))
{
@ -285,6 +298,7 @@ Cli::_KhompShowChannels Cli::KhompShowChannels;
Cli::_KhompShowLinks Cli::KhompShowLinks;
Cli::_KhompShowStatistics Cli::KhompShowStatistics;
Cli::_KhompClearLinks Cli::KhompClearLinks;
Cli::_KhompDumpConfig Cli::KhompDumpConfig;
Cli::_KhompClearStatistics Cli::KhompClearStatistics;
Cli::_KhompResetLinks Cli::KhompResetLinks;
Cli::_KhompChannelsDisconnect Cli::KhompChannelsDisconnect;
@ -337,7 +351,9 @@ bool Cli::_KhompSummary::execute(int argc, char *argv[])
K::Logger::Logg2(classe, stream, "|------------------------------------------------------------------|");
}
if (k3lGetDeviceConfig(-1, ksoAPI, &apiCfg, sizeof(apiCfg)) == ksSuccess)
const bool running = (k3lGetDeviceConfig(-1, ksoAPI, &apiCfg, sizeof(apiCfg)) == ksSuccess);
if(running)
{
switch(output_type)
{
@ -376,6 +392,28 @@ bool Cli::_KhompSummary::execute(int argc, char *argv[])
break;
}
}
else
{
switch(output_type)
{
case Cli::VERBOSE:
{
K::Logger::Logg2(classe, stream, "| Connection to KServer broken, please check system logs! |");
} break;
case Cli::CONCISE:
{
K::Logger::Logg2(classe, stream, "CONNECTION BROKEN");
} break;
case Cli::XML:
{
/* summary/k3lapi */
switch_xml_t xk3lapi = switch_xml_add_child_d(root, "k3lapi",0);
switch_xml_set_txt_d(xk3lapi, "CONNECTION BROKEN");
} break;
}
}
#ifndef MOD_KHOMP_VERSION
#define MOD_KHOMP_VERSION "unknown"
@ -423,6 +461,20 @@ bool Cli::_KhompSummary::execute(int argc, char *argv[])
break;
}
if(!running)
{
if (output_type == Cli::VERBOSE)
K::Logger::Logg2(classe,stream, " ------------------------------------------------------------------");
if (output_type == Cli::XML)
{
printXMLOutput(stream);
clearRoot();
}
return false;
}
if (output_type == Cli::XML)
{
/* summary/board */
@ -2154,6 +2206,38 @@ bool Cli::_KhompClearStatistics::execute(int argc, char *argv[])
return true;
}
bool Cli::_KhompDumpConfig::execute(int argc, char *argv[])
{
if (argc != 2)
{
printUsage(stream);
return false;
}
const Config::StringSet opts = Globals::options.options();
K::Logger::Logg2(C_CLI, stream, " ------------------------------------------------------------------------");
K::Logger::Logg2(C_CLI, stream, "|--------------------------- Khomp Options Dump -------------------------|");
K::Logger::Logg2(C_CLI, stream, "|------------------------------------------------------------------------|");
for (Config::StringSet::const_iterator itr = opts.begin(); itr != opts.end(); ++itr)
{ try
{
if(removeUnavaible((*itr))) continue;
K::Logger::Logg2(C_CLI, stream, FMT("| %-24s => %42s |")
% (*itr) % Globals::options.get(&(Opt::_options), (*itr)));
}
catch(Config::EmptyValue &e)
{
K::Logger::Logg(C_ERROR, FMT("%s (%s)") % e.what() % (*itr));
}
}
K::Logger::Logg2(C_CLI, stream, " ------------------------------------------------------------------------");
return true;
}
void Cli::_KhompResetLinks::resetLink(unsigned int device, unsigned int link)
{
try
@ -2718,10 +2802,18 @@ bool Cli::_KhompSet::execute(int argc, char *argv[])
try
{
Globals::options.process(&Opt::_options, (const char *) argv[1], (const char *) args.c_str());
const Config::Options::Messages msgs = Globals::options.commit(&Opt::_options, (const char *)argv[1]);
for (Config::Options::Messages::const_iterator i = msgs.begin(); i != msgs.end(); ++i)
{
K::Logger::Logg2(C_ERROR, stream, FMT("%s.") % (*i));
}
K::Logger::Logg2(C_CLI, stream, FMT("Setting %s for value %s") % argv[1] % argv[2]);
}
catch (Config::Failure &e)
{
K::Logger::Logg2(C_CLI,stream, FMT("config processing error: %s.") % e.what());
K::Logger::Logg2(C_ERROR,stream, FMT("config processing error: %s.") % e.what());
}
return true;
@ -2891,7 +2983,6 @@ bool Cli::_KhompSelectSim::execute(int argc, char *argv[])
K::Logger::Logg2(C_CLI, stream, "ERROR: Unable to select sim card");
return false;
}
}
catch (Strings::invalid_value & e)
{

View File

@ -1119,12 +1119,7 @@ bool Board::KhompPvt::cleanup(CleanupType type)
/* pára cadências e limpa estado das flags */
stopCadence();
if (call()->_indication != INDICA_NONE)
{
call()->_indication = INDICA_NONE;
mixer(KHOMP_LOG, 1, kmsGenerator, kmtSilence);
}
cleanupIndications(true);
if(call()->_input_volume >= -10 && call()->_input_volume <= 10)
setVolume("input" , Opt::_options._input_volume());
@ -1152,6 +1147,15 @@ bool Board::KhompPvt::cleanup(CleanupType type)
return true;
}
void Board::KhompPvt::cleanupIndications(bool force)
{
if (call()->_indication != INDICA_NONE)
{
call()->_indication = INDICA_NONE;
mixer(KHOMP_LOG, 1, kmsGenerator, kmtSilence);
}
}
bool Board::KhompPvt::isFree(bool just_phy)
{
//DBG(FUNC, DP(this, "c"));
@ -1168,28 +1172,6 @@ bool Board::KhompPvt::isFree(bool just_phy)
if(session())
return false;
/*
if (!is_gsm())
{
if (calls.at(0).owner != NULL)
{
DBG(FUNC, DP(this, "we have owner, not free!"));
return false;
}
}
else
{
for (int i = 0; i < 6; i++)
{
call_data_type & data = calls.at(i);
if (data.owner != NULL)
return false;
}
}
*/
bool free_state = !(_call->_flags.check(Kflags::IS_INCOMING) || _call->_flags.check(Kflags::IS_OUTGOING));
DBG(FUNC, PVT_FMT(target(), "[free = %s]") % (free_state ? "yes" : "no"));
@ -1559,7 +1541,7 @@ bool Board::KhompPvt::echoCancellation(bool enable)
bool Board::KhompPvt::autoGainControl(bool enable)
{
bool ret = command(KHOMP_LOG,(enable ? CM_ENABLE_AGC : CM_DISABLE_AGC));//, SCE_SHOW_DEBUG);
bool ret = command(KHOMP_LOG,(enable ? CM_ENABLE_AGC : CM_DISABLE_AGC));
return ret;
}
@ -1625,10 +1607,11 @@ bool Board::KhompPvt::setCollectCall()
DBG(FUNC, PVT_FMT(_target, "option drop collect call is '%s'") % (Opt::_options._drop_collect_call() ? "yes" : "no"));
// get global filter configuration value
tmp_var = switch_core_get_variable_dup("KDropCollectCall");
tmp_var = getFSGlobalVar("KDropCollectCall");
confvalues.push_back(getTriStateValue(tmp_var));
DBG(FUNC, PVT_FMT(_target, "global KDropCollectCall was '%s'") % (tmp_var ? tmp_var : "(empty)"));
switch_safe_free(tmp_var);
freeFSGlobalVar(&tmp_var);
try
{
@ -2052,6 +2035,7 @@ bool Board::KhompPvt::onNoAnswer(K3L_EVENT *e)
DBG(FUNC, PVT_FMT(_target, "Detected: \"%s\"") % Verbose::callStartInfo((KCallStartInfo)e->AddInfo).c_str());
// Fire a custom event about this
/* MUST USE THE NEW EVENT SYSTEM
switch_event_t * event;
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, KHOMP_EVENT_MAINT) == SWITCH_STATUS_SUCCESS)
{
@ -2062,6 +2046,8 @@ bool Board::KhompPvt::onNoAnswer(K3L_EVENT *e)
switch_event_fire(&event);
}
*/
return true;
}

View File

@ -715,37 +715,47 @@ bool BoardFXO::KhompPvtFXO::indicateBusyUnlocked(int cause, bool sent_signaling)
if(call()->_flags.check(Kflags::IS_INCOMING))
{
/* already connected or sent signaling... */
mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
if(!call()->_flags.check(Kflags::CONNECTED) && !sent_signaling)
{
//we are talking about branches, not trunks
/* we are talking about branches, not trunks */
command(KHOMP_LOG, CM_CONNECT);
command(KHOMP_LOG, CM_DISCONNECT);
}
else
{
//already connected or sent signaling...
mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
callFXO()->_busy_disconnect = Board::board(_target.device)->_timers.add(Opt::_options._fxo_busy_disconnection(), &BoardFXO::KhompPvtFXO::busyDisconnect, this);
}
}
else if(call()->_flags.check(Kflags::IS_OUTGOING))
{
//already connected or sent signaling...
/* already connected or sent signaling... */
mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
}
DBG(FUNC,PVT_FMT(_target, "(FXO) r"));
return true;
}
void BoardFXO::KhompPvtFXO::busyDisconnect(Board::KhompPvt * pvt)
{
DBG(FUNC, PVT_FMT(pvt->target(), "Disconnecting FXO"));
try
{
ScopedPvtLock lock(pvt);
pvt->command(KHOMP_LOG, CM_DISCONNECT);
}
catch (...)
{
LOG(ERROR, PVT_FMT(pvt->target(), "unable to lock the pvt !"));
}
}
void BoardFXO::KhompPvtFXO::reportFailToReceive(int fail_code)
{
KhompPvt::reportFailToReceive(fail_code);
command(KHOMP_LOG, CM_CONNECT);
command(KHOMP_LOG, CM_DISCONNECT);
}
bool BoardFXO::KhompPvtFXO::validContexts(

View File

@ -312,6 +312,9 @@ int BoardGSM::KhompPvtGSM::makeCall(std::string params)
command(KHOMP_LOG, CM_DISABLE_CALL_ANSWER_INFO);
}
if(!_call->_orig_addr.compare("restricted"))
params += " orig_addr=\"restricted\"";
int ret = KhompPvt::makeCall(params);
if(ret != ksSuccess)

View File

@ -372,18 +372,37 @@ bool BoardE1::onLinkStatus(K3L_EVENT *e)
bool BoardE1::KhompPvtISDN::onSyncUserInformation(K3L_EVENT *e)
{
KUserInformation * info = (KUserInformation *) (((char*)e) + sizeof(K3L_EVENT));
DBG(FUNC,PVT_FMT(_target, "Synchronizing"));
callISDN()->_uui_descriptor = info->ProtocolDescriptor;
if(callISDN()->_uui_extended)
{
KUserInformationEx * info = (KUserInformationEx *) (((char*)e) + sizeof(K3L_EVENT));
callISDN()->_uui_descriptor = (long int) info->ProtocolDescriptor;
/* clean string */
callISDN()->_uui_information.clear();
/* clean string */
callISDN()->_uui_information.clear();
if (info->UserInfoLength)
{
/* append to a clean string */
for (unsigned int i = 0; i < info->UserInfoLength; ++i)
callISDN()->_uui_information += STG(FMT("%02hhx") % ((unsigned char) info->UserInfo[i]));
}
}
else
{
KUserInformation * info = (KUserInformation *) (((char*)e) + sizeof(K3L_EVENT));
callISDN()->_uui_descriptor = info->ProtocolDescriptor;
/* clean string */
callISDN()->_uui_information.clear();
if (info->UserInfoLength)
{
/* append to a clean string */
callISDN()->_uui_information.append((const char *)info->UserInfo, info->UserInfoLength);
}
if (info->UserInfoLength)
{
for (unsigned int i = 0; i < info->UserInfoLength; ++i)
callISDN()->_uui_information += STG(FMT("%02hhx") % ((unsigned char) info->UserInfo[i]));
}
}
return true;
}
@ -440,15 +459,20 @@ bool BoardE1::KhompPvtISDN::onNewCall(K3L_EVENT *e)
bool isdn_reverse_charge = false;
std::string isdn_reverse_charge_str;
bool ret;
try
{
callISDN()->_isdn_orig_type_of_number = Globals::k3lapi.get_param(e, "isdn_orig_type_of_number");
callISDN()->_isdn_orig_numbering_plan = Globals::k3lapi.get_param(e, "isdn_orig_numbering_plan");
callISDN()->_isdn_dest_type_of_number = Globals::k3lapi.get_param(e, "isdn_dest_type_of_number");
callISDN()->_isdn_dest_numbering_plan = Globals::k3lapi.get_param(e, "isdn_dest_numbering_plan");
callISDN()->_isdn_orig_presentation = Globals::k3lapi.get_param(e, "isdn_orig_presentation");
isdn_reverse_charge_str = Globals::k3lapi.get_param(e, "isdn_reverse_charge");
isdn_reverse_charge = Strings::toboolean(isdn_reverse_charge_str);
}
catch(K3LAPI::get_param_failed & err)
{
/* do nothing, maybe the parameter is not sent */
LOG(WARNING, PVT_FMT(_target, "maybe the parameter is not sent (%s)'") % err.name.c_str());
}
catch (Strings::invalid_value & err)
{
@ -866,25 +890,84 @@ int BoardE1::KhompPvtISDN::makeCall(std::string params)
DBG(FUNC,PVT_FMT(_target, "got userinfo"));
/* grab this information first, avoiding latter side-effects */
const char * info_data = call->_uui_information.c_str();
size_t info_size = std::min(call->_uui_information.size(), (size_t)KMAX_USER_USER_LEN);
const bool info_extd = call->_uui_extended;
const long int info_desc = call->_uui_descriptor;
const std::string info_data = call->_uui_information.c_str();
const size_t info_size = std::min<size_t>(call->_uui_information.size(), (info_extd ? KMAX_USER_USER_EX_LEN : KMAX_USER_USER_LEN) << 1) >> 1;
KUserInformation info;
info.ProtocolDescriptor = call->_uui_descriptor;
info.UserInfoLength = info_size;
memcpy((void *) info.UserInfo, (const void *) info_data, info_size);
if (!command(KHOMP_LOG, CM_USER_INFORMATION, (const char *)&info))
bool res = true;
if(info_extd)
{
LOG(ERROR,PVT_FMT(_target, "UUI could not be sent before dialing!"));
KUserInformationEx info;
info.ProtocolDescriptor = info_desc;
info.UserInfoLength = info_size;
for (unsigned int pos = 0u, index = 0u; pos < info_size; index+=2, ++pos)
info.UserInfo[pos] = (unsigned char)Strings::toulong(info_data.substr(index,2), 16);
if (!command(KHOMP_LOG, CM_USER_INFORMATION_EX, (const char *) &info))
{
LOG(ERROR,PVT_FMT(_target, "UUI could not be sent before dialing!"));
}
}
else
{
KUserInformation info;
info.ProtocolDescriptor = info_desc;
info.UserInfoLength = info_size;
for (unsigned int pos = 0u, index = 0u; pos < info_size; index+=2, ++pos)
info.UserInfo[pos] = (unsigned char)Strings::toulong(info_data.substr(index,2), 16);
if (!command(KHOMP_LOG, CM_USER_INFORMATION, (const char *) &info))
{
LOG(ERROR,PVT_FMT(_target, "UUI could not be sent before dialing!"));
}
}
call->_uui_extended = false;
call->_uui_descriptor = -1;
call->_uui_information.clear();
}
if (!callISDN()->_isdn_orig_type_of_number.empty())
{
params += "isdn_orig_type_of_number=\"";
params += callISDN()->_isdn_orig_type_of_number;
params += "\" ";
}
if (!callISDN()->_isdn_dest_type_of_number.empty())
{
params += "isdn_dest_type_of_number=\"";
params += callISDN()->_isdn_dest_type_of_number;
params += "\" ";
}
if (!callISDN()->_isdn_orig_numbering_plan.empty())
{
params += "isdn_orig_numbering_plan=\"";
params += callISDN()->_isdn_orig_numbering_plan;
params += "\" ";
}
if (!callISDN()->_isdn_dest_numbering_plan.empty())
{
params += "isdn_dest_numbering_plan=\"";
params += callISDN()->_isdn_dest_numbering_plan;
params += "\" ";
}
if (!callISDN()->_isdn_orig_presentation.empty())
{
params += "isdn_orig_presentation=\"";
params += callISDN()->_isdn_orig_presentation;
params += "\" ";
}
int ret = KhompPvtE1::makeCall(params);
call->_cleanup_upon_hangup = (ret == ksInvalidParams || ret == ksBusy);
@ -995,12 +1078,6 @@ bool BoardE1::KhompPvtR2::doChannelAnswer(CommandRequest &cmd)
// is this a collect call?
bool has_recv_collect_call = _call->_collect_call;
if(has_recv_collect_call)
DBG(FUNC, PVT_FMT(target(), "receive a collect call"));
if(call()->_flags.check(Kflags::DROP_COLLECT))
DBG(FUNC, PVT_FMT(target(), "flag DROP_COLLECT == true"));
// do we have to drop collect calls?
bool has_drop_collect_call = call()->_flags.check(Kflags::DROP_COLLECT);
@ -1013,29 +1090,37 @@ bool BoardE1::KhompPvtR2::doChannelAnswer(CommandRequest &cmd)
if(do_send_ring)
{
call()->_flags.clear(Kflags::NEEDS_RINGBACK_CMD);
//TODO: callFailFromCause ??
std::string cause = ( do_drop_call ? STG(FMT("r2_cond_b=\"%d\"") % kgbBusy) : "" );
command(KHOMP_LOG,CM_RINGBACK,cause.c_str());
usleep(75000);
}
if(!(do_drop_call && do_send_ring))
if(!do_drop_call)
{
command(KHOMP_LOG, CM_CONNECT);
}
if(has_drop_collect_call && !do_send_ring)
if(!do_send_ring && has_drop_collect_call)
{
usleep(75000);
if(has_recv_collect_call)
{
usleep(75000);
DBG(FUNC, PVT_FMT(target(), "disconnecting collect call doChannelAnswer R2"));
command(KHOMP_LOG,CM_DISCONNECT);
// thou shalt not talk anymore!
stopListen();
stopStream();
if (call()->_indication == INDICA_NONE)
{
call()->_indication = INDICA_BUSY;
mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
}
DBG(FUNC, PVT_FMT(_target,"forcing disconnect for collect call"));
forceDisconnect();
}
else
{
@ -1797,6 +1882,8 @@ bool BoardE1::KhompPvtR2::onNewCall(K3L_EVENT *e)
DBG(FUNC,PVT_FMT(_target, "Setting DROP_COLLECT flag"));
}
freeFSGlobalVar(&drop_str);
// keeping the hardcore mode
if (do_drop_collect && call()->_collect_call)
{
@ -2388,6 +2475,7 @@ void BoardE1::KhompPvtFXS::dialTimer(KhompPvt * pvt)
}
/*
void BoardE1::KhompPvtFXS::transferTimer(KhompPvt * pvt)
{
DBG(FUNC, PVT_FMT(pvt->target(), "c"));
@ -2420,7 +2508,7 @@ void BoardE1::KhompPvtFXS::transferTimer(KhompPvt * pvt)
return;
}
/* begin context adjusting + processing */
// begin context adjusting + processing
MatchExtension::ContextListType contexts;
pvt_fxs->validContexts(contexts);
@ -2469,6 +2557,7 @@ void BoardE1::KhompPvtFXS::transferTimer(KhompPvt * pvt)
DBG(FUNC, PVT_FMT(pvt->target(), "r"));
}
*/
bool BoardE1::KhompPvtFXS::onChannelRelease(K3L_EVENT *e)
{
@ -2480,22 +2569,23 @@ bool BoardE1::KhompPvtFXS::onChannelRelease(K3L_EVENT *e)
{
ScopedPvtLock lock(this);
/*
if(!callFXS()->_uuid_other_session.empty() && session())
{
/*
switch_core_session_t *hold_session;
//switch_core_session_t *hold_session;
if ((hold_session = switch_core_session_locate(callFXS()->_uuid_other_session.c_str())))
{
switch_channel_t * hold = switch_core_session_get_channel(hold_session);
switch_channel_stop_broadcast(hold);
switch_channel_wait_for_flag(hold, CF_BROADCAST, SWITCH_FALSE, 5000, NULL);
switch_core_session_rwunlock(hold_session);
}
*/
//if ((hold_session = switch_core_session_locate(callFXS()->_uuid_other_session.c_str())))
//{
// switch_channel_t * hold = switch_core_session_get_channel(hold_session);
// switch_channel_stop_broadcast(hold);
// switch_channel_wait_for_flag(hold, CF_BROADCAST, SWITCH_FALSE, 5000, NULL);
// switch_core_session_rwunlock(hold_session);
//}
try
{
/* get other side of the bridge */
// get other side of the bridge
switch_core_session_t * peer_session = getFSLockedPartnerSession();
unlockPartner(peer_session);
DBG(FUNC, PVT_FMT(target(), "bridge with the new session"));
@ -2509,6 +2599,7 @@ bool BoardE1::KhompPvtFXS::onChannelRelease(K3L_EVENT *e)
callFXS()->_uuid_other_session.clear();
}
*/
ret = KhompPvt::onChannelRelease(e);
@ -2523,7 +2614,7 @@ bool BoardE1::KhompPvtFXS::onChannelRelease(K3L_EVENT *e)
return ret;
}
/*
bool BoardE1::KhompPvtFXS::startTransfer()
{
DBG(FUNC, PVT_FMT(target(), "c"));
@ -2596,7 +2687,7 @@ bool BoardE1::KhompPvtFXS::stopTransfer()
try
{
/* get other side of the bridge */
// get other side of the bridge
switch_core_session_t * peer_session = getFSLockedPartnerSession();
switch_channel_t * peer_channel = getFSChannel(peer_session);
@ -2664,33 +2755,33 @@ static switch_status_t xferHook(switch_core_session_t *session)
else if (state == CS_HANGUP)
{
switch_core_event_hook_remove_state_change(session, xferHook);
/*
BoardE1::KhompPvtFXS * pvt = static_cast<BoardE1::KhompPvtFXS*>(switch_core_session_get_private(session));
if(!pvt)
{
DBG(FUNC, D("pvt is NULL"));
return SWITCH_STATUS_FALSE;
}
try
{
ScopedPvtLock lock(pvt);
//BoardE1::KhompPvtFXS * pvt = static_cast<BoardE1::KhompPvtFXS*>(switch_core_session_get_private(session));
//
//if(!pvt)
//{
// DBG(FUNC, D("pvt is NULL"));
// return SWITCH_STATUS_FALSE;
//}
if(!pvt->callFXS()->_uuid_other_session.empty())
{
DBG(FUNC, D("bridge after hangup"));
std::string number = pvt->callFXS()->_uuid_other_session;
pvt->callFXS()->_uuid_other_session.clear();
//try
//{
// ScopedPvtLock lock(pvt);
// if(!pvt->callFXS()->_uuid_other_session.empty())
// {
// DBG(FUNC, D("bridge after hangup"));
// std::string number = pvt->callFXS()->_uuid_other_session;
// pvt->callFXS()->_uuid_other_session.clear();
// switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), number.c_str());
// }
//}
//catch(ScopedLockFailed & err)
//{
// LOG(ERROR, PVT_FMT(pvt->target(), "unable to lock: %s!") % err._msg.c_str());
//}
switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), number.c_str());
}
}
catch(ScopedLockFailed & err)
{
LOG(ERROR, PVT_FMT(pvt->target(), "unable to lock: %s!") % err._msg.c_str());
}
*/
}
return SWITCH_STATUS_SUCCESS;
@ -2716,7 +2807,7 @@ bool BoardE1::KhompPvtFXS::transfer(std::string & context, bool blind)
try
{
/* get other side of the bridge */
// get other side of the bridge
switch_core_session_t * peer_session = getFSLockedPartnerSession();
switch_channel_t * peer_channel = getFSChannel(peer_session);
@ -2774,16 +2865,16 @@ bool BoardE1::KhompPvtFXS::transfer(std::string & context, bool blind)
call()->_flags.set(Kflags::GEN_CO_RING);
startCadence(PLAY_RINGBACK);
/*
try
{
call()->_idx_co_ring = Board::board(_target.device)->_timers.add(Opt::_options._ringback_co_delay(), &Board::KhompPvt::coRingGen,this);
}
catch (K3LAPITraits::invalid_device & err)
{
LOG(ERROR, PVT_FMT(_target, "unable to get device: %d!") % err.device);
}
*/
//try
//{
// call()->_idx_co_ring = Board::board(_target.device)->_timers.add(Opt::_options._ringback_co_delay(), &Board::KhompPvt::coRingGen,this);
//}
//catch (K3LAPITraits::invalid_device & err)
//{
// LOG(ERROR, PVT_FMT(_target, "unable to get device: %d!") % err.device);
//}
}
}
catch(Board::KhompPvt::InvalidSwitchChannel & err)
@ -2796,6 +2887,7 @@ bool BoardE1::KhompPvtFXS::transfer(std::string & context, bool blind)
return true;
}
*/
bool BoardE1::KhompPvtFXS::onDtmfDetected(K3L_EVENT *e)
{
@ -2902,6 +2994,7 @@ bool BoardE1::KhompPvtFXS::onDtmfDetected(K3L_EVENT *e)
break;
}
}
/*
else if(callFXS()->_flags.check(Kflags::FXS_OFFHOOK) &&
callFXS()->_flags.check(Kflags::FXS_FLASH_TRANSFER))
{
@ -2922,7 +3015,7 @@ bool BoardE1::KhompPvtFXS::onDtmfDetected(K3L_EVENT *e)
callFXS()->_flash_transfer += e->AddInfo;
/* begin context adjusting + processing */
// begin context adjusting + processing
MatchExtension::ContextListType contexts;
validContexts(contexts);
@ -2949,7 +3042,7 @@ bool BoardE1::KhompPvtFXS::onDtmfDetected(K3L_EVENT *e)
case MatchExtension::MATCH_MORE:
DBG(FUNC, PVT_FMT(target(), "match more..."));
/* can match, will match more, and it's an external call? */
// can match, will match more, and it's an external call?
for (DestVectorType::const_iterator i = Opt::_options._fxs_co_dialtone().begin(); i != Opt::_options._fxs_co_dialtone().end(); i++)
{
if (callFXS()->_flash_transfer == (*i))
@ -2975,6 +3068,7 @@ bool BoardE1::KhompPvtFXS::onDtmfDetected(K3L_EVENT *e)
}
}
}
*/
else
{
ret = KhompPvt::onDtmfDetected(e);
@ -3042,6 +3136,7 @@ bool BoardE1::KhompPvtFXS::onFlashDetected(K3L_EVENT *e)
/******************************************************************************/
//Old implementation, not used
/*
if(callFXS()->_flags.check(Kflags::FXS_FLASH_TRANSFER))
{
DBG(FUNC, PVT_FMT(_target, "(FXS) transfer canceled"));
@ -3078,6 +3173,7 @@ bool BoardE1::KhompPvtFXS::onFlashDetected(K3L_EVENT *e)
DBG(FUNC, PVT_FMT(target(), "(FXS) r (unable to start transfer)"));
return false;
}
*/
/******************************************************************************/
}
@ -3207,7 +3303,8 @@ bool BoardE1::KhompPvtFXS::doChannelHangup(CommandRequest &cmd)
try
{
ScopedPvtLock lock(this);
/*
if(!callFXS()->_uuid_other_session.empty())
{
DBG(FUNC,PVT_FMT(_target, "unable to transfer"));
@ -3225,6 +3322,7 @@ bool BoardE1::KhompPvtFXS::doChannelHangup(CommandRequest &cmd)
}
callFXS()->_uuid_other_session.clear();
}
*/
if (call()->_flags.check(Kflags::IS_INCOMING))
{

View File

@ -75,11 +75,14 @@ void Opt::initialize(void)
Globals::options.add(Config::Option("recording", &Options::_recording, true));
Globals::options.add(Config::Option("has-ctbus", &Options::_has_ctbus, false));
Globals::options.add(Config::Option("fxs-bina", &Options::_fxs_bina, true));
Globals::options.add(Config::Option("fxo-send-pre-audio", &Options::_fxo_send_pre_audio, true));
Globals::options.add(Config::Option("fxs-sharp-dial", &Options::_fxs_sharp_dial, true));
Globals::options.add(Config::Option("drop-collect-call", &Options::_drop_collect_call, false));
Globals::options.add(Config::Option("ignore-letter-dtmfs", &Options::_ignore_letter_dtmfs, true));
Globals::options.add(Config::Option("optimize-audio-path", &Options::_optimize_audio_path, false));
Globals::options.add(Config::Option("fxo-send-pre-audio", &Options::_fxo_send_pre_audio, true));
Globals::options.add(Config::Option("fxo-busy-disconnection", &Options::_fxo_busy_disconnection, 1250u, 50u, 90000u));
Globals::options.add(Config::Option("auto-fax-adjustment", &Options::_auto_fax_adjustment, true));
Globals::options.add(Config::Option("fax-adjustment-timeout", &Options::_fax_adjustment_timeout, 30u, 3u, 9999u));

View File

@ -78,8 +78,6 @@ static SpecRetType processSpecAtom(std::string & atom, SpecFlagsType & flags, Sp
return processSpecAtoms(allocstr, flags, fun);
}
//Regex::Expression e("(((([bB])[ ]*([0-9]+))|(([sS])[ ]*([0-9]+)))[ ]*(([cClL])[ ]*([0-9]+)[ ]*([-][ ]*([0-9]+))?)?)|(([rR])[ ]*([0-9]+)[ ]*([-][ ]*([0-9]+))?)", Regex::E_EXTENDED);
Regex::Match what(allocstr, Globals::regex_allocation);
if (!what.matched())

View File

@ -244,21 +244,26 @@ bool MatchExtension::canMatch(std::string & context, std::string & exten,
return true;
}
size_t finished = exten.find('#');
if(finished != std::string::npos)
if (Opt::_options._fxs_sharp_dial())
{
if(exten.size() <= 1)
char key_digit = '#';
size_t finished = exten.find_last_of(key_digit);
char last_char = exten.at(exten.size() - 1);
if(finished != std::string::npos && last_char == key_digit)
{
DBG(FUNC, FMT("exten=%s size=%d") % exten % exten.size());
return true;
if(exten.size() <= 1)
{
DBG(FUNC, FMT("exten=%s size=%d") % exten % exten.size());
return true;
}
exten.erase(finished);
DBG(FUNC, FMT("match exact!!! exten=%s") % exten);
return false;
}
exten.erase(finished);
DBG(FUNC, FMT("match exact!!! exten=%s") % exten);
return false;
}
return true;
/*

View File

@ -96,8 +96,10 @@ typedef struct private_object private_object_t;
#define SOFIA_MULTIPART_PREFIX_T "~sip_mp_"
#define SOFIA_SIP_HEADER_PREFIX "sip_h_"
#define SOFIA_SIP_RESPONSE_HEADER_PREFIX "sip_rh_"
#define SOFIA_SIP_RESPONSE_HEADER_PREFIX_T "~sip_rh_"
#define SOFIA_SIP_BYE_HEADER_PREFIX "sip_bye_h_"
#define SOFIA_SIP_PROGRESS_HEADER_PREFIX "sip_ph_"
#define SOFIA_SIP_PROGRESS_HEADER_PREFIX_T "~sip_ph_"
#define SOFIA_SIP_HEADER_PREFIX_T "~sip_h_"
#define SOFIA_DEFAULT_PORT "5060"
#define SOFIA_DEFAULT_TLS_PORT "5061"
@ -587,6 +589,8 @@ struct private_object {
sofia_private_t *sofia_private;
uint8_t flags[TFLAG_MAX];
switch_payload_t agreed_pt;
switch_payload_t audio_recv_pt;
switch_payload_t video_recv_pt;
switch_core_session_t *session;
switch_channel_t *channel;
switch_frame_t read_frame;

View File

@ -2148,8 +2148,13 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
if (!zstr(from_domain)) {
gateway->from_domain = switch_core_strdup(gateway->pool, from_domain);
}
if (!zstr(register_transport) && !switch_stristr("transport=", proxy)) {
gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s;transport=%s", proxy, register_transport);
} else {
gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s", proxy);
}
gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s", proxy);
gateway->register_from = switch_core_sprintf(gateway->pool, "<sip:%s@%s;transport=%s>",
from_user, !zstr(from_domain) ? from_domain : proxy, register_transport);
@ -4142,7 +4147,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
if ((status == 180 || status == 183 || status == 200)) {
const char *x_freeswitch_support;
const char *x_freeswitch_support, *vval;
switch_channel_set_flag(channel, CF_MEDIA_ACK);
@ -4156,7 +4161,26 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
switch_channel_set_variable(channel, "sip_user_agent", sip->sip_server->g_string);
}
sofia_glue_set_extra_headers(channel, sip, SOFIA_SIP_PROGRESS_HEADER_PREFIX);
if (status == 200) {
sofia_glue_set_extra_headers(channel, sip, SOFIA_SIP_RESPONSE_HEADER_PREFIX);
} else {
sofia_glue_set_extra_headers(channel, sip, SOFIA_SIP_PROGRESS_HEADER_PREFIX);
}
if (!(vval = switch_channel_get_variable(channel, "sip_copy_custom_headers")) || switch_true(vval)) {
switch_core_session_t *other_session;
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
if (status == 200) {
switch_ivr_transfer_variable(session, other_session, SOFIA_SIP_RESPONSE_HEADER_PREFIX_T);
} else {
switch_ivr_transfer_variable(session, other_session, SOFIA_SIP_PROGRESS_HEADER_PREFIX_T);
}
switch_core_session_rwunlock(other_session);
}
}
sofia_update_callee_id(session, profile, sip, SWITCH_FALSE);

View File

@ -826,6 +826,8 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
tech_pvt->recv_te = tech_pvt->te = profile->te;
}
tech_pvt->dtmf_type = tech_pvt->profile->dtmf_type;
if (!sofia_test_pflag(tech_pvt->profile, PFLAG_SUPPRESS_CNG)) {
if (tech_pvt->bcng_pt) {
tech_pvt->cng_pt = tech_pvt->bcng_pt;
@ -836,6 +838,7 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
tech_pvt->session = session;
tech_pvt->channel = switch_core_session_get_channel(session);
sofia_glue_check_dtmf_type(tech_pvt);
switch_channel_set_cap(tech_pvt->channel, CC_MEDIA_ACK);
switch_channel_set_cap(tech_pvt->channel, CC_BYPASS_MEDIA);
switch_channel_set_cap(tech_pvt->channel, CC_PROXY_MEDIA);
@ -3234,6 +3237,11 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
switch_rtp_set_telephony_recv_event(tech_pvt->rtp_session, tech_pvt->recv_te);
}
if (tech_pvt->audio_recv_pt != tech_pvt->agreed_pt) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_CRIT, "Set audio receive payload to %u\n", tech_pvt->audio_recv_pt);
switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->audio_recv_pt);
}
if (sofia_test_pflag(tech_pvt->profile, PFLAG_SUPPRESS_CNG) ||
((val = switch_channel_get_variable(tech_pvt->channel, "supress_cng")) && switch_true(val)) ||
((val = switch_channel_get_variable(tech_pvt->channel, "suppress_cng")) && switch_true(val))) {
@ -3307,7 +3315,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port"))) {
remote_rtcp_port = (switch_port_t)atoi(rport);
}
if (switch_rtp_set_remote_address
(tech_pvt->video_rtp_session, tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port, remote_rtcp_port, SWITCH_TRUE,
&err) != SWITCH_STATUS_SUCCESS) {
@ -3412,6 +3420,13 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
switch_rtp_set_ssrc(tech_pvt->video_rtp_session, ssrc_ul);
}
if (tech_pvt->video_recv_pt != tech_pvt->video_agreed_pt) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
"Set video receive payload to %u\n", tech_pvt->video_recv_pt);
switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->video_recv_pt);
}
switch_channel_set_variable_printf(tech_pvt->channel, "sip_use_video_pt", "%d", tech_pvt->video_agreed_pt);
tech_pvt->video_ssrc = switch_rtp_get_ssrc(tech_pvt->rtp_session);
switch_channel_set_variable_printf(tech_pvt->channel, "rtp_use_video_ssrc", "%u", tech_pvt->ssrc);
@ -4038,6 +4053,24 @@ switch_t38_options_t *sofia_glue_extract_t38_options(switch_core_session_t *sess
}
switch_status_t sofia_glue_get_offered_pt(private_object_t *tech_pvt, const switch_codec_implementation_t *mimp, switch_payload_t *pt)
{
int i = 0;
for (i = 0; i < tech_pvt->num_codecs; i++) {
const switch_codec_implementation_t *imp = tech_pvt->codecs[i];
if (!strcasecmp(imp->iananame, mimp->iananame)) {
*pt = tech_pvt->ianacodes[i];
return SWITCH_STATUS_SUCCESS;
}
}
return SWITCH_STATUS_FALSE;
}
uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_sdp)
{
uint8_t match = 0;
@ -4554,9 +4587,17 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_sdp_audio_port);
switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip);
switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
tech_pvt->audio_recv_pt = map->rm_pt;
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
sofia_glue_get_offered_pt(tech_pvt, mimp, &tech_pvt->audio_recv_pt);
}
switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->audio_recv_pt);
switch_channel_set_variable(tech_pvt->channel, "sip_audio_recv_pt", tmp);
}
if (match) {
if (sofia_glue_tech_set_codec(tech_pvt, 1) == SWITCH_STATUS_SUCCESS) {
got_audio = 1;
@ -4583,7 +4624,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
}
}
if (!match && greedy && mine < tech_pvt->num_codecs) {
mine++;
skip = 0;
@ -4665,6 +4706,16 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->video_agreed_pt);
switch_channel_set_variable(tech_pvt->channel, "sip_video_pt", tmp);
sofia_glue_check_video_codecs(tech_pvt);
tech_pvt->video_recv_pt = map->rm_pt;
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
sofia_glue_get_offered_pt(tech_pvt, mimp, &tech_pvt->video_recv_pt);
}
switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->video_recv_pt);
switch_channel_set_variable(tech_pvt->channel, "sip_video_recv_pt", tmp);
break;
} else {
vmatch = 0;
@ -5164,7 +5215,7 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName
if ((tmp = switch_channel_get_variable(channel, "sip_use_pt"))) {
tech_pvt->pt = tech_pvt->agreed_pt = (switch_payload_t)atoi(tmp);
}
sofia_glue_tech_set_codec(tech_pvt, 1);
tech_pvt->adv_sdp_audio_ip = tech_pvt->extrtpip = (char *) ip;
@ -5219,6 +5270,19 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName
switch_xml_free(xml);
return 0;
}
if (switch_rtp_ready(tech_pvt->rtp_session)) {
if ((tmp = switch_channel_get_variable(channel, "sip_audio_recv_pt"))) {
switch_rtp_set_recv_pt(tech_pvt->rtp_session, atoi(tmp));
}
}
if (switch_rtp_ready(tech_pvt->video_rtp_session)) {
if ((tmp = switch_channel_get_variable(channel, "sip_video_recv_pt"))) {
switch_rtp_set_recv_pt(tech_pvt->rtp_session, atoi(tmp));
}
}
}
if (switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) {

View File

@ -189,16 +189,8 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
dup_dest = strdup(dst->contact);
if (switch_stristr("fs_path", dst->contact)) {
const char *s;
if ((s = switch_stristr("fs_path=", dst->contact))) {
s += 8;
}
if (s) {
remote_host = strdup(s);
switch_url_decode(remote_host);
}
if (dst->route_uri) {
remote_host = strdup(dst->route_uri);
if (!zstr(remote_host)) {
switch_split_user_domain(remote_host, NULL, &remote_ip);
}
@ -239,8 +231,14 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
status = SWITCH_STATUS_SUCCESS;
/* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */
/*
if ((p = strstr(contact, ";fs_"))) {
*p = '\0';
}
*/
/* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */
msg_nh = nua_handle(profile->nua, NULL,
TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)),
TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),

View File

@ -1555,6 +1555,8 @@ static void switch_load_core_config(const char *file)
if (tmp > -1 && tmp < 11) {
switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp);
}
} else if (!strcasecmp(var, "multiple-registrations")) {
runtime.multiple_registrations = switch_true(val);
} else if (!strcasecmp(var, "sql-buffer-len")) {
int tmp = atoi(val);

View File

@ -1653,7 +1653,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, c
return SWITCH_STATUS_FALSE;
}
sql = switch_mprintf("delete from registrations where hostname='%q' and (url='%q' or token='%q')", switch_core_get_hostname(), url, switch_str_nil(token));
if (runtime.multiple_registrations) {
sql = switch_mprintf("delete from registrations where hostname='%q' and (url='%q' or token='%q')",
switch_core_get_hostname(), url, switch_str_nil(token));
} else {
sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q'",
user, realm, switch_core_get_hostname());
}
switch_cache_db_execute_sql(dbh, sql, NULL);
free(sql);

View File

@ -1398,8 +1398,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu
return SWITCH_STATUS_FALSE;
}
if (!switch_channel_test_flag(originator_channel, CF_ANSWERED)) {
if (switch_channel_test_flag(originatee_channel, CF_ANSWERED)) {
//if (!switch_channel_test_flag(originator_channel, CF_ANSWERED)) {
if (!switch_channel_media_ready(originator_channel)) {
if (switch_channel_media_ready(originatee_channel)) {
//if (switch_channel_test_flag(originatee_channel, CF_ANSWERED)) {
swap_session = originator_session;
originator_session = originatee_session;
originatee_session = swap_session;

View File

@ -126,6 +126,7 @@ struct switch_rtp_rfc2833_data {
unsigned int out_digit_dur;
uint16_t in_digit_seq;
uint32_t in_digit_ts;
uint32_t last_in_digit_ts;
uint32_t in_digit_sanity;
uint32_t in_interleaved;
uint32_t timestamp_dtmf;
@ -306,6 +307,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed DTMF payload check.\n");
rtp_session->dtmf_data.last_digit = 0;
rtp_session->dtmf_data.in_digit_ts = 0;
rtp_session->dtmf_data.in_digit_sanity = 0;
}
end = packet[1] & 0x80 ? 1 : 0;
@ -355,6 +357,15 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
}
if (end) {
if (!rtp_session->dtmf_data.in_digit_ts && rtp_session->dtmf_data.last_in_digit_ts != ts) {
#ifdef DEBUG_2833
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "start with end packet %d\n", ts);
#endif
rtp_session->dtmf_data.last_in_digit_ts = ts;
rtp_session->dtmf_data.in_digit_ts = ts;
rtp_session->dtmf_data.first_digit = key;
rtp_session->dtmf_data.in_digit_sanity = 2000;
}
if (rtp_session->dtmf_data.in_digit_ts) {
switch_dtmf_t dtmf = { key, duration };
@ -395,7 +406,11 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_
}
} else if (!rtp_session->dtmf_data.in_digit_ts) {
#ifdef DEBUG_2833
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "start %d\n", ts);
#endif
rtp_session->dtmf_data.in_digit_ts = ts;
rtp_session->dtmf_data.last_in_digit_ts = ts;
rtp_session->dtmf_data.first_digit = key;
rtp_session->dtmf_data.in_digit_sanity = 2000;
}
@ -1578,7 +1593,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session
rtp_session->recv_msg.header.cc = 0;
rtp_session->payload = payload;
rtp_session->rpayload = payload;
rtp_session->rtcp_send_msg.header.version = 2;
rtp_session->rtcp_send_msg.header.p = 0;
@ -1773,6 +1788,12 @@ SWITCH_DECLARE(void) switch_rtp_set_telephony_recv_event(switch_rtp_t *rtp_sessi
}
}
SWITCH_DECLARE(void) switch_rtp_set_recv_pt(switch_rtp_t *rtp_session, switch_payload_t pt)
{
rtp_session->rpayload = pt;
}
SWITCH_DECLARE(void) switch_rtp_set_cng_pt(switch_rtp_t *rtp_session, switch_payload_t pt)
{
rtp_session->cng_pt = pt;
@ -2345,7 +2366,7 @@ static void do_flush(switch_rtp_t *rtp_session)
if (bytes > rtp_header_len && rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) {
handle_rfc2833(rtp_session, bytes, &do_cng);
#ifdef DEBUG_2833
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "*** RTP packet handled in flush loop ***\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "*** RTP packet handled in flush loop %d ***\n", do_cng);
#endif
}
@ -2640,13 +2661,25 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
while (switch_rtp_ready(rtp_session)) {
int do_cng = 0;
int read_pretriggered = 0;
bytes = 0;
if (rtp_session->timer.interval) {
if ((switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTOFLUSH) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_STICKY_FLUSH)) &&
rtp_session->read_pollfd) {
if (switch_poll(rtp_session->read_pollfd, 1, &fdr, 0) == SWITCH_STATUS_SUCCESS) {
rtp_session->hot_hits += rtp_session->samples_per_interval;
status = read_rtp_packet(rtp_session, &bytes, flags);
/* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Initial %d\n", bytes); */
read_pretriggered = 1;
if (switch_poll(rtp_session->read_pollfd, 1, &fdr, 0) == SWITCH_STATUS_SUCCESS) {
/* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Trigger %d\n", rtp_session->hot_hits); */
rtp_session->hot_hits += rtp_session->samples_per_interval;
} else {
rtp_session->hot_hits = 0;
switch_core_timer_sync(&rtp_session->timer);
goto recvfrom;
}
if (rtp_session->hot_hits >= rtp_session->samples_per_second * 5) {
switch_set_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH);
@ -2674,7 +2707,9 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
}
recvfrom:
bytes = 0;
if (!read_pretriggered) {
bytes = 0;
}
read_loops++;
poll_loop = 0;
@ -2685,7 +2720,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
if (!rtp_session->timer.interval && rtp_session->read_pollfd) {
int pt = poll_sec * 1000000;
if (rtp_session->dtmf_data.out_digit_dur > 0) {
if (rtp_session->dtmf_data.out_digit_dur > 0 || rtp_session->dtmf_data.in_digit_sanity) {
pt = 20000;
}
@ -2694,13 +2729,18 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
}
poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt);
do_2833(rtp_session, session);
if (rtp_session->dtmf_data.out_digit_dur > 0) {
do_2833(rtp_session, session);
return_cng_frame();
}
}
if (poll_status == SWITCH_STATUS_SUCCESS) {
status = read_rtp_packet(rtp_session, &bytes, flags);
if (!read_pretriggered) {
status = read_rtp_packet(rtp_session, &bytes, flags);
/* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Read bytes %d\n", bytes); */
}
} else {
if (!SWITCH_STATUS_IS_BREAK(poll_status) && poll_status != SWITCH_STATUS_TIMEOUT) {
char tmp[128] = "";
@ -2813,7 +2853,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
rtp_session->recv_msg.header.pt != 13 &&
rtp_session->recv_msg.header.pt != rtp_session->recv_te &&
(!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) &&
rtp_session->recv_msg.header.pt != rtp_session->payload) {
rtp_session->recv_msg.header.pt != rtp_session->rpayload) {
/* drop frames of incorrect payload number and return CNG frame instead */
return_cng_frame();
}
@ -3131,8 +3171,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
rtp_session->recv_msg.header.pt = 97;
}
rtp_session->rpayload = (switch_payload_t) rtp_session->recv_msg.header.pt;
break;
do_continue:

View File

@ -58,12 +58,7 @@ static int MONO = 1;
static int MONO = 0;
#endif
#if defined(HAVE_CLOCK_NANOSLEEP)
static int NANO = 1;
#else
static int NANO = 0;
#endif
static int OFFSET = 0;