Merge branch 'master' into arnaldo.zt_chan_next_event
This commit is contained in:
commit
7732a67598
|
@ -1,6 +1,6 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchConsole", "w32\Console\FreeSwitchConsole.2008.vcproj", "{1AF3A893-F7BE-43DD-B697-8AB2397C0D67}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
|
||||
|
@ -11,6 +11,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchCoreLib", "w32\Li
|
|||
ProjectSection(ProjectDependencies) = postProject
|
||||
{8D04B550-D240-4A44-8A18-35DA3F7038D9} = {8D04B550-D240-4A44-8A18-35DA3F7038D9}
|
||||
{89385C74-5860-4174-9CAF-A39E7C48909C} = {89385C74-5860-4174-9CAF-A39E7C48909C}
|
||||
{1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}
|
||||
{F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3}
|
||||
{03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD}
|
||||
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
|
||||
|
|
|
@ -381,6 +381,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchCoreLib", "w32\Li
|
|||
ProjectSection(ProjectDependencies) = postProject
|
||||
{8D04B550-D240-4A44-8A18-35DA3F7038D9} = {8D04B550-D240-4A44-8A18-35DA3F7038D9}
|
||||
{89385C74-5860-4174-9CAF-A39E7C48909C} = {89385C74-5860-4174-9CAF-A39E7C48909C}
|
||||
{1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}
|
||||
{F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3}
|
||||
{03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD}
|
||||
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
|
||||
|
|
|
@ -707,6 +707,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_distributor", "src\mod\
|
|||
EndProject
|
||||
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Setup", "w32\Setup\Setup.wixproj", "{47213370-B933-487D-9F45-BCA26D7E2B6F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_say_pt", "src\mod\say\mod_say_pt\mod_say_pt.2010.vcxproj", "{7C22BDFF-CC09-400C-8A09-660733980028}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
All|Win32 = All|Win32
|
||||
|
@ -3619,6 +3621,23 @@ Global
|
|||
{47213370-B933-487D-9F45-BCA26D7E2B6F}.Release|x64 Setup.Build.0 = Release|x64
|
||||
{47213370-B933-487D-9F45-BCA26D7E2B6F}.Release|x86 Setup.ActiveCfg = Release|x86
|
||||
{47213370-B933-487D-9F45-BCA26D7E2B6F}.Release|x86 Setup.Build.0 = Release|x86
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.All|Win32.ActiveCfg = Release|x64
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.All|x64.ActiveCfg = Release|x64
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.All|x64.Build.0 = Release|x64
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.All|x64 Setup.ActiveCfg = Release|x64
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.All|x86 Setup.ActiveCfg = Release|x64
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.Debug|x64.Build.0 = Debug|x64
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.Debug|x64 Setup.ActiveCfg = Debug|x64
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.Debug|x86 Setup.ActiveCfg = Debug|x64
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.Release|Win32.Build.0 = Release|Win32
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.Release|x64.ActiveCfg = Release|x64
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.Release|x64.Build.0 = Release|x64
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.Release|x64 Setup.ActiveCfg = Release|x64
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028}.Release|x86 Setup.ActiveCfg = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -3769,6 +3788,7 @@ Global
|
|||
{A4B122CF-5196-476B-8C0E-D8BD59AC3C14} = {6CD61A1D-797C-470A-BE08-8C31B68BB336}
|
||||
{B6A9FB7A-1CC4-442B-812D-EC33E4E4A36E} = {6CD61A1D-797C-470A-BE08-8C31B68BB336}
|
||||
{0382E8FD-CFDC-41C0-8B03-792C7C84FC31} = {6CD61A1D-797C-470A-BE08-8C31B68BB336}
|
||||
{7C22BDFF-CC09-400C-8A09-660733980028} = {6CD61A1D-797C-470A-BE08-8C31B68BB336}
|
||||
{3B08FEFD-4D3D-4C16-BA94-EE83509E32A0} = {57D119DC-484F-420F-B9E9-8589FD9A8DF8}
|
||||
{7BFD517E-7F8F-4A40-A78E-8D3632738227} = {57D119DC-484F-420F-B9E9-8589FD9A8DF8}
|
||||
{6374D55C-FABE-4A02-9CF1-4145308A56C5} = {57D119DC-484F-420F-B9E9-8589FD9A8DF8}
|
||||
|
|
12
Makefile.am
12
Makefile.am
|
@ -90,6 +90,8 @@ $(RECURSIVE_TARGETS):
|
|||
fi; \
|
||||
if test -z "$$fail" ; then \
|
||||
cd $(top_builddir)/build && $(MAKE) $(AM_MAKEFLAGS) $$target || exit 1; \
|
||||
else \
|
||||
exit 1; \
|
||||
fi ;
|
||||
|
||||
CORE_CFLAGS = `$(switch_builddir)/libs/apr/apr-1-config --cflags --cppflags --includes`
|
||||
|
@ -100,6 +102,7 @@ CORE_CFLAGS += -I$(switch_srcdir)/libs/pcre
|
|||
CORE_CFLAGS += -I$(switch_srcdir)/libs/speex/include -Ilibs/speex/include
|
||||
CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/include
|
||||
CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/crypto/include -Ilibs/srtp/crypto/include
|
||||
CORE_CFLAGS += -I$(switch_srcdir)/libs/spandsp/src -I$(switch_srcdir)/libs/tiff-3.8.2/libtiff
|
||||
|
||||
CORE_LIBS = libs/apr-util/libaprutil-1.la libs/apr/libapr-1.la
|
||||
CORE_LIBS += libs/sqlite/libsqlite3.la libs/pcre/libpcre.la libs/speex/libspeex/libspeexdsp.la
|
||||
|
@ -247,7 +250,8 @@ libfreeswitch_la_SOURCES = \
|
|||
libs/miniupnpc/minissdpc.c \
|
||||
libs/miniupnpc/upnperrors.c \
|
||||
libs/libnatpmp/natpmp.c \
|
||||
libs/libnatpmp/getgateway.c
|
||||
libs/libnatpmp/getgateway.c\
|
||||
libs/spandsp/src/plc.c
|
||||
|
||||
if ENABLE_CPP
|
||||
libfreeswitch_la_SOURCES += src/switch_cpp.cpp
|
||||
|
@ -272,7 +276,8 @@ bin_PROGRAMS = freeswitch fs_cli fs_ivrd tone2wav fs_encode
|
|||
##
|
||||
## fs_cli ()
|
||||
##
|
||||
fs_cli_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c libs/esl/src/esl_threadmutex.c libs/esl/fs_cli.c libs/esl/src/esl_json.c
|
||||
fs_cli_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c \
|
||||
libs/esl/src/esl_threadmutex.c libs/esl/fs_cli.c libs/esl/src/esl_json.c libs/esl/src/esl_buffer.c
|
||||
fs_cli_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include
|
||||
fs_cli_LDFLAGS = $(AM_LDFLAGS) -lpthread $(ESL_LDFLAGS) -lm
|
||||
|
||||
|
@ -300,7 +305,8 @@ tone2wav_LDADD = libfreeswitch.la
|
|||
##
|
||||
## fs_ivrd ()
|
||||
##
|
||||
fs_ivrd_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c libs/esl/src/esl_threadmutex.c libs/esl/ivrd.c libs/esl/src/esl_json.c
|
||||
fs_ivrd_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c \
|
||||
libs/esl/src/esl_threadmutex.c libs/esl/ivrd.c libs/esl/src/esl_json.c libs/esl/src/esl_buffer.c
|
||||
fs_ivrd_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include
|
||||
fs_ivrd_LDFLAGS = $(AM_LDFLAGS) -lpthread $(ESL_LDFLAGS) -lm
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ say/mod_say_en
|
|||
#say/mod_say_fr
|
||||
#say/mod_say_it
|
||||
#say/mod_say_nl
|
||||
#say/mod_say_pt
|
||||
say/mod_say_ru
|
||||
#say/mod_say_zh
|
||||
#say/mod_say_hu
|
||||
|
|
|
@ -205,10 +205,14 @@ if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then
|
|||
APR_ADDTO(SWITCH_AM_CFLAGS, -DPIC)
|
||||
APR_ADDTO(SWITCH_AM_CFLAGS, -erroff=E_END_OF_LOOP_CODE_NOT_REACHED)
|
||||
APR_ADDTO(SWITCH_AM_CFLAGS, -errtags=yes)
|
||||
APR_ADDTO(SWITCH_AM_CFLAGS, -D__FUNCTION__=__func__ )
|
||||
APR_ADDTO(SWITCH_AM_CFLAGS, -mt)
|
||||
APR_ADDTO(SWITCH_AM_CXXFLAGS, -errtags=yes)
|
||||
APR_ADDTO(SWITCH_AM_CXXFLAGS, -KPIC)
|
||||
APR_ADDTO(SWITCH_AM_CXXFLAGS, -DPIC)
|
||||
APR_ADDTO(SWITCH_AM_CXXFLAGS, "-features=extensions")
|
||||
APR_ADDTO(SWITCH_AM_CXXFLAGS, -D__FUNCTION__=__func__)
|
||||
APR_ADDTO(SWITCH_AM_CXXFLAGS, -mt)
|
||||
|
||||
APR_ADDTO(SWITCH_AM_LDFLAGS, -R${prefix}/lib)
|
||||
if test "${enable_64}" = "yes"; then
|
||||
|
|
|
@ -20,6 +20,7 @@ freeswitch (1.0.7)
|
|||
build: Remove mod_spidermonkey from windows 2008 x64 builds - does not work (r:280e894d)
|
||||
build: fix warnings on windows x64 builds src and mods projects - only libsofia included on the libs side (r:45ecbc2f)
|
||||
build: Patch debian init.d script to set ulimit values (r:0eb33e57/FS-2844)
|
||||
build: add plc to core (r:b7c80a84)
|
||||
codec2: working prototype, still for testing only (r:04ca0751)
|
||||
config: move limit.conf to db.conf
|
||||
config: Update VM phrase macros to voice option then action on main, config menus
|
||||
|
@ -32,6 +33,8 @@ freeswitch (1.0.7)
|
|||
config: default example to resolve some issues with SCA in cases where host and ip are mixed causing the phone to be confused. (r:0279261b)
|
||||
config: Fix phrase files, still missing a sound file (r:6741f350/FS-2742)
|
||||
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)
|
||||
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
|
||||
|
@ -134,6 +137,25 @@ freeswitch (1.0.7)
|
|||
core: Better handling of progress and answering to prevent sip profile from locking up at higher volumes (r:04e57577/FS-2801)
|
||||
core: ACL for IPv6 address and swigall to boot (r:db91f0e8/FS-2842)
|
||||
core: add intercept_unanswered_only var akin to intercept_unbridged_only (r:68f18efe)
|
||||
core: switch_odbc_handle_exec_string duplication SQLExecute (r:8b0e7d24/FS-2880)
|
||||
core: Fix timeout while bridge is waiting for CF_BRIDGED flag (r:2572621b/FS-2368)
|
||||
core: don't parse events for b legs from a leg thread in case they are using a monolothic python script as a group_confirm exec over socket to send it messages while the call is ringing (r:ed5266d3)
|
||||
core: add new function to check when messages need parsing to improve performance on parsing messages during originate (r:8b0421ff)
|
||||
core: run execute_on_answer on_media _on_ring apps async (r:ef4a4ed0)
|
||||
core: add switch_ivr_insert_file to insert one file into another at an arbitrary sample point (r:82394b37)
|
||||
core: Slow reload cause calls to hang (r:1ba98b02/FS-2852)
|
||||
core: Application intercept causes FS to stop processing calls (r:12fc65f7/FS-2872)
|
||||
core: fix edge cases for endless loop in sql thread (r:5d7c09ed)
|
||||
core: prevent race while changing codecs mid call (r:7aa72b67)
|
||||
core: Fix crash in ODBC when SQL Server kills TCP connection (r:5aba96e3/FS-2910)
|
||||
core: Fix fallback to CORE_DB when MSSQL fails init (r:3406d05b)
|
||||
core: add new function to init an empty switch_sockaddr_t to avoid an unnecessary dns lookup on 0.0.0.0 (r:009c41d4)
|
||||
core: fix endless RTP loop in Windows (r:cb2d0736/FS-2924)
|
||||
core: play_and_get_digits should actually timeout, not last forever... (r:28cab5ed/FS-2923)
|
||||
core: Fix crash w/o core dump (r:00046ee0/FS-2933)
|
||||
core: normalize tests for outbound channels to use switch_channel_direction instead of testing for CF_OUTBOUND (r:93cc3dc5)
|
||||
core: add CF_DIALPLAN (r:3ff07445)
|
||||
core: tweak on calle[re] id (r:9db4a826)
|
||||
lang: Improve French phrase files (FSCONFIG-23)
|
||||
libapr: Fix issue where after a bridge with a member, uuid of Agent is set to single quote character ' (r:3fee704d/FS-2738)
|
||||
libdingaling: fix race on shutdown causing crash (FSMOD-47)
|
||||
|
@ -151,6 +173,9 @@ freeswitch (1.0.7)
|
|||
libesl: Fix SEGV when using serialize function without any arguments (r:910729b5/ESL-44)
|
||||
libesl: fix leak-on-error in esl_connect_timeout() (r:4263d60e)
|
||||
libesl: Call close on connection handle if the connection fails (r:413dcc4c/ESL-50)
|
||||
libesl: allow fs_cli -x to have args up to 1024 chars (was 256) (r:7039ba47)
|
||||
libesl: Make last_event pointer last longer (r:a15f51d5/ESL-37)
|
||||
libesl: use a packet buffer for ESL (r:2081bf97)
|
||||
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)
|
||||
|
@ -189,7 +214,8 @@ freeswitch (1.0.7)
|
|||
mod_callcenter: Fix invalid update of agent field (r:426a448f/FS-2738)
|
||||
mod_callcenter: Allow to get queue info via api (r:70d592ae)
|
||||
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 ammount of second before it kicked out of the queue rather than get rejected automaticly. (r:81a03869)
|
||||
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_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
|
||||
|
@ -205,6 +231,10 @@ freeswitch (1.0.7)
|
|||
mod_commands: ***BEHAVIOUR CHANGE*** reloadacl, load <module>, reload <module> will now explicitly call reloadxml (r:42c9df72)
|
||||
mod_commands: add nat_map usage (r:7577b8aa)
|
||||
mod_commands: add escaping empty strings to sql_escape (r:7bd0a5a6/FS-2833)
|
||||
mod_commands: add uuid_fileman <uuid> <cmd>:<val> <-- same vals as the callbacks in js and lua to control the currently playing file of a channel from the cli or ESL (for the people who were ignoring me on the conference call so I decided to implement it instead of try to explain it ) (r:c4369fc8)
|
||||
mod_commands: FS-2210 Add support for auto completion for uuid_simplify (r:72bcc01b/FS-2210)
|
||||
mod_commands: allow epoch in strftime_tz (r:bbf1cd1f)
|
||||
mod_commands: Dramatic jitterbuffer changes (r:d5470961)
|
||||
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
|
||||
|
@ -214,6 +244,7 @@ freeswitch (1.0.7)
|
|||
mod_conference: Fix floor change events not always firing (r:8f1767d3/MODAPP-424)
|
||||
mod_conference: refactor conference to use switch_ivr_dmachine for the digit parsing controls are now bound to each member separately based on conference_controls channel var, then the caller-controls param in the profile or a default to "default" (r:ac19f73c)
|
||||
mod_conference: Fix crash on dtmf action (r:4d5389bd/FS-2781)
|
||||
mod_conference: revert to the last transfered conference on recover (r:d11c83b1)
|
||||
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)
|
||||
|
@ -221,6 +252,8 @@ freeswitch (1.0.7)
|
|||
mod_dingaling: make dingaling work with google voice inbound too (r:4ee68141)
|
||||
mod_dingaling: Fix crash when testing the new gv-dingaling with around 24 concurrent calls (r:73e1ec5e/FSCORE-667)
|
||||
mod_dingaling: Fix NULL pointer (r:e3eff816/FS-1103)
|
||||
mod_dingaling: fix leak in chat_send (r:eb109a85)
|
||||
mod_dingaling: use the login as message source when not in component mode. (chat_send) (r:58c28aab)
|
||||
mod_directory: Add variable directory_search_order to allow to search by first name by default is set to "first_name" (r:163ca31f)
|
||||
mod_distributor: Add mod_distributor to VS2010 - not built by default (r:bac79ba1)
|
||||
mod_dptools: add eavesdrop_enable_dtmf chan var (r:596c0012)
|
||||
|
@ -279,8 +312,10 @@ freeswitch (1.0.7)
|
|||
mod_freetdm: lock the channel when placing call (r:705dd237)
|
||||
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_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)
|
||||
mod_hash: free all hashtables on shutdown (r:e76d7d92)
|
||||
mod_hash: remove unneeded initializer (r:10d468a6)
|
||||
mod_hash: begin working on remote support (r:c5ad49da)
|
||||
|
@ -324,6 +359,7 @@ freeswitch (1.0.7)
|
|||
mod_lua: Added SAF_ROUTING_EXEC flag to lua app, so it can be run inline (r:7d5ca1c0)
|
||||
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)
|
||||
mod_mp4v: MP4V-ES passthru for washibechi on IRC
|
||||
mod_mp4: New module. Supports playback of MP4 files. Depends on libmp4v2 <http://code.google.com/p/mp4v2/> (originally compiled against v1.6.1)
|
||||
mod_nibblebill: free allocated mem at shutdown; free properly if using custom_sql
|
||||
|
@ -472,6 +508,19 @@ freeswitch (1.0.7)
|
|||
mod_sofia: fix missing name and potential segfault in gateway status (r:40ac860a)
|
||||
mod_sofia: Add missing RTP info for early SDP in bypass media (r:10119e9e/FS-2824)
|
||||
mod_sofia: add manual_rtp_bugs to profile and chan var and 3 new RTP bugs SEND_LINEAR_TIMESTAMPS|START_SEQ_AT_ZERO|NEVER_SEND_MARKER (r:b278dd23)
|
||||
mod_sofia: apparently some sip device vendors did not read the RFC (who knew?) adding verbose_sdp=true var to add needless a= lines for standard iana codecs that explicitly do not require them (r:6c4f49a8)
|
||||
mod_sofia: Fix registering a gateway, sofia always places a Via header with ext-sip-ip, even if this gateway is local (r:cf398e1a/FS-535)
|
||||
mod_sofia: add presence-probe-on-register sofia param to send a probe on register instead of presence to deal with some broken phones and add some general improvements to allow multi homed presence (r:14394994)
|
||||
mod_sofia: Fix issue when fs_path is used so we pick the correct media IP in our outbound invite this was soemthing that wouldn't work correctly over ATT on the iphone. (r:a669f76f)
|
||||
mod_sofia: Default T38 Options (r:92f43440/FS-2892)
|
||||
mod_sofia: Fix wrong IP in VIA and contact HEADER for MESSAGE method while fs run in private network (r:59ea4a1b/FS-2886)
|
||||
mod_sofia: SIP-header History-Info might exist multiple times, but only last header is exposed as a channel variable (r:8cf15012/FS-2881)
|
||||
mod_sofia: Add support to reboot Yealink phone remotely (r:fdc31908/FS-2897)
|
||||
mod_sofia: Add reuse-connections sofia profile param to allow users to turn off TPTAG_REUSE, thus not re-using TCP connections (r:98ed05cc)
|
||||
mod_sofia: Make sofia recover also work on custom uuid (r:3a645dee/FS-2913)
|
||||
mod_sofia: remove check for va_list completely in sofia since i don't even think it happens ever (r:dfecc914)
|
||||
mod_sofia: have mod_sofia always elect to be the session refresher so we know it will work, also make the session-expires set to 0 imply 100% disabled session timers (r:321013ef)
|
||||
mod_sofia: Do not set nat mode when the device's network_ip is within the acl also so if your FS is behind nat and your phone is too then it will still make the right decisions (r:6c6eab8c)
|
||||
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)
|
||||
|
@ -487,6 +536,7 @@ freeswitch (1.0.7)
|
|||
mod_spidermonkey: fix seg in js hangup (r:7d554c11)
|
||||
mod_spidermonkey: Fix mod_spidermonkey build on FreeBSD, (Undefined symbol PR_LocalTimeParameters). (r:3edb8419)
|
||||
mod_spy: add support for loopback endpoint (MODAPP-416)
|
||||
mod_spy: fix crash when session can't be located (r:c4154633/FS-2929)
|
||||
mod_tts_commandline: fix core dump, temp file problem. flush can be called several times (FSMOD-35)
|
||||
mod_unimrcp: fix fortify findings for mod_unimrcp (r:336f0b4e/FSMOD-67)
|
||||
mod_valet_parking: add event data to valet parking hold event
|
||||
|
@ -508,6 +558,8 @@ freeswitch (1.0.7)
|
|||
mod_xml_cdr: fix minor memory leaks and config bug (r:19253d83/MODEVENT-62)
|
||||
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)
|
||||
scripts: add_user - cmd line utility that lets admin create new users very easily. (r:ec8f2c2b)
|
||||
sofia-sip: fix null derefernce segfault in soa (r:f356c5e6)
|
||||
sofia-sip: extend timeout for session expires on short timeouts to be 90% of timeout instead of 1/3 to handle devices that do not refresh in time such as polycom (r:a7f48928/SFSIP-212)
|
||||
tools: Add fs_encode tool (r:89b17601)
|
||||
|
|
|
@ -31,7 +31,7 @@ PROJECT_NAME = FreeSWITCH
|
|||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 1.0.4
|
||||
PROJECT_NUMBER = 1.0.6
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
|
|
|
@ -221,6 +221,7 @@
|
|||
<prompt phrase="Welcome to your new voicemail. To listen to a tutorial and setup your voice mail box, press 1. To skip, press 2." filename="vm-tutorial_yes_no.wav"/>
|
||||
<prompt phrase="I need to record your first and last name. This recording is used throughout the system, including in the company directory." filename="vm-tutorial_record_name.wav"/>
|
||||
<prompt phrase="Your personal identification number, or 'pin', is used to prevent others from accessing your voicemail messages. Would you like to change it now?" filename="vm-tutorial_change_pin.wav"/>
|
||||
<prompt phrase="The person you are trying to reach is not available and does not have voicemail." filename="vm-not_available_no_voicemail.wav"/>
|
||||
</voicemail>
|
||||
<directory>
|
||||
<prompt phrase="Please enter the first few letters of the persons" filename="dir-enter_person.wav"/>
|
||||
|
@ -241,6 +242,8 @@
|
|||
<prompt phrase="...letters of the person's name." filename="dir-letters_of_person_name.wav"/>
|
||||
<prompt phrase="Please try again." filename="dir-please_try_again.wav"/>
|
||||
<prompt phrase="press" filename="dir-press.wav" info="we can copy vm/vm-press.wav"/>
|
||||
<prompt phrase="For the next entry..." filename="dir-for_next.wav" note="re-recorded because original was wrong"/>
|
||||
<prompt phrase="Please enter the first few letters of the person's first or last name" filename="dir-enter_person_first_or_last.wav"/>
|
||||
</directory>
|
||||
<conference>
|
||||
<prompt phrase="NULL" filename="conf-ack.wav" type="tone"/>
|
||||
|
@ -259,6 +262,12 @@
|
|||
<prompt phrase="Invalid pin number, try again." filename="conf-bad-pin.wav"/>
|
||||
<prompt phrase="goodbye" filename="conf-goodbye.wav"/>
|
||||
<prompt phrase="Welcome to the conference." filename="conf-welcome.wav"/>
|
||||
<prompt phrase="Please enter the conference number, followed by the pound key" filename="conf-enter_conf_number.wav"/>
|
||||
<prompt phrase="Enter the conference PIN number, followed by the pound key." filename="conf-enter_conf_pin.wav"/>
|
||||
<prompt phrase="...has entered the conference." filename="conf-has_joined.wav"/>
|
||||
<prompt phrase="...has left the conference." filename="conf-has_left.wav"/>
|
||||
<prompt phrase="You are already muted." filename="conf-you_are_already_muted.wav"/>
|
||||
<prompt phrase="You are now bi-directionally muted." filename="conf-you_are_now_bidirectionally_muted.wav"/>
|
||||
</conference>
|
||||
<ivr>
|
||||
<prompt phrase="Account number" filename="ivr-account_number.wav"/>
|
||||
|
@ -362,8 +371,6 @@
|
|||
<prompt phrase="Thank you for calling. If you know your party's extension, please enter it now. For a directory, press..." filename="ivr-generic_greeting.wav"/>
|
||||
<prompt phrase="...file..." filename="ivr-file.wav"/>
|
||||
<prompt phrase="...files..." filename="ivr-files-.wav"/>
|
||||
|
||||
<!-- The following phrases still need to be recorded -->
|
||||
<prompt phrase="For a wakeup call..." filename="ivr-for_a_wakeup_call.wav"/>
|
||||
<prompt phrase="This is your wakeup call." filename="ivr-this_is_your_wakeup_call.wav"/>
|
||||
<prompt phrase="To request a wakeup call..." filename="ivr-request_wakeup_call.wav"/>
|
||||
|
@ -390,15 +397,10 @@
|
|||
<prompt phrase="You are the..." filename="ivr-you_are_the.wav"/>
|
||||
<prompt phrase="One moment please." filename="ivr-one_moment_please.wav"/>
|
||||
<prompt phrase="Your call will be answered in the order it was received." filename="ivr-call_answered_order_received.wav"/>
|
||||
<prompt phrase="Please enter the conference number, followed by the pound key" filename="conf-enter_conf_number.wav"/>
|
||||
<prompt phrase="Enter the conference PIN number, followed by the pound key." filename="conf-enter_conf_pin.wav"/>
|
||||
<prompt phrase="...has entered the conference." filename="conf-has_joined.wav"/>
|
||||
<prompt phrase="...has left the conference." filename="conf-has_left.wav"/>
|
||||
<prompt phrase="You entered..." filename="ivr-you_entered.wav"/>
|
||||
<prompt phrase="Extension number..." filename="ivr-extension_number.wav"/>
|
||||
<prompt phrase="Please hold while your party is being contacted." filename="ivr-please_hold_while_party_contacted.wav"/>
|
||||
<prompt phrase="Please enjoy the music while your party is being reached." filename="ivr-please_enjoy_music_while_party_reached.wav"/>
|
||||
<prompt phrase="For the next entry..." filename="dir-for_next.wav" note="re-record because original is wrong"/>
|
||||
<prompt phrase="Thank you for calling. If you know your party's extension, please enter it now, or dial nine for a directory." filename="ivr-generic_greeting.wav"/>
|
||||
<prompt phrase="If this is correct, press 1. If not, press 2." filename="ivr-if_correct_one_if_not_two.wav"/>
|
||||
<prompt phrase="To repeat this information..." filename="ivr-repeat_this_information.wav"/>
|
||||
|
@ -409,10 +411,7 @@
|
|||
<prompt phrase="That's it! One more mistake and I WILL hang up on your ass." filename="ivr-one_more_mistake.wav"/>
|
||||
<prompt phrase="Congratulations, you pressed star. This does not mean you ARE a star. It simply means that you can press buttons and probably have fingers." filename="ivr-congratulations_you_pressed_star.wav"/>
|
||||
<prompt phrase="All of our engineers are busy assisting other sales guys with demonstrating how cool the CudaTel is." filename="ivr-engineers_busy_assisting_other_sales.wav"/>
|
||||
<prompt phrase="The person you are trying to reach is not available and does not have voicemail." filename="vm-not_available_no_voicemail.wav"/>
|
||||
<prompt phrase="This message will self-destruct in 5, 4, 3, 2, 1..." filename="ivr-message_self_destruct.wav"/>
|
||||
<prompt phrase="You are already muted." filename="conf-you_are_already_muted.wav"/>
|
||||
<prompt phrase="You are now bi-directionally muted." filename="conf-you_are_now_bidirectionally_muted.wav"/>
|
||||
<prompt phrase="All your call are belong to us." filename="ivr-all_your_call_are_belong_to_us.wav"/>
|
||||
<prompt phrase="I just love the way you press those touch tones!" filename="ivr-love_those_touch_tones.wav"/>
|
||||
<prompt phrase="Yes, we have no bananas." filename="ivr-yes_we_have_no_bananas.wav"/>
|
||||
|
@ -425,20 +424,10 @@
|
|||
<prompt phrase="Please contact the system administrator for assistance." filename="ivr-contact_system_administrator.wav"/>
|
||||
<prompt phrase="Barracuda Networks" filename="ivr-barracuda_networks.wav"/>
|
||||
<prompt phrase="CudaTel Communication Server" filename="ivr-cudatel_communication_server.wav"/>
|
||||
<prompt phrase="Please enter the first few letters of the person's first or last name" filename="dir-enter_person_first_or_last.wav"/>
|
||||
<prompt phrase="There are no calls waiting in this queue." filename="ivr-no_calls_waiting_in_queue.wav"/>
|
||||
<prompt phrase="Brian West" filename="misc-Brian_West.wav"/>
|
||||
<prompt phrase="Anthony Minessale" filename="misc-Anthony_Minessale.wav"/>
|
||||
<prompt phrase="Michael Jerris" filename="misc-Michael_Jerris.wav"/>
|
||||
<prompt phrase="Raymond Chandler" filename="misc-Raymond_Chandler.wav"/>
|
||||
<prompt phrase="Michael Collins" filename="misc-Michael_Collins.wav"/>
|
||||
<prompt phrase="Mark Mann" filename="misc-Mark_Mann.wav"/>
|
||||
<prompt phrase="William King" filename="misc-William_King.wav"/>
|
||||
<prompt phrase="Rudy Fleminger" filename="misc-Rudy_Fleminger.wav"/>
|
||||
<prompt phrase="Andrew Thompson" filename="misc-Andrew_Thompson.wav"/>
|
||||
<prompt phrase="Graham Saathoff" filename="misc-Graham_Saathoff.wav"/>
|
||||
<prompt phrase="Nicholaus Belluni" filename="misc-Nicholaus_Belluni.wav"/>
|
||||
<prompt phrase="Sean Heiney" filename="misc-Sean_Heiney.wav"/>
|
||||
|
||||
<!-- The following phrases still need to be recorded -->
|
||||
<prompt phrase="You are caller number one. Of course, *every* caller is number one in our book so you may be waiting a while." filename="ivr-youre_number_one.wav"/>
|
||||
</ivr>
|
||||
<misc>
|
||||
<prompt phrase="This call has been secured" filename="call_secured.wav"/>
|
||||
|
|
|
@ -0,0 +1,994 @@
|
|||
<language>
|
||||
<es_ES>
|
||||
<ascii>
|
||||
<prompt phrase="Espacio" filename="32.wav"/>
|
||||
<prompt phrase="Almohadilla" filename="35.wav"/>
|
||||
<prompt phrase="Asterisco" filename="42.wav"/>
|
||||
<prompt phrase="Punto" filename="46.wav"/>
|
||||
<prompt phrase="A" filename="97.wav"/>
|
||||
<prompt phrase="B" filename="98.wav"/>
|
||||
<prompt phrase="C" filename="99.wav"/>
|
||||
<prompt phrase="D" filename="100.wav"/>
|
||||
<prompt phrase="E" filename="101.wav"/>
|
||||
<prompt phrase="F" filename="102.wav"/>
|
||||
<prompt phrase="G" filename="103.wav"/>
|
||||
<prompt phrase="H" filename="104.wav"/>
|
||||
<prompt phrase="I" filename="105.wav"/>
|
||||
<prompt phrase="J" filename="106.wav"/>
|
||||
<prompt phrase="K" filename="107.wav"/>
|
||||
<prompt phrase="L" filename="108.wav"/>
|
||||
<prompt phrase="M" filename="109.wav"/>
|
||||
<prompt phrase="N" filename="110.wav"/>
|
||||
<prompt phrase="Ñ" filename="Ñ.wav"/>
|
||||
<prompt phrase="O" filename="111.wav"/>
|
||||
<prompt phrase="P" filename="112.wav"/>
|
||||
<prompt phrase="Q" filename="113.wav"/>
|
||||
<prompt phrase="R" filename="114.wav"/>
|
||||
<prompt phrase="S" filename="115.wav"/>
|
||||
<prompt phrase="T" filename="116.wav"/>
|
||||
<prompt phrase="U" filename="117.wav"/>
|
||||
<prompt phrase="V" filename="118.wav"/>
|
||||
<prompt phrase="W" filename="119.wav"/>
|
||||
<prompt phrase="X" filename="120.wav"/>
|
||||
<prompt phrase="Y" filename="121.wav"/>
|
||||
<prompt phrase="Z" filename="122.wav"/>
|
||||
</ascii>
|
||||
<phonetic-ascii>
|
||||
<prompt phrase="Espacio" filename="32.wav"/>
|
||||
<prompt phrase="Punto" filename="46.wav"/>
|
||||
<prompt phrase="Alpha" filename="97.wav"/>
|
||||
<prompt phrase="Bravo" filename="98.wav"/>
|
||||
<prompt phrase="Charlie" filename="99.wav"/>
|
||||
<prompt phrase="Delta" filename="100.wav"/>
|
||||
<prompt phrase="Echo" filename="101.wav"/>
|
||||
<prompt phrase="Foxtrot" filename="102.wav"/>
|
||||
<prompt phrase="Golf" filename="103.wav"/>
|
||||
<prompt phrase="Hotel" filename="104.wav"/>
|
||||
<prompt phrase="India" filename="105.wav"/>
|
||||
<prompt phrase="Juliet" filename="106.wav"/>
|
||||
<prompt phrase="Kilo" filename="107.wav"/>
|
||||
<prompt phrase="Lima" filename="108.wav"/>
|
||||
<prompt phrase="Mike" filename="109.wav"/>
|
||||
<prompt phrase="November" filename="110.wav"/>
|
||||
<prompt phrase="Oscar" filename="111.wav"/>
|
||||
<prompt phrase="Papa" filename="112.wav"/>
|
||||
<prompt phrase="Quebec" filename="113.wav"/>
|
||||
<prompt phrase="Romeo" filename="114.wav"/>
|
||||
<prompt phrase="Sierra" filename="115.wav"/>
|
||||
<prompt phrase="Tango" filename="116.wav"/>
|
||||
<prompt phrase="Unifor" filename="117.wav"/>
|
||||
<prompt phrase="Victor" filename="118.wav"/>
|
||||
<prompt phrase="Whiskey" filename="119.wav"/>
|
||||
<prompt phrase="Xray" filename="120.wav"/>
|
||||
<prompt phrase="Yankee" filename="121.wav"/>
|
||||
<prompt phrase="Zulu" filename="122.wav"/>
|
||||
</phonetic-ascii>
|
||||
<digits>
|
||||
<prompt phrase="Cero" filename="0.wav"/>
|
||||
<prompt phrase="Uno" filename="1.wav"/>
|
||||
<prompt phrase="Dos" filename="2.wav"/>
|
||||
<prompt phrase="Tres" filename="3.wav"/>
|
||||
<prompt phrase="Cuatro" filename="4.wav"/>
|
||||
<prompt phrase="Cinco" filename="5.wav"/>
|
||||
<prompt phrase="Seis" filename="6.wav"/>
|
||||
<prompt phrase="Siete" filename="7.wav"/>
|
||||
<prompt phrase="Ocho" filename="8.wav"/>
|
||||
<prompt phrase="Nueve" filename="9.wav"/>
|
||||
<prompt phrase="Diez" filename="10.wav"/>
|
||||
<prompt phrase="Once" filename="11.wav"/>
|
||||
<prompt phrase="Doce" filename="12.wav"/>
|
||||
<prompt phrase="Trece" filename="13.wav"/>
|
||||
<prompt phrase="Catorce" filename="14.wav"/>
|
||||
<prompt phrase="Quince" filename="15.wav"/>
|
||||
<prompt phrase="Dieciséis" filename="16.wav"/>
|
||||
<prompt phrase="Diecisiete" filename="17.wav"/>
|
||||
<prompt phrase="Dieciocho" filename="18.wav"/>
|
||||
<prompt phrase="Diecinueve" filename="19.wav"/>
|
||||
<prompt phrase="Veinte" filename="20.wav"/>
|
||||
<prompt phrase="Veinti" filename="veinti.wav"/>
|
||||
<prompt phrase="Treinta" filename="30.wav"/>
|
||||
<prompt phrase="Cuarenta" filename="40.wav"/>
|
||||
<prompt phrase="Cincuenta" filename="50.wav"/>
|
||||
<prompt phrase="Sesenta" filename="60.wav"/>
|
||||
<prompt phrase="Setenta" filename="70.wav"/>
|
||||
<prompt phrase="Ochenta" filename="80.wav"/>
|
||||
<prompt phrase="Noventa" filename="90.wav"/>
|
||||
<prompt phrase="Cien" filename="100.wav"/>
|
||||
<prompt phrase="Quinientos" filename="500.wav"/>
|
||||
<prompt phrase="Setecientos" filename="700.wav"/>
|
||||
<prompt phrase="Novecientos" filename="900.wav"/>
|
||||
<prompt phrase="Punto" filename="dot.wav"/>
|
||||
<prompt phrase="Primero" filename="h-1.wav"/>
|
||||
<prompt phrase="Segundo" filename="h-2.wav"/>
|
||||
<prompt phrase="Tercero" filename="h-3.wav"/>
|
||||
<prompt phrase="Cuarto" filename="h-4.wav"/>
|
||||
<prompt phrase="Quinto" filename="h-5.wav"/>
|
||||
<prompt phrase="Sexto" filename="h-6.wav"/>
|
||||
<prompt phrase="Séptimo" filename="h-7.wav"/>
|
||||
<prompt phrase="Octavo" filename="h-8.wav"/>
|
||||
<prompt phrase="Noveno" filename="h-9.wav"/>
|
||||
<prompt phrase="Décimo" filename="h-10.wav"/>
|
||||
<prompt phrase="Undécimo" filename="h-11.wav"/>
|
||||
<prompt phrase="Duodécimo" filename="h-12.wav"/>
|
||||
<prompt phrase="Decimotercero" filename="h-13.wav"/>
|
||||
<prompt phrase="Decimocuarto" filename="h-14.wav"/>
|
||||
<prompt phrase="Decimoquinto" filename="h-15.wav"/>
|
||||
<prompt phrase="Decimosexto" filename="h-16.wav"/>
|
||||
<prompt phrase="Decimoséptimo" filename="h-17.wav"/>
|
||||
<prompt phrase="Decimoctavo" filename="h-18.wav"/>
|
||||
<prompt phrase="Decimonoveno" filename="h-19.wav"/>
|
||||
<prompt phrase="Vigésimo" filename="h-20.wav"/>
|
||||
<prompt phrase="Trigésimo" filename="h-30.wav"/>
|
||||
<prompt phrase="Un" filename="un.wav"/>
|
||||
<prompt phrase="Ciento" filename="hundred.wav"/>
|
||||
<prompt phrase="Cientos" filename="hundreds.wav"/>
|
||||
<prompt phrase="Mil" filename="thousand.wav"/>
|
||||
<prompt phrase="Millón" filename="million.wav"/>
|
||||
<prompt phrase="Millones" filename="millions.wav"/>
|
||||
<prompt phrase="Período" filename="period.wav"/>
|
||||
<prompt phrase="Punto" filename="point.wav"/>
|
||||
<prompt phrase="Almohadilla" filename="pound.wav"/>
|
||||
<prompt phrase="Asterisco" filename="star.wav"/>
|
||||
</digits>
|
||||
<currency>
|
||||
<prompt phrase="Y" filename="and.wav"/>
|
||||
<prompt phrase="Céntimo" filename="cent.wav"/>
|
||||
<prompt phrase="Central" filename="central.wav"/>
|
||||
<prompt phrase="Céntimos por minuto" filename="cents-per-minute.wav"/>
|
||||
<prompt phrase="Céntimos" filename="cents.wav"/>
|
||||
<prompt phrase="Dólar" filename="dollar.wav"/>
|
||||
<prompt phrase="Dólares" filename="dollars.wav"/>
|
||||
<prompt phrase="Menos" filename="minus.wav"/>
|
||||
<prompt phrase="Negativo" filename="negative.wav"/>
|
||||
</currency>
|
||||
<time>
|
||||
<prompt phrase="A.M." filename="a-m.wav"/>
|
||||
<prompt phrase="A la..." filename="at.wav"/>
|
||||
<prompt phrase="A las..." filename="ats.wav"/>
|
||||
<prompt phrase="Domingo" filename="day-0.wav"/>
|
||||
<prompt phrase="Lunes" filename="day-1.wav"/>
|
||||
<prompt phrase="Martes" filename="day-2.wav"/>
|
||||
<prompt phrase="Miércoles" filename="day-3.wav"/>
|
||||
<prompt phrase="Jueves" filename="day-4.wav"/>
|
||||
<prompt phrase="Viernes" filename="day-5.wav"/>
|
||||
<prompt phrase="Sábado" filename="day-6.wav"/>
|
||||
<prompt phrase="Hora" filename="hour.wav"/>
|
||||
<prompt phrase="Horas" filename="hours.wav"/>
|
||||
<prompt phrase="Minuto" filename="minute.wav"/>
|
||||
<prompt phrase="Minutos" filename="minutes.wav"/>
|
||||
<prompt phrase="Enero" filename="mon-0.wav"/>
|
||||
<prompt phrase="Febrero" filename="mon-1.wav"/>
|
||||
<prompt phrase="Marzo" filename="mon-2.wav"/>
|
||||
<prompt phrase="Abril" filename="mon-3.wav"/>
|
||||
<prompt phrase="Mayo" filename="mon-4.wav"/>
|
||||
<prompt phrase="Junio" filename="mon-5.wav"/>
|
||||
<prompt phrase="Julio" filename="mon-6.wav"/>
|
||||
<prompt phrase="Agosto" filename="mon-7.wav"/>
|
||||
<prompt phrase="Septiembre" filename="mon-8.wav"/>
|
||||
<prompt phrase="Octubre" filename="mon-9.wav"/>
|
||||
<prompt phrase="Noviembre" filename="mon-10.wav"/>
|
||||
<prompt phrase="Diciembre" filename="mon-11.wav"/>
|
||||
<prompt phrase="En punto" filename="oclock.wav"/>
|
||||
<prompt phrase="P.M." filename="p-m.wav"/>
|
||||
<prompt phrase="Segundo" filename="second.wav"/>
|
||||
<prompt phrase="Segundos" filename="seconds.wav"/>
|
||||
<prompt phrase="Hoy" filename="today.wav"/>
|
||||
<prompt phrase="Mañana" filename="tomorrow.wav"/>
|
||||
<prompt phrase="Ayer" filename="yesterday.wav"/>
|
||||
</time>
|
||||
<voicemail>
|
||||
<prompt phrase="La persona en la extensión..." filename="vm-person.wav"/>
|
||||
<prompt phrase="Marcado urgente." filename="vm-marked-urgent.wav"/>
|
||||
<prompt phrase="Enviado por correo electrónico." filename="vm-emailed.wav"/>
|
||||
<prompt phrase="Usted tiene..." filename="vm-you_have.wav"/>
|
||||
<prompt phrase="Por favor introduzca su número de usuario, seguido por..." filename="vm-enter_id.wav"/>
|
||||
<prompt phrase="Por favor introduzca su contraseña, seguido por..." filename="vm-enter_pass.wav"/>
|
||||
<prompt phrase="Inicio de sesión incorrecto." filename="vm-fail_auth.wav"/>
|
||||
<prompt phrase="Bienvenido a su buzón de voz." filename="vm-hello.wav"/>
|
||||
<prompt phrase="Adiós" filename="vm-goodbye.wav"/>
|
||||
<prompt phrase="Por favor grabe su nombre después de la señal, pulse cualquier tecla o deje de hablar para poner fin a la grabación." filename="vm-record_name1.wav"/>
|
||||
<prompt phrase="Elija un saludo entre 1 y 9." filename="vm-choose_greeting_choose.wav"/>
|
||||
<prompt phrase="Valor inválido." filename="vm-choose_greeting_fail.wav"/>
|
||||
<prompt phrase="Demasiados intentos fallidos." filename="vm-abort.wav"/>
|
||||
<prompt phrase="Para cambiar su contraseña..." filename="vm-change_password.wav"/>
|
||||
<prompt phrase="Grabe su saludo después de la señal, pulse cualquier tecla o deje de hablar para poner fin a la grabación." filename="vm-record_greeting.wav"/>
|
||||
<prompt phrase="Grabe su mensaje después de la señal, pulse cualquier tecla o deje de hablar para poner fin a la grabación." filename="vm-record_message.wav"/>
|
||||
<prompt phrase="...no está disponible." filename="vm-play_greeting.wav"/>
|
||||
<prompt phrase="Urgente nuevo." filename="vm-urgent-new.wav"/>
|
||||
<prompt phrase="Nuevo" filename="vm-new.wav"/>
|
||||
<prompt phrase="Urgente guardado" filename="vm-urgent-saved.wav"/>
|
||||
<prompt phrase="Guardado" filename="vm-saved.wav"/>
|
||||
<prompt phrase="Mensaje" filename="vm-message.wav"/>
|
||||
<prompt phrase="Mensajes" filename="vm-messages.wav"/>
|
||||
<prompt phrase="Pulse" filename="vm-press.wav"/>
|
||||
<prompt phrase="Para escuchar mensajes nuevos..." filename="vm-listen_new.wav"/>
|
||||
<prompt phrase="Para escuchar mensajes guardados..." filename="vm-listen_saved.wav"/>
|
||||
<prompt phrase="Para opciones avanzadas..." filename="vm-advanced.wav"/>
|
||||
<prompt phrase="Para salir..." filename="vm-to_exit.wav"/>
|
||||
<prompt phrase="Para grabar un saludo..." filename="vm-record_greeting.wav"/>
|
||||
<prompt phrase="Para elegir un saludo..." filename="vm-choose_greeting.wav"/>
|
||||
<prompt phrase="Para grabar su nombre..." filename="vm-record_name2.wav"/>
|
||||
<prompt phrase="Para el menú principal..." filename="vm-main_menu.wav"/>
|
||||
<prompt phrase="Para escuchar la grabación..." filename="vm-listen_to_recording.wav"/>
|
||||
<prompt phrase="Para guardar la grabación..." filename="vm-save_recording.wav"/>
|
||||
<prompt phrase="Para regrabar..." filename="vm-rerecord.wav"/>
|
||||
<prompt phrase="Para marcar este mensaje como urgente..." filename="vm-mark-urgent.wav"/>
|
||||
<prompt phrase="Para continuar..." filename="vm-continue.wav"/>
|
||||
<prompt phrase="Para escuchar la grabación de nuevo..." filename="vm-listen_to_recording_again.wav"/>
|
||||
<prompt phrase="Para eliminar la grabación..." filename="vm-delete_recording.wav"/>
|
||||
<prompt phrase="Para enviar la grabación a su correo electrónico..." filename="vm-forward_to_email.wav"/>
|
||||
<prompt phrase="Saludo" filename="vm-greeting.wav"/>
|
||||
<prompt phrase="Seleccionado" filename="vm-selected.wav"/>
|
||||
<prompt phrase="...no está disponible." filename="vm-not_available.wav"/>
|
||||
<prompt phrase="Mensaje número..." filename="vm-message_number.wav"/>
|
||||
<prompt phrase="Eliminado" filename="vm-deleted.wav"/>
|
||||
<prompt phrase="Su grabación es demasiado corta, por favor intente de nuevo." filename="vm-too-small.wav"/>
|
||||
<prompt phrase="...en la bandeja de entrada." filename="vm-in_folder.wav"/>
|
||||
<prompt phrase="Para devolver la llamada..." filename="vm-return_call.wav"/>
|
||||
<prompt phrase="Urgente" filename="vm-urgent.wav"/>
|
||||
<prompt phrase="Este buzón está lleno. Por favor intente llamar mas tarde." filename="vm-mailbox_full.wav"/>
|
||||
<prompt phrase="Bienvenido a su nuevo buzón de voz. Para escuchar el tutorial y configurar su buzón, pulse 1. Para saltarlo pulse 2." filename="vm-tutorial_yes_no.wav"/>
|
||||
<prompt phrase="Necesito grabar su nombre y apellido. Esta grabación se usará entre otros en el servicio de directorio." filename="vm-tutorial_record_name.wav"/>
|
||||
<prompt phrase="Su número de identificación personal o PIN sirve para impedir a terceros el acceso a sus mensajes. Desea cambiar su PIN ahora?" filename="vm-tutorial_change_pin.wav"/>
|
||||
</voicemail>
|
||||
<directory>
|
||||
<prompt phrase="Por favor introduzca las primeras letras del nombre buscado." filename="dir-enter_person.wav"/>
|
||||
<prompt phrase="...apellido..." filename="dir-last_name.wav"/>
|
||||
<prompt phrase="Para buscar por..." filename="dir-to_search_by.wav"/>
|
||||
<prompt phrase="...nombre..." filename="dir-first_name.wav"/>
|
||||
<prompt phrase="No hay resultados que coincidan con su busqueda." filename="dir-no_matching_results.wav"/>
|
||||
<prompt phrase="...resultados coinciden con su busqueda." filename="dir-result_match.wav"/>
|
||||
<prompt phrase="Su busqueda genera demasiados resultados." filename="dir-too_many_result.wav"/>
|
||||
<prompt phrase="No hay más resultados." filename="dir-no_more_results.wav"/>
|
||||
<prompt phrase="Resultado número..." filename="dir-result_number.wav"/>
|
||||
<prompt phrase="...en la extensión..." filename="dir-at_extension.wav"/>
|
||||
<prompt phrase="Para seleccionar este resultado..." filename="dir-to_select_entry.wav"/>
|
||||
<prompt phrase="Para el resultado siguiente..." filename="dir-for_next.wav"/>
|
||||
<prompt phrase="Para el resultado previo..." filename="dir-for_prev.wav"/>
|
||||
<prompt phrase="Para empezar una nueva busqueda..." filename="dir-start_new_search.wav"/>
|
||||
<prompt phrase="Necesita especificar un mínimo de..." filename="dir-specify_mininum.wav"/>
|
||||
<prompt phrase="...letras del nombre buscado." filename="dir-letters_of_person_name.wav"/>
|
||||
<prompt phrase="Por favor intente de nuevo." filename="dir-please_try_again.wav"/>
|
||||
<prompt phrase="Pulse..." filename="dir-press.wav" info="we can copy vm/vm-press.wav"/>
|
||||
</directory>
|
||||
<conference>
|
||||
<prompt phrase="NULL" filename="conf-ack.wav" type="tone"/>
|
||||
<prompt phrase="NULL" filename="conf-nack.wav" type="tone"/>
|
||||
<prompt phrase="Su voz ha sido silenciada." filename="conf-muted.wav"/>
|
||||
<prompt phrase="Su voz ha sido habilitada." filename="conf-unmuted.wav"/>
|
||||
<prompt phrase="En este momento usted es la única persona en la conferencia." filename="conf-alone.wav"/>
|
||||
<prompt phrase="NULL" filename="conf-perpetual.wav" type="music"/>
|
||||
<prompt phrase="NULL" filename="conf-enter.wav" type="tone"/>
|
||||
<prompt phrase="NULL" filename="conf-exit.wav" type="tone"/>
|
||||
<prompt phrase="Usted ha sido expulsado de la conferencia." filename="conf-kicked.wav"/>
|
||||
<prompt phrase="Esta conferencia está bloqueada." filename="conf-locked.wav"/>
|
||||
<prompt phrase="La conferencia está ahora bloqueada." filename="conf-is-locked.wav"/>
|
||||
<prompt phrase="La conferencia está ahora desbloqueada." filename="conf-is-unlocked.wav"/>
|
||||
<prompt phrase="Por favor ingrese el PIN de la conferencia." filename="conf-pin.wav"/>
|
||||
<prompt phrase="PIN inválido, intente de nuevo." filename="conf-bad-pin.wav"/>
|
||||
<prompt phrase="Hasta luego." filename="conf-goodbye.wav"/>
|
||||
<prompt phrase="Bienvenido a la conferencia." filename="conf-welcome.wav"/>
|
||||
</conference>
|
||||
<ivr>
|
||||
<prompt phrase="Número de cuenta" filename="ivr-account_number.wav"/>
|
||||
<prompt phrase="Conectar con el llamante" filename="ivr-connect_to_caller.wav"/>
|
||||
<prompt phrase="Si conoce la extensión de su destino, por favor marquela ahora." filename="ivr-enter_ext_pound.wav"/>
|
||||
<prompt phrase="Por favor ingrese un número de extensión seguido por la tecla almohadilla." filename="ivr-enter_ext.wav"/>
|
||||
<prompt phrase="Para esta persona..." filename="ivr-for_this_person.wav"/>
|
||||
<prompt phrase="Por favor espere mientras se conecta su llamada." filename="ivr-hold_connect_call.wav"/>
|
||||
<prompt phrase="Lo siento..." filename="ivr-im_sorry.wav"/>
|
||||
<prompt phrase="Por favor..." filename="ivr-please.wav"/>
|
||||
<prompt phrase="Por favor devuelva nuestra llamada al..." filename="ivr-please_return_our_call_at.wav"/>
|
||||
<prompt phrase="Acerca del número de referencia..." filename="ivr-regarding_reference_number.wav"/>
|
||||
<prompt phrase="Este es un ejemplo de un submenú." filename="ivr-sample_submenu.wav"/>
|
||||
<prompt phrase="Por favor diga su nombre después del tono." filename="ivr-say_name.wav"/>
|
||||
<prompt phrase="Enviar a este llamante al buzón de voz." filename="ivr-send_to_voicemail.wav"/>
|
||||
<prompt phrase="Para hablar con un representante del servicio de atención al cliente..." filename="ivr-speak_to_a_customer_service_representative.wav"/>
|
||||
<prompt phrase="Tomar un mensaje" filename="ivr-take_a_message.wav"/>
|
||||
<prompt phrase="Gracias" filename="ivr-thank_you.wav"/>
|
||||
<prompt phrase="Esa fue una entrada inválida." filename="ivr-that_was_an_invalid_entry.wav"/>
|
||||
<prompt phrase="Esta es una llamada de..." filename="ivr-this_is_a_call_from.wav"/>
|
||||
<prompt phrase="Este menú de voz le permitirá probar algunas de las funciones..." filename="ivr-this_ivr_will_let_you_test_features.wav"/>
|
||||
<prompt phrase="Para llamar a la conferencia de FreeSWITCH..." filename="ivr-to_call_the_freeswitch_conference.wav"/>
|
||||
<prompt phrase="Para hacer una prueba de eco de FreeSWITCH..." filename="ivr-to_do_a_freeswitch_echo_test.wav"/>
|
||||
<prompt phrase="Para hacer una prueba de eco de FWD..." filename="ivr-to_do_a_fwd_echo_test.wav"/>
|
||||
<prompt phrase="Para escuchar un ejemplo de un submenú..." filename="ivr-to_hear_sample_submenu.wav"/>
|
||||
<prompt phrase="Para escuchar simios gritando..." filename="ivr-to_hear_screaming_monkeys.wav"/>
|
||||
<prompt phrase="Para escuchar música de llamada en espera..." filename="ivr-to_listen_to_moh.wav"/>
|
||||
<prompt phrase="Para repetir estas opciones..." filename="ivr-to_repeat_these_options.wav"/>
|
||||
<prompt phrase="Para volver al menú anterior..." filename="ivr-to_return_to_previous_menu.wav"/>
|
||||
<prompt phrase="Para hablar con una operadora..." filename="ivr-to_speak_with_an_operator.wav"/>
|
||||
<prompt phrase="Bienvenido a FreeSWITCH, el futuro de la telefonía." filename="ivr-welcome_to_freeswitch.wav"/>
|
||||
<prompt phrase="Usted puede colgar en cualquier momento para salir." filename="ivr-you_may_exit_by_hanging_up.wav"/>
|
||||
<prompt phrase="O" filename="ivr-or.wav"/>
|
||||
<prompt phrase="No" filename="ivr-not.wav"/>
|
||||
<prompt phrase="Llamar" filename="ivr-call.wav"/>
|
||||
<prompt phrase="Usted puede..." filename="ivr-you_may.wav"/>
|
||||
<prompt phrase="Hola" filename="ivr-hello.wav"/>
|
||||
<prompt phrase="Usando el teclado de su teléfono..." filename="ivr-use_telephone_keypad.wav"/>
|
||||
<prompt phrase="Por favor deletree el nombre de la persona con la cual está intentando contactar." filename="ivr-spell_name.wav"/>
|
||||
<prompt phrase="Primero el apellido" filename="ivr-last_name_first.wav"/>
|
||||
<prompt phrase="Primero el nombre" filename="ivr-first_name_first.wav"/>
|
||||
<prompt phrase="Pulse 1 para Q ó Z." filename="ivr-press_one_q_or_z.wav"/>
|
||||
<prompt phrase="Ventas" filename="ivr-sales.wav"/>
|
||||
<prompt phrase="Servicio de atención al cliente" filename="ivr-customer_service.wav"/>
|
||||
<prompt phrase="Soporte técnico" filename="ivr-technical_support.wav"/>
|
||||
<prompt phrase="Operador" filename="ivr-operator.wav"/>
|
||||
<prompt phrase="Usted marcó una extensión inválida." filename="ivr-you_have_dialed_an_invalid_extension.wav"/>
|
||||
<prompt phrase="Por favor introduzca su número de extensión, seguido de la tecla almohadilla." filename="ivr-please_enter_extension_followed_by_pound.wav"/>
|
||||
<prompt phrase="Por favor introduzca su contraseña, seguido de la tecla almohadilla." filename="ivr-please_enter_pin_followed_by_pound.wav"/>
|
||||
<prompt phrase="Su contraseña o extensión es inválida." filename="ivr-pin_or_extension_is-invalid.wav"/>
|
||||
<prompt phrase="Usted esta a punto de asociar este teléfono a su cuenta..." filename="ivr-you_are_about_to_provision_this_phone.wav"/>
|
||||
<prompt phrase="Por favor vuelva a introducir su contraseña para confirmar." filename="ivr-please_reenter_your_pin.wav"/>
|
||||
<prompt phrase="Para registrarse en ClueCon, por favor pulse..." filename="ivr-register_for_cluecon.wav"/>
|
||||
<prompt phrase="Para conectarse..." filename="ivr-to_log_in.wav"/>
|
||||
<prompt phrase="Para desconectarse..." filename="ivr-to_log_out.wav"/>
|
||||
<prompt phrase="Usted está ahora conectado." filename="ivr-you_are_now_logged_in.wav"/>
|
||||
<prompt phrase="Usted está ahora desconectado." filename="ivr-you_are_now_logged_out.wav"/>
|
||||
<prompt phrase="Por favor intente de nuevo." filename="ivr-please_try_again.wav"/>
|
||||
<prompt phrase="Usted está a punto de asociar este teléfono a su cuenta de forma permanente." filename="ivr-provision_phone_permanently_to_extension.wav"/>
|
||||
<prompt phrase="Por favor introduzca su número de extensión con la cual desea asociar su teléfono, seguido de la tecla almohadilla." filename="ivr-extension_to_provision_this_phone.wav"/>
|
||||
<prompt phrase="Gracias, este teléfono va a reiniciarse ahora." filename="ivr-this_phone_will_now_reboot.wav"/>
|
||||
<prompt phrase="Gracias, su grabación ha sido guardada." filename="ivr-recording_saved.wav"/>
|
||||
<prompt phrase="Pulse 1 para guardar su grabación. Pulse 2 para escuchar su grabación. Pulse 3 para volver a grabar." filename="ivr-save_review_record.wav"/>
|
||||
<prompt phrase="En este momento, el sistema no puede guardar su fichero de audio. Por favor intente de nuevo." filename="ivr-unable_save.wav"/>
|
||||
<prompt phrase="Usted está en la posición..." filename="ivr-you_are_number.wav"/>
|
||||
<prompt phrase="...en la cola de espera." filename="ivr-in_line.wav"/>
|
||||
<prompt phrase="Gracias por permanecer en espera." filename="ivr-thank_you_for_holding.wav"/>
|
||||
<prompt phrase="El tiempo estimado de espera es..." filename="ivr-estimated_hold_time.wav"/>
|
||||
<prompt phrase="Más de..." filename="ivr-more_than.wav"/>
|
||||
<prompt phrase="Menos de..." filename="ivr-less_than.wav"/>
|
||||
<prompt phrase="Empieze a grabar." filename="ivr-begin_recording.wav "/>
|
||||
<prompt phrase="El desvío de llamada ha sido desactivado." filename="ivr-call_forwarding_has_been_cancelled.wav"/>
|
||||
<prompt phrase="El desvío de llamada ha sido activado." filename="ivr-call_forwarding_has_been_set.wav"/>
|
||||
<prompt phrase="Por favor introduzca el número de teléfono." filename="ivr-please_enter_the_phone_number.wav"/>
|
||||
<prompt phrase="Por favor diga su nombre, y la razón de la llamada." filename="ivr-please_state_your_name_and_reason_for_calling.wav"/>
|
||||
<prompt phrase="Para aceptar, pulse 1. Para rechazar, pulse 2. Para enviar al buzón de voz, pulse 3." filename="ivr-accept_reject_voicemail.wav"/>
|
||||
<prompt phrase="Llamada entrante." filename="ivr-incoming_call.wav"/>
|
||||
<prompt phrase="Gracias por llamar." filename="ivr-thank_you_for_calling.wav"/>
|
||||
<prompt phrase="Por favor mentengase a la espera. Su llamada será atendida en un momento." filename="ivr-stay_on_line_call_answered_momentarily.wav"/>
|
||||
<prompt phrase="Su llamada está siendo procesada." filename="ivr-call_being_transferred.wav"/>
|
||||
<prompt phrase="Por favor disfrute de la música mientras su llamada está siendo procesada..." filename="ivr-enjoy_music_while_transfer.wav"/>
|
||||
<prompt phrase="Usted tiene una llamada de..." filename="ivr-call_from.wav"/>
|
||||
<prompt phrase="Este menú no tiene entradas. Por favor contacte con el administrador." filename="ivr-no_menu_items.wav"/>
|
||||
<prompt phrase="Para el servicio de directorio, pulse..." filename="ivr-for_directory_press.wav"/>
|
||||
<prompt phrase="Usando las teclas de su teléfono..." filename="ivr-using_telephone_keypad.wav"/>
|
||||
<prompt phrase="Introduzca las primeras letras del apellido de la persona." filename="ivr-enter_letters_last_name.wav"/>
|
||||
<prompt phrase="Introduzca las primeras letras del nombre de la persona." filename="ivr-enter_letters_first_name.wav"/>
|
||||
<prompt phrase="Introduzca las primeras letras del nombre o apellido de la persona." filename="ivr-enter_letters_first_or_last_name.wav"/>
|
||||
<prompt phrase="Si es correcto, pulse..." filename="ivr-if_correct_press.wav"/>
|
||||
<prompt phrase="Sino, pulse..." filename="ivr-if_not_press.wav"/>
|
||||
<prompt phrase="Cuando termine, pulse la tecla almohadilla." filename="ivr-finished_pound_hash_key.wav"/>
|
||||
<prompt phrase="La función de No Molestar ha sido activada." filename="ivr-dnd_activated.wav"/>
|
||||
<prompt phrase="La función de No Molestar ha sido desactivada." filename="ivr-dnd_cancelled.wav"/>
|
||||
<prompt phrase="Pulse cualquier otro dígito..." filename="ivr-any_other_digit.wav"/>
|
||||
<prompt phrase="Pulse uno si su respuesta es sí. Pulse dos si su respuesta es no." filename="ivr-one_yes_two_no.wav"/>
|
||||
<prompt phrase="Por favor introduzca el número de la cola, seguido de la tecla almohadilla." filename="ivr-enter_queue_number.wav"/>
|
||||
<prompt phrase="Por favor introduzca el..." filename="ivr-please_enter_the.wav"/>
|
||||
<prompt phrase="Número." filename="ivr-number.wav"/>
|
||||
<prompt phrase="...seguido de la tecla almohadilla." filename="ivr-followed_by_pound.wav"/>
|
||||
<prompt phrase="El balance de la cuenta es..." filename="ivr-account_balance_is.wav"/>
|
||||
<prompt phrase="Gracias por llamar. Si conoce la extensión de su destino, por favor marquela ahora. Para acceder al directorio, pulse..." filename="ivr-generic_greeting.wav"/>
|
||||
<prompt phrase="...fichero..." filename="ivr-file.wav"/>
|
||||
<prompt phrase="...ficheros..." filename="ivr-files-.wav"/>
|
||||
<prompt phrase="Para una llamada de despertador..." filename="ivr-for_a_wakeup_call.wav"/>
|
||||
<prompt phrase="Este es el servicio de despertador." filename="ivr-this_is_your_wakeup_call.wav"/>
|
||||
<prompt phrase="Para solicitar una llamada de despertador..." filename="ivr-request_wakeup_call.wav"/>
|
||||
<prompt phrase="Para confirmar la llamada de despertador..." filename="ivr-confirm_wakeup_call.wav"/>
|
||||
<prompt phrase="Para anular la llamada de despertador..." filename="ivr-cancel_wakeup_call.wav"/>
|
||||
<prompt phrase="Usted ha solicitado una llamada de despertador para..." filename="ivr-requested_wakeup_call_for.wav"/>
|
||||
<prompt phrase="Usted no ha solicitado llamadas de despertador." filename="ivr-not_requested_wakeup_call.wav"/>
|
||||
<prompt phrase="Su llamada de despertador ha sido anulada." filename="ivr-wakeup_call_cancelled.wav"/>
|
||||
<prompt phrase="Para una llamada diaria de despertador..." filename="ivr-for_daily_wakeup_call.wav"/>
|
||||
<prompt phrase="Llamada diaria de despertador..." filename="ivr-daily_wakeup_call.wav"/>
|
||||
<prompt phrase="Para llamadas diarias de despertador..." filename="ivr-for_daily_wakeup_calls.wav"/>
|
||||
<prompt phrase="Para una llamada de despertador única..." filename="ivr-for_one_time_wakeup_call.wav"/>
|
||||
<prompt phrase="Llamada de despertador única..." filename="ivr-one_time_wakeup_call.wav"/>
|
||||
<prompt phrase="...llamada de despertador..." filename="ivr-wakeup_call.wav"/>
|
||||
<prompt phrase="¡Vamos despierta cielo!" filename="ivr-wakey_wakey_sunshine.wav"/>
|
||||
<prompt phrase="Bienvenido." filename="ivr-welcome.wav"/>
|
||||
<prompt phrase="Bienvenido a..." filename="ivr-welcome_to.wav"/>
|
||||
<prompt phrase="Buenos días." filename="ivr-good_morning.wav"/>
|
||||
<prompt phrase="Buenas tardes." filename="ivr-good_afternoon.wav"/>
|
||||
<prompt phrase="Buenas noches." filename="ivr-good_evening.wav"/>
|
||||
<prompt phrase="Gracias." filename="ivr-Thank_you.wav"/>
|
||||
<prompt phrase="Para..." filename="ivr-for.wav"/>
|
||||
<prompt phrase="El tiempo de espera esta siendo anormalmente elevado." filename="ivr-longer_than_usual_hold_times.wav"/>
|
||||
<prompt phrase="Usted es el..." filename="ivr-you_are_the.wav"/>
|
||||
<prompt phrase="Un momento por favor." filename="ivr-one_moment_please.wav"/>
|
||||
<prompt phrase="Su llamada será atendida según el orden de entrada." filename="ivr-call_answered_order_received.wav"/>
|
||||
<prompt phrase="Por favor introduzca el número de conferencia, seguido de la tecla almohadilla." filename="conf-enter_conf_number.wav"/>
|
||||
<prompt phrase="Introduzca el PIN de la conferencia, seguido de la tecla almohadilla." filename="conf-enter_conf_pin.wav"/>
|
||||
<prompt phrase="...se incorporó a la conferencia." filename="conf-has_joined.wav"/>
|
||||
<prompt phrase="...ha abandonado la conferencia." filename="conf-has_left.wav"/>
|
||||
<prompt phrase="Usted entró..." filename="ivr-you_entered.wav"/>
|
||||
<prompt phrase="Número de extensión..." filename="ivr-extension_number.wav"/>
|
||||
<prompt phrase="Por favor mantengase a la espera mientras contactamos con su destino." filename="ivr-please_hold_while_party_contacted.wav"/>
|
||||
<prompt phrase="Por favor disfrute de la música mientras le conectamos con su destino." filename="ivr-please_enjoy_music_while_party_reached.wav"/>
|
||||
<prompt phrase="Gracias por llamar. Si conoce la extensión de su destino, por favor marquela ahora, o marque nueve para el servicio de directorio." filename="ivr-generic_greeting.wav"/>
|
||||
<prompt phrase="Si es correcto, pulse 1. Sino, pulse 2." filename="ivr-if_correct_one_if_not_two.wav"/>
|
||||
<prompt phrase="Para repetir esta información..." filename="ivr-repeat_this_information.wav"/>
|
||||
<prompt phrase="No no no!" filename="ivr-no_no_no.wav"/>
|
||||
<prompt phrase="Era su intención pulsar esta tecla?" filename="ivr-did_you_mean_to_press_key.wav"/>
|
||||
<prompt phrase="Pensaba Usted DE VERDAD pulsar esta tecla?" filename="ivr-seriously_mean_to_press_key.wav"/>
|
||||
<prompt phrase="Oh DA IGUAL." filename="ivr-oh_whatever.wav"/>
|
||||
<prompt phrase="Se acabó! Un error más y le colgaré a la cara." filename="ivr-one_more_mistake.wav"/>
|
||||
<prompt phrase="Felicitaciones. Ha pulsado estrella. Esto no significa que ES una estrella. Tan solo significa que puede pulsar teclas y probablemente tiene dedos." filename="ivr-congratulations_you_pressed_star.wav"/>
|
||||
<prompt phrase="Todos nuestros ingenieros están ocupados en demostrar lo impresionante que es el CudaTel." filename="ivr-engineers_busy_assisting_other_sales.wav"/>
|
||||
<prompt phrase="La persona con la que intenta hablar no está disponible y no tiene buzón de voz." filename="vm-not_available_no_voicemail.wav"/>
|
||||
<prompt phrase="Este mensaje se auto-destruira en 5, 4, 3, 2, 1..." filename="ivr-message_self_destruct.wav"/>
|
||||
<prompt phrase="Su llamada ya está silenciada." filename="conf-you_are_already_muted.wav"/>
|
||||
<prompt phrase="Su llamada ha sido silenciada en ambos sentidos." filename="conf-you_are_now_bidirectionally_muted.wav"/>
|
||||
<prompt phrase="Todas sus llamadas nos pertenecen." filename="ivr-all_your_call_are_belong_to_us.wav"/>
|
||||
<prompt phrase="Me encanta como está pulsando estas teclas!" filename="ivr-love_those_touch_tones.wav"/>
|
||||
<prompt phrase="No, no tenemos bananas." filename="ivr-yes_we_have_no_bananas.wav"/>
|
||||
<prompt phrase="Está haciendo el ridículo!" filename="ivr-dude_you_suck.wav"/>
|
||||
<prompt phrase="Su llamada es muy importante para nosotros, pero su bienestar mental no lo es, así que estamos felices mantenerle a la espera, torturándole indefinidamente con nuestra pésima música en espera." filename="ivr-on_hold_indefinitely.wav"/>
|
||||
<prompt phrase="...ha abandonado el edificio." filename="ivr-has_left_the_building.wav"/>
|
||||
<prompt phrase="Este teléfono no está asignado y no puede ser usado para realizar llamadas externas." filename="ivr-phone_is_unassigned.wav"/>
|
||||
<prompt phrase="Este teléfono no está configurado correctamente." filename="ivr-phone_not_configured.wav"/>
|
||||
<prompt phrase="Felicitaciones! Este teléfono está configurado correctamente y puede ahora ser asociado a un usuario." filename="ivr-phone_is_configured_properly.wav"/>
|
||||
<prompt phrase="Por favor contacte con el administrador del sistema para obtener asistencia." filename="ivr-contact_system_administrator.wav"/>
|
||||
<prompt phrase="Barracuda Networks" filename="ivr-barracuda_networks.wav"/>
|
||||
<prompt phrase="CudaTel Communication Server" filename="ivr-cudatel_communication_server.wav"/>
|
||||
<prompt phrase="Por favor introduzca las primeras letras del nombre o apellido de la persona." filename="dir-enter_person_first_or_last.wav"/>
|
||||
<prompt phrase="No hay llamadas en espera en esta cola." filename="ivr-no_calls_waiting_in_queue.wav"/>
|
||||
<prompt phrase="Brian West" filename="misc-Brian_West.wav"/>
|
||||
<prompt phrase="Anthony Minessale" filename="misc-Anthony_Minessale.wav"/>
|
||||
<prompt phrase="Michael Jerris" filename="misc-Michael_Jerris.wav"/>
|
||||
<prompt phrase="Raymond Chandler" filename="misc-Raymond_Chandler.wav"/>
|
||||
<prompt phrase="Michael Collins" filename="misc-Michael_Collins.wav"/>
|
||||
<prompt phrase="Mark Mann" filename="misc-Mark_Mann.wav"/>
|
||||
<prompt phrase="William King" filename="misc-William_King.wav"/>
|
||||
<prompt phrase="Rudy Fleminger" filename="misc-Rudy_Fleminger.wav"/>
|
||||
<prompt phrase="Andrew Thompson" filename="misc-Andrew_Thompson.wav"/>
|
||||
<prompt phrase="Graham Saathoff" filename="misc-Graham_Saathoff.wav"/>
|
||||
<prompt phrase="Nicholaus Belluni" filename="misc-Nicholaus_Belluni.wav"/>
|
||||
<prompt phrase="Sean Heiney" filename="misc-Sean_Heiney.wav"/>
|
||||
</ivr>
|
||||
<misc>
|
||||
<prompt phrase="Esta llamada está ahora protegida." filename="call_secured.wav"/>
|
||||
<prompt phrase="...seguido de la tecla almohadilla." filename="followed.wav"/>
|
||||
<prompt phrase="Si usted es esta persona..." filename="if_you_are_this_person.wav"/>
|
||||
<prompt phrase="Si usted desea..." filename="if_you_would_like_to.wav"/>
|
||||
<prompt phrase="Por favor, introduzca el número de referencia." filename="provide_reference_number.wav"/>
|
||||
<prompt phrase="Por favor, marque la extensión a la cual desea transferir." filename="transfer1.wav"/>
|
||||
<prompt phrase="Transferir" filename="transfer2.wav"/>
|
||||
<prompt phrase="Estamos tratando de contactar..." filename="we_are_trying_to_reach.wav"/>
|
||||
<prompt phrase="Ha ocurrido un error, por favor contacte con el administrador." filename="error.wav"/>
|
||||
<prompt phrase="Su llamada será terminada en..." filename="misc-your_call_will_be_terminated_in.wav"/>
|
||||
<prompt phrase="Su llamada ha sido terminada." filename="misc-your_call_has_been_terminated.wav"/>
|
||||
</misc>
|
||||
<zrtp>
|
||||
<!-- base256 prompts for SAS -->
|
||||
<prompt phrase="Algol" filename="Algol.wav"/>
|
||||
<prompt phrase="Apollo" filename="Apollo.wav"/>
|
||||
<prompt phrase="Athens" filename="Athens.wav"/>
|
||||
<prompt phrase="Atlantic" filename="Atlantic.wav"/>
|
||||
<prompt phrase="Aztec" filename="Aztec.wav"/>
|
||||
<prompt phrase="Babylon" filename="Babylon.wav"/>
|
||||
<prompt phrase="Belfast" filename="Belfast.wav"/>
|
||||
<prompt phrase="Bradbury" filename="Bradbury.wav"/>
|
||||
<prompt phrase="Brazilian" filename="Brazilian.wav"/>
|
||||
<prompt phrase="Burbank" filename="Burbank.wav"/>
|
||||
<prompt phrase="Burlington" filename="Burlington.wav"/>
|
||||
<prompt phrase="Camelot" filename="Camelot.wav"/>
|
||||
<prompt phrase="Capricorn" filename="Capricorn.wav"/>
|
||||
<prompt phrase="Cherokee" filename="Cherokee.wav"/>
|
||||
<prompt phrase="Chicago" filename="Chicago.wav"/>
|
||||
<prompt phrase="Christmas" filename="Christmas.wav"/>
|
||||
<prompt phrase="Dakota" filename="Dakota.wav"/>
|
||||
<prompt phrase="December" filename="December.wav"/>
|
||||
<prompt phrase="Dupont" filename="Dupont.wav"/>
|
||||
<prompt phrase="Eskimo" filename="Eskimo.wav"/>
|
||||
<prompt phrase="Galveston" filename="Galveston.wav"/>
|
||||
<prompt phrase="Geiger" filename="Geiger.wav"/>
|
||||
<prompt phrase="Hamilton" filename="Hamilton.wav"/>
|
||||
<prompt phrase="Istanbul" filename="Istanbul.wav"/>
|
||||
<prompt phrase="Jamaica" filename="Jamaica.wav"/>
|
||||
<prompt phrase="Jupiter" filename="Jupiter.wav"/>
|
||||
<prompt phrase="Medusa" filename="Medusa.wav"/>
|
||||
<prompt phrase="Mohawk" filename="Mohawk.wav"/>
|
||||
<prompt phrase="Montana" filename="Montana.wav"/>
|
||||
<prompt phrase="Neptune" filename="Neptune.wav"/>
|
||||
<prompt phrase="Norwegian" filename="Norwegian.wav"/>
|
||||
<prompt phrase="Oakland" filename="Oakland.wav"/>
|
||||
<prompt phrase="October" filename="October.wav"/>
|
||||
<prompt phrase="Ohio" filename="Ohio.wav"/>
|
||||
<prompt phrase="Orlando" filename="Orlando.wav"/>
|
||||
<prompt phrase="Pacific" filename="Pacific.wav"/>
|
||||
<prompt phrase="Pandora" filename="Pandora.wav"/>
|
||||
<prompt phrase="Pegasus" filename="Pegasus.wav"/>
|
||||
<prompt phrase="Pluto" filename="Pluto.wav"/>
|
||||
<prompt phrase="Saturday" filename="Saturday.wav"/>
|
||||
<prompt phrase="Scotland" filename="Scotland.wav"/>
|
||||
<prompt phrase="Trojan" filename="Trojan.wav"/>
|
||||
<prompt phrase="Virginia" filename="Virginia.wav"/>
|
||||
<prompt phrase="Vulcan" filename="Vulcan.wav"/>
|
||||
<prompt phrase="Waterloo" filename="Waterloo.wav"/>
|
||||
<prompt phrase="Wichita" filename="Wichita.wav"/>
|
||||
<prompt phrase="Wilmington" filename="Wilmington.wav"/>
|
||||
<prompt phrase="Wyoming" filename="Wyoming.wav"/>
|
||||
<prompt phrase="Yucatan" filename="Yucatan.wav"/>
|
||||
<prompt phrase="Zulu" filename="Zulu.wav"/>
|
||||
<prompt phrase="aardvark" filename="aardvark.wav"/>
|
||||
<prompt phrase="absurd" filename="absurd.wav"/>
|
||||
<prompt phrase="accrue" filename="accrue.wav"/>
|
||||
<prompt phrase="acme" filename="acme.wav"/>
|
||||
<prompt phrase="adrift" filename="adrift.wav"/>
|
||||
<prompt phrase="adroitness" filename="adroitness.wav"/>
|
||||
<prompt phrase="adult" filename="adult.wav"/>
|
||||
<prompt phrase="adviser" filename="adviser.wav"/>
|
||||
<prompt phrase="afflict" filename="afflict.wav"/>
|
||||
<prompt phrase="aftermath" filename="aftermath.wav"/>
|
||||
<prompt phrase="aggregate" filename="aggregate.wav"/>
|
||||
<prompt phrase="ahead" filename="ahead.wav"/>
|
||||
<prompt phrase="aimless" filename="aimless.wav"/>
|
||||
<prompt phrase="alkali" filename="alkali.wav"/>
|
||||
<prompt phrase="allow" filename="allow.wav"/>
|
||||
<prompt phrase="almighty" filename="almighty.wav"/>
|
||||
<prompt phrase="alone" filename="alone.wav"/>
|
||||
<prompt phrase="ammo" filename="ammo.wav"/>
|
||||
<prompt phrase="amulet" filename="amulet.wav"/>
|
||||
<prompt phrase="amusement" filename="amusement.wav"/>
|
||||
<prompt phrase="ancient" filename="ancient.wav"/>
|
||||
<prompt phrase="antenna" filename="antenna.wav"/>
|
||||
<prompt phrase="apple" filename="apple.wav"/>
|
||||
<prompt phrase="applicant" filename="applicant.wav"/>
|
||||
<prompt phrase="armistice" filename="armistice.wav"/>
|
||||
<prompt phrase="article" filename="article.wav"/>
|
||||
<prompt phrase="artist" filename="artist.wav"/>
|
||||
<prompt phrase="assume" filename="assume.wav"/>
|
||||
<prompt phrase="asteroid" filename="asteroid.wav"/>
|
||||
<prompt phrase="atlas" filename="atlas.wav"/>
|
||||
<prompt phrase="atmosphere" filename="atmosphere.wav"/>
|
||||
<prompt phrase="autopsy" filename="autopsy.wav"/>
|
||||
<prompt phrase="baboon" filename="baboon.wav"/>
|
||||
<prompt phrase="backfield" filename="backfield.wav"/>
|
||||
<prompt phrase="backward" filename="backward.wav"/>
|
||||
<prompt phrase="backwater" filename="backwater.wav"/>
|
||||
<prompt phrase="banjo" filename="banjo.wav"/>
|
||||
<prompt phrase="barbecue" filename="barbecue.wav"/>
|
||||
<prompt phrase="beaming" filename="beaming.wav"/>
|
||||
<prompt phrase="bedlamp" filename="bedlamp.wav"/>
|
||||
<prompt phrase="beehive" filename="beehive.wav"/>
|
||||
<prompt phrase="beeswax" filename="beeswax.wav"/>
|
||||
<prompt phrase="befriend" filename="befriend.wav"/>
|
||||
<prompt phrase="belowground" filename="belowground.wav"/>
|
||||
<prompt phrase="berserk" filename="berserk.wav"/>
|
||||
<prompt phrase="bifocals" filename="bifocals.wav"/>
|
||||
<prompt phrase="billiard" filename="billiard.wav"/>
|
||||
<prompt phrase="bison" filename="bison.wav"/>
|
||||
<prompt phrase="blackjack" filename="blackjack.wav"/>
|
||||
<prompt phrase="blockade" filename="blockade.wav"/>
|
||||
<prompt phrase="blowtorch" filename="blowtorch.wav"/>
|
||||
<prompt phrase="bluebird" filename="bluebird.wav"/>
|
||||
<prompt phrase="bodyguard" filename="bodyguard.wav"/>
|
||||
<prompt phrase="bombast" filename="bombast.wav"/>
|
||||
<prompt phrase="bookseller" filename="bookseller.wav"/>
|
||||
<prompt phrase="bookshelf" filename="bookshelf.wav"/>
|
||||
<prompt phrase="borderline" filename="borderline.wav"/>
|
||||
<prompt phrase="bottomless" filename="bottomless.wav"/>
|
||||
<prompt phrase="brackish" filename="brackish.wav"/>
|
||||
<prompt phrase="bravado" filename="bravado.wav"/>
|
||||
<prompt phrase="breadline" filename="breadline.wav"/>
|
||||
<prompt phrase="breakaway" filename="breakaway.wav"/>
|
||||
<prompt phrase="breakup" filename="breakup.wav"/>
|
||||
<prompt phrase="brickyard" filename="brickyard.wav"/>
|
||||
<prompt phrase="briefcase" filename="briefcase.wav"/>
|
||||
<prompt phrase="businessman" filename="businessman.wav"/>
|
||||
<prompt phrase="butterfat" filename="butterfat.wav"/>
|
||||
<prompt phrase="button" filename="button.wav"/>
|
||||
<prompt phrase="buzzard" filename="buzzard.wav"/>
|
||||
<prompt phrase="candidate" filename="candidate.wav"/>
|
||||
<prompt phrase="cannonball" filename="cannonball.wav"/>
|
||||
<prompt phrase="caravan" filename="caravan.wav"/>
|
||||
<prompt phrase="caretaker" filename="caretaker.wav"/>
|
||||
<prompt phrase="celebrate" filename="celebrate.wav"/>
|
||||
<prompt phrase="cellulose" filename="cellulose.wav"/>
|
||||
<prompt phrase="cement" filename="cement.wav"/>
|
||||
<prompt phrase="certify" filename="certify.wav"/>
|
||||
<prompt phrase="chairlift" filename="chairlift.wav"/>
|
||||
<prompt phrase="chambermaid" filename="chambermaid.wav"/>
|
||||
<prompt phrase="chatter" filename="chatter.wav"/>
|
||||
<prompt phrase="checkup" filename="checkup.wav"/>
|
||||
<prompt phrase="chisel" filename="chisel.wav"/>
|
||||
<prompt phrase="choking" filename="choking.wav"/>
|
||||
<prompt phrase="chopper" filename="chopper.wav"/>
|
||||
<prompt phrase="clamshell" filename="clamshell.wav"/>
|
||||
<prompt phrase="classic" filename="classic.wav"/>
|
||||
<prompt phrase="classroom" filename="classroom.wav"/>
|
||||
<prompt phrase="cleanup" filename="cleanup.wav"/>
|
||||
<prompt phrase="clergyman" filename="clergyman.wav"/>
|
||||
<prompt phrase="clockwork" filename="clockwork.wav"/>
|
||||
<prompt phrase="cobra" filename="cobra.wav"/>
|
||||
<prompt phrase="coherence" filename="coherence.wav"/>
|
||||
<prompt phrase="combustion" filename="combustion.wav"/>
|
||||
<prompt phrase="commando" filename="commando.wav"/>
|
||||
<prompt phrase="commence" filename="commence.wav"/>
|
||||
<prompt phrase="company" filename="company.wav"/>
|
||||
<prompt phrase="component" filename="component.wav"/>
|
||||
<prompt phrase="concert" filename="concert.wav"/>
|
||||
<prompt phrase="concurrent" filename="concurrent.wav"/>
|
||||
<prompt phrase="confidence" filename="confidence.wav"/>
|
||||
<prompt phrase="conformist" filename="conformist.wav"/>
|
||||
<prompt phrase="congregate" filename="congregate.wav"/>
|
||||
<prompt phrase="consensus" filename="consensus.wav"/>
|
||||
<prompt phrase="consulting" filename="consulting.wav"/>
|
||||
<prompt phrase="corporate" filename="corporate.wav"/>
|
||||
<prompt phrase="corrosion" filename="corrosion.wav"/>
|
||||
<prompt phrase="councilman" filename="councilman.wav"/>
|
||||
<prompt phrase="cowbell" filename="cowbell.wav"/>
|
||||
<prompt phrase="crackdown" filename="crackdown.wav"/>
|
||||
<prompt phrase="cranky" filename="cranky.wav"/>
|
||||
<prompt phrase="crossover" filename="crossover.wav"/>
|
||||
<prompt phrase="crowfoot" filename="crowfoot.wav"/>
|
||||
<prompt phrase="crucial" filename="crucial.wav"/>
|
||||
<prompt phrase="crucifix" filename="crucifix.wav"/>
|
||||
<prompt phrase="crumpled" filename="crumpled.wav"/>
|
||||
<prompt phrase="crusade" filename="crusade.wav"/>
|
||||
<prompt phrase="cubic" filename="cubic.wav"/>
|
||||
<prompt phrase="cumbersome" filename="cumbersome.wav"/>
|
||||
<prompt phrase="customer" filename="customer.wav"/>
|
||||
<prompt phrase="dashboard" filename="dashboard.wav"/>
|
||||
<prompt phrase="deadbolt" filename="deadbolt.wav"/>
|
||||
<prompt phrase="decadence" filename="decadence.wav"/>
|
||||
<prompt phrase="decimal" filename="decimal.wav"/>
|
||||
<prompt phrase="deckhand" filename="deckhand.wav"/>
|
||||
<prompt phrase="designing" filename="designing.wav"/>
|
||||
<prompt phrase="detector" filename="detector.wav"/>
|
||||
<prompt phrase="detergent" filename="detergent.wav"/>
|
||||
<prompt phrase="determine" filename="determine.wav"/>
|
||||
<prompt phrase="dictator" filename="dictator.wav"/>
|
||||
<prompt phrase="dinosaur" filename="dinosaur.wav"/>
|
||||
<prompt phrase="direction" filename="direction.wav"/>
|
||||
<prompt phrase="disable" filename="disable.wav"/>
|
||||
<prompt phrase="disbelief" filename="disbelief.wav"/>
|
||||
<prompt phrase="disruptive" filename="disruptive.wav"/>
|
||||
<prompt phrase="distortion" filename="distortion.wav"/>
|
||||
<prompt phrase="document" filename="document.wav"/>
|
||||
<prompt phrase="dogsled" filename="dogsled.wav"/>
|
||||
<prompt phrase="dragnet" filename="dragnet.wav"/>
|
||||
<prompt phrase="drainage" filename="drainage.wav"/>
|
||||
<prompt phrase="dreadful" filename="dreadful.wav"/>
|
||||
<prompt phrase="drifter" filename="drifter.wav"/>
|
||||
<prompt phrase="dropper" filename="dropper.wav"/>
|
||||
<prompt phrase="drumbeat" filename="drumbeat.wav"/>
|
||||
<prompt phrase="drunken" filename="drunken.wav"/>
|
||||
<prompt phrase="dwelling" filename="dwelling.wav"/>
|
||||
<prompt phrase="eating" filename="eating.wav"/>
|
||||
<prompt phrase="edict" filename="edict.wav"/>
|
||||
<prompt phrase="egghead" filename="egghead.wav"/>
|
||||
<prompt phrase="eightball" filename="eightball.wav"/>
|
||||
<prompt phrase="embezzle" filename="embezzle.wav"/>
|
||||
<prompt phrase="enchanting" filename="enchanting.wav"/>
|
||||
<prompt phrase="endorse" filename="endorse.wav"/>
|
||||
<prompt phrase="endow" filename="endow.wav"/>
|
||||
<prompt phrase="enlist" filename="enlist.wav"/>
|
||||
<prompt phrase="enrollment" filename="enrollment.wav"/>
|
||||
<prompt phrase="enterprise" filename="enterprise.wav"/>
|
||||
<prompt phrase="equation" filename="equation.wav"/>
|
||||
<prompt phrase="equipment" filename="equipment.wav"/>
|
||||
<prompt phrase="erase" filename="erase.wav"/>
|
||||
<prompt phrase="escapade" filename="escapade.wav"/>
|
||||
<prompt phrase="escape" filename="escape.wav"/>
|
||||
<prompt phrase="everyday" filename="everyday.wav"/>
|
||||
<prompt phrase="examine" filename="examine.wav"/>
|
||||
<prompt phrase="exceed" filename="exceed.wav"/>
|
||||
<prompt phrase="existence" filename="existence.wav"/>
|
||||
<prompt phrase="exodus" filename="exodus.wav"/>
|
||||
<prompt phrase="eyeglass" filename="eyeglass.wav"/>
|
||||
<prompt phrase="eyetooth" filename="eyetooth.wav"/>
|
||||
<prompt phrase="facial" filename="facial.wav"/>
|
||||
<prompt phrase="fallout" filename="fallout.wav"/>
|
||||
<prompt phrase="fascinate" filename="fascinate.wav"/>
|
||||
<prompt phrase="filament" filename="filament.wav"/>
|
||||
<prompt phrase="finicky" filename="finicky.wav"/>
|
||||
<prompt phrase="flagpole" filename="flagpole.wav"/>
|
||||
<prompt phrase="flatfoot" filename="flatfoot.wav"/>
|
||||
<prompt phrase="flytrap" filename="flytrap.wav"/>
|
||||
<prompt phrase="forever" filename="forever.wav"/>
|
||||
<prompt phrase="fortitude" filename="fortitude.wav"/>
|
||||
<prompt phrase="fracture" filename="fracture.wav"/>
|
||||
<prompt phrase="framework" filename="framework.wav"/>
|
||||
<prompt phrase="freedom" filename="freedom.wav"/>
|
||||
<prompt phrase="frequency" filename="frequency.wav"/>
|
||||
<prompt phrase="frighten" filename="frighten.wav"/>
|
||||
<prompt phrase="gadgetry" filename="gadgetry.wav"/>
|
||||
<prompt phrase="gazelle" filename="gazelle.wav"/>
|
||||
<prompt phrase="getaway" filename="getaway.wav"/>
|
||||
<prompt phrase="glitter" filename="glitter.wav"/>
|
||||
<prompt phrase="glossary" filename="glossary.wav"/>
|
||||
<prompt phrase="glucose" filename="glucose.wav"/>
|
||||
<prompt phrase="goggles" filename="goggles.wav"/>
|
||||
<prompt phrase="goldfish" filename="goldfish.wav"/>
|
||||
<prompt phrase="gossamer" filename="gossamer.wav"/>
|
||||
<prompt phrase="graduate" filename="graduate.wav"/>
|
||||
<prompt phrase="gravity" filename="gravity.wav"/>
|
||||
<prompt phrase="gremlin" filename="gremlin.wav"/>
|
||||
<prompt phrase="guidance" filename="guidance.wav"/>
|
||||
<prompt phrase="guitarist" filename="guitarist.wav"/>
|
||||
<prompt phrase="hamburger" filename="hamburger.wav"/>
|
||||
<prompt phrase="hamlet" filename="hamlet.wav"/>
|
||||
<prompt phrase="handiwork" filename="handiwork.wav"/>
|
||||
<prompt phrase="hazardous" filename="hazardous.wav"/>
|
||||
<prompt phrase="headwaters" filename="headwaters.wav"/>
|
||||
<prompt phrase="hemisphere" filename="hemisphere.wav"/>
|
||||
<prompt phrase="hesitate" filename="hesitate.wav"/>
|
||||
<prompt phrase="hideaway" filename="hideaway.wav"/>
|
||||
<prompt phrase="highchair" filename="highchair.wav"/>
|
||||
<prompt phrase="hockey" filename="hockey.wav"/>
|
||||
<prompt phrase="holiness" filename="holiness.wav"/>
|
||||
<prompt phrase="hurricane" filename="hurricane.wav"/>
|
||||
<prompt phrase="hydraulic" filename="hydraulic.wav"/>
|
||||
<prompt phrase="impartial" filename="impartial.wav"/>
|
||||
<prompt phrase="impetus" filename="impetus.wav"/>
|
||||
<prompt phrase="inception" filename="inception.wav"/>
|
||||
<prompt phrase="indigo" filename="indigo.wav"/>
|
||||
<prompt phrase="indoors" filename="indoors.wav"/>
|
||||
<prompt phrase="indulge" filename="indulge.wav"/>
|
||||
<prompt phrase="inertia" filename="inertia.wav"/>
|
||||
<prompt phrase="infancy" filename="infancy.wav"/>
|
||||
<prompt phrase="inferno" filename="inferno.wav"/>
|
||||
<prompt phrase="informant" filename="informant.wav"/>
|
||||
<prompt phrase="insincere" filename="insincere.wav"/>
|
||||
<prompt phrase="insurgent" filename="insurgent.wav"/>
|
||||
<prompt phrase="integrate" filename="integrate.wav"/>
|
||||
<prompt phrase="intention" filename="intention.wav"/>
|
||||
<prompt phrase="inventive" filename="inventive.wav"/>
|
||||
<prompt phrase="inverse" filename="inverse.wav"/>
|
||||
<prompt phrase="involve" filename="involve.wav"/>
|
||||
<prompt phrase="island" filename="island.wav"/>
|
||||
<prompt phrase="jawbone" filename="jawbone.wav"/>
|
||||
<prompt phrase="keyboard" filename="keyboard.wav"/>
|
||||
<prompt phrase="kickoff" filename="kickoff.wav"/>
|
||||
<prompt phrase="kiwi" filename="kiwi.wav"/>
|
||||
<prompt phrase="klaxon" filename="klaxon.wav"/>
|
||||
<prompt phrase="leprosy" filename="leprosy.wav"/>
|
||||
<prompt phrase="letterhead" filename="letterhead.wav"/>
|
||||
<prompt phrase="liberty" filename="liberty.wav"/>
|
||||
<prompt phrase="locale" filename="locale.wav"/>
|
||||
<prompt phrase="lockup" filename="lockup.wav"/>
|
||||
<prompt phrase="maritime" filename="maritime.wav"/>
|
||||
<prompt phrase="matchmaker" filename="matchmaker.wav"/>
|
||||
<prompt phrase="maverick" filename="maverick.wav"/>
|
||||
<prompt phrase="megaton" filename="megaton.wav"/>
|
||||
<prompt phrase="merit" filename="merit.wav"/>
|
||||
<prompt phrase="microscope" filename="microscope.wav"/>
|
||||
<prompt phrase="microwave" filename="microwave.wav"/>
|
||||
<prompt phrase="midsummer" filename="midsummer.wav"/>
|
||||
<prompt phrase="millionaire" filename="millionaire.wav"/>
|
||||
<prompt phrase="minnow" filename="minnow.wav"/>
|
||||
<prompt phrase="miracle" filename="miracle.wav"/>
|
||||
<prompt phrase="miser" filename="miser.wav"/>
|
||||
<prompt phrase="misnomer" filename="misnomer.wav"/>
|
||||
<prompt phrase="molasses" filename="molasses.wav"/>
|
||||
<prompt phrase="molecule" filename="molecule.wav"/>
|
||||
<prompt phrase="monument" filename="monument.wav"/>
|
||||
<prompt phrase="mosquito" filename="mosquito.wav"/>
|
||||
<prompt phrase="mural" filename="mural.wav"/>
|
||||
<prompt phrase="music" filename="music.wav"/>
|
||||
<prompt phrase="narrative" filename="narrative.wav"/>
|
||||
<prompt phrase="nebula" filename="nebula.wav"/>
|
||||
<prompt phrase="necklace" filename="necklace.wav"/>
|
||||
<prompt phrase="newborn" filename="newborn.wav"/>
|
||||
<prompt phrase="newsletter" filename="newsletter.wav"/>
|
||||
<prompt phrase="nightbird" filename="nightbird.wav"/>
|
||||
<prompt phrase="obtuse" filename="obtuse.wav"/>
|
||||
<prompt phrase="offload" filename="offload.wav"/>
|
||||
<prompt phrase="onlooker" filename="onlooker.wav"/>
|
||||
<prompt phrase="optic" filename="optic.wav"/>
|
||||
<prompt phrase="opulent" filename="opulent.wav"/>
|
||||
<prompt phrase="orca" filename="orca.wav"/>
|
||||
<prompt phrase="outfielder" filename="outfielder.wav"/>
|
||||
<prompt phrase="pandemic" filename="pandemic.wav"/>
|
||||
<prompt phrase="paperweight" filename="paperweight.wav"/>
|
||||
<prompt phrase="paragon" filename="paragon.wav"/>
|
||||
<prompt phrase="paragraph" filename="paragraph.wav"/>
|
||||
<prompt phrase="paramount" filename="paramount.wav"/>
|
||||
<prompt phrase="passenger" filename="passenger.wav"/>
|
||||
<prompt phrase="payday" filename="payday.wav"/>
|
||||
<prompt phrase="peachy" filename="peachy.wav"/>
|
||||
<prompt phrase="pedigree" filename="pedigree.wav"/>
|
||||
<prompt phrase="penetrate" filename="penetrate.wav"/>
|
||||
<prompt phrase="perceptive" filename="perceptive.wav"/>
|
||||
<prompt phrase="performance" filename="performance.wav"/>
|
||||
<prompt phrase="pharmacy" filename="pharmacy.wav"/>
|
||||
<prompt phrase="pheasant" filename="pheasant.wav"/>
|
||||
<prompt phrase="phonetic" filename="phonetic.wav"/>
|
||||
<prompt phrase="photograph" filename="photograph.wav"/>
|
||||
<prompt phrase="physique" filename="physique.wav"/>
|
||||
<prompt phrase="pioneer" filename="pioneer.wav"/>
|
||||
<prompt phrase="playhouse" filename="playhouse.wav"/>
|
||||
<prompt phrase="pocketful" filename="pocketful.wav"/>
|
||||
<prompt phrase="politeness" filename="politeness.wav"/>
|
||||
<prompt phrase="positive" filename="positive.wav"/>
|
||||
<prompt phrase="potato" filename="potato.wav"/>
|
||||
<prompt phrase="preclude" filename="preclude.wav"/>
|
||||
<prompt phrase="prefer" filename="prefer.wav"/>
|
||||
<prompt phrase="preshrunk" filename="preshrunk.wav"/>
|
||||
<prompt phrase="printer" filename="printer.wav"/>
|
||||
<prompt phrase="processor" filename="processor.wav"/>
|
||||
<prompt phrase="provincial" filename="provincial.wav"/>
|
||||
<prompt phrase="prowler" filename="prowler.wav"/>
|
||||
<prompt phrase="proximate" filename="proximate.wav"/>
|
||||
<prompt phrase="puberty" filename="puberty.wav"/>
|
||||
<prompt phrase="publisher" filename="publisher.wav"/>
|
||||
<prompt phrase="pupil" filename="pupil.wav"/>
|
||||
<prompt phrase="puppy" filename="puppy.wav"/>
|
||||
<prompt phrase="pyramid" filename="pyramid.wav"/>
|
||||
<prompt phrase="python" filename="python.wav"/>
|
||||
<prompt phrase="quadrant" filename="quadrant.wav"/>
|
||||
<prompt phrase="quantity" filename="quantity.wav"/>
|
||||
<prompt phrase="quiver" filename="quiver.wav"/>
|
||||
<prompt phrase="quota" filename="quota.wav"/>
|
||||
<prompt phrase="racketeer" filename="racketeer.wav"/>
|
||||
<prompt phrase="ragtime" filename="ragtime.wav"/>
|
||||
<prompt phrase="ratchet" filename="ratchet.wav"/>
|
||||
<prompt phrase="rebellion" filename="rebellion.wav"/>
|
||||
<prompt phrase="rebirth" filename="rebirth.wav"/>
|
||||
<prompt phrase="recipe" filename="recipe.wav"/>
|
||||
<prompt phrase="recover" filename="recover.wav"/>
|
||||
<prompt phrase="reform" filename="reform.wav"/>
|
||||
<prompt phrase="regain" filename="regain.wav"/>
|
||||
<prompt phrase="reindeer" filename="reindeer.wav"/>
|
||||
<prompt phrase="rematch" filename="rematch.wav"/>
|
||||
<prompt phrase="repay" filename="repay.wav"/>
|
||||
<prompt phrase="repellent" filename="repellent.wav"/>
|
||||
<prompt phrase="replica" filename="replica.wav"/>
|
||||
<prompt phrase="reproduce" filename="reproduce.wav"/>
|
||||
<prompt phrase="resistor" filename="resistor.wav"/>
|
||||
<prompt phrase="responsive" filename="responsive.wav"/>
|
||||
<prompt phrase="retouch" filename="retouch.wav"/>
|
||||
<prompt phrase="retraction" filename="retraction.wav"/>
|
||||
<prompt phrase="retrieval" filename="retrieval.wav"/>
|
||||
<prompt phrase="retrospect" filename="retrospect.wav"/>
|
||||
<prompt phrase="revenge" filename="revenge.wav"/>
|
||||
<prompt phrase="revenue" filename="revenue.wav"/>
|
||||
<prompt phrase="revival" filename="revival.wav"/>
|
||||
<prompt phrase="revolver" filename="revolver.wav"/>
|
||||
<prompt phrase="reward" filename="reward.wav"/>
|
||||
<prompt phrase="rhythm" filename="rhythm.wav"/>
|
||||
<prompt phrase="ribcage" filename="ribcage.wav"/>
|
||||
<prompt phrase="ringbolt" filename="ringbolt.wav"/>
|
||||
<prompt phrase="robust" filename="robust.wav"/>
|
||||
<prompt phrase="rocker" filename="rocker.wav"/>
|
||||
<prompt phrase="ruffled" filename="ruffled.wav"/>
|
||||
<prompt phrase="sailboat" filename="sailboat.wav"/>
|
||||
<prompt phrase="sandalwood" filename="sandalwood.wav"/>
|
||||
<prompt phrase="sardonic" filename="sardonic.wav"/>
|
||||
<prompt phrase="savagery" filename="savagery.wav"/>
|
||||
<prompt phrase="sawdust" filename="sawdust.wav"/>
|
||||
<prompt phrase="scallion" filename="scallion.wav"/>
|
||||
<prompt phrase="scavenger" filename="scavenger.wav"/>
|
||||
<prompt phrase="scenic" filename="scenic.wav"/>
|
||||
<prompt phrase="scorecard" filename="scorecard.wav"/>
|
||||
<prompt phrase="seabird" filename="seabird.wav"/>
|
||||
<prompt phrase="select" filename="select.wav"/>
|
||||
<prompt phrase="sensation" filename="sensation.wav"/>
|
||||
<prompt phrase="sentence" filename="sentence.wav"/>
|
||||
<prompt phrase="shadow" filename="shadow.wav"/>
|
||||
<prompt phrase="shamrock" filename="shamrock.wav"/>
|
||||
<prompt phrase="showgirl" filename="showgirl.wav"/>
|
||||
<prompt phrase="skullcap" filename="skullcap.wav"/>
|
||||
<prompt phrase="skydive" filename="skydive.wav"/>
|
||||
<prompt phrase="slingshot" filename="slingshot.wav"/>
|
||||
<prompt phrase="slowdown" filename="slowdown.wav"/>
|
||||
<prompt phrase="snapline" filename="snapline.wav"/>
|
||||
<prompt phrase="snapshot" filename="snapshot.wav"/>
|
||||
<prompt phrase="snowcap" filename="snowcap.wav"/>
|
||||
<prompt phrase="snowslide" filename="snowslide.wav"/>
|
||||
<prompt phrase="sociable" filename="sociable.wav"/>
|
||||
<prompt phrase="solo" filename="solo.wav"/>
|
||||
<prompt phrase="southward" filename="southward.wav"/>
|
||||
<prompt phrase="souvenir" filename="souvenir.wav"/>
|
||||
<prompt phrase="soybean" filename="soybean.wav"/>
|
||||
<prompt phrase="spaniel" filename="spaniel.wav"/>
|
||||
<prompt phrase="spearhead" filename="spearhead.wav"/>
|
||||
<prompt phrase="specialist" filename="specialist.wav"/>
|
||||
<prompt phrase="speculate" filename="speculate.wav"/>
|
||||
<prompt phrase="spellbind" filename="spellbind.wav"/>
|
||||
<prompt phrase="spheroid" filename="spheroid.wav"/>
|
||||
<prompt phrase="spigot" filename="spigot.wav"/>
|
||||
<prompt phrase="spindle" filename="spindle.wav"/>
|
||||
<prompt phrase="spyglass" filename="spyglass.wav"/>
|
||||
<prompt phrase="stagehand" filename="stagehand.wav"/>
|
||||
<prompt phrase="stagnate" filename="stagnate.wav"/>
|
||||
<prompt phrase="stairway" filename="stairway.wav"/>
|
||||
<prompt phrase="standard" filename="standard.wav"/>
|
||||
<prompt phrase="stapler" filename="stapler.wav"/>
|
||||
<prompt phrase="steamship" filename="steamship.wav"/>
|
||||
<prompt phrase="sterling" filename="sterling.wav"/>
|
||||
<prompt phrase="stethoscope" filename="stethoscope.wav"/>
|
||||
<prompt phrase="stockman" filename="stockman.wav"/>
|
||||
<prompt phrase="stopwatch" filename="stopwatch.wav"/>
|
||||
<prompt phrase="stormy" filename="stormy.wav"/>
|
||||
<prompt phrase="stupendous" filename="stupendous.wav"/>
|
||||
<prompt phrase="sugar" filename="sugar.wav"/>
|
||||
<prompt phrase="supportive" filename="supportive.wav"/>
|
||||
<prompt phrase="surmount" filename="surmount.wav"/>
|
||||
<prompt phrase="surrender" filename="surrender.wav"/>
|
||||
<prompt phrase="suspense" filename="suspense.wav"/>
|
||||
<prompt phrase="suspicious" filename="suspicious.wav"/>
|
||||
<prompt phrase="sweatband" filename="sweatband.wav"/>
|
||||
<prompt phrase="swelter" filename="swelter.wav"/>
|
||||
<prompt phrase="sympathy" filename="sympathy.wav"/>
|
||||
<prompt phrase="tactics" filename="tactics.wav"/>
|
||||
<prompt phrase="talon" filename="talon.wav"/>
|
||||
<prompt phrase="tambourine" filename="tambourine.wav"/>
|
||||
<prompt phrase="tapeworm" filename="tapeworm.wav"/>
|
||||
<prompt phrase="telephone" filename="telephone.wav"/>
|
||||
<prompt phrase="tempest" filename="tempest.wav"/>
|
||||
<prompt phrase="therapist" filename="therapist.wav"/>
|
||||
<prompt phrase="tiger" filename="tiger.wav"/>
|
||||
<prompt phrase="tissue" filename="tissue.wav"/>
|
||||
<prompt phrase="tobacco" filename="tobacco.wav"/>
|
||||
<prompt phrase="tolerance" filename="tolerance.wav"/>
|
||||
<prompt phrase="tomorrow" filename="tomorrow.wav"/>
|
||||
<prompt phrase="tonic" filename="tonic.wav"/>
|
||||
<prompt phrase="topmost" filename="topmost.wav"/>
|
||||
<prompt phrase="torpedo" filename="torpedo.wav"/>
|
||||
<prompt phrase="tracker" filename="tracker.wav"/>
|
||||
<prompt phrase="tradition" filename="tradition.wav"/>
|
||||
<prompt phrase="transit" filename="transit.wav"/>
|
||||
<prompt phrase="trauma" filename="trauma.wav"/>
|
||||
<prompt phrase="travesty" filename="travesty.wav"/>
|
||||
<prompt phrase="treadmill" filename="treadmill.wav"/>
|
||||
<prompt phrase="trombonist" filename="trombonist.wav"/>
|
||||
<prompt phrase="trouble" filename="trouble.wav"/>
|
||||
<prompt phrase="truncated" filename="truncated.wav"/>
|
||||
<prompt phrase="tumor" filename="tumor.wav"/>
|
||||
<prompt phrase="tunnel" filename="tunnel.wav"/>
|
||||
<prompt phrase="tycoon" filename="tycoon.wav"/>
|
||||
<prompt phrase="typewriter" filename="typewriter.wav"/>
|
||||
<prompt phrase="ultimate" filename="ultimate.wav"/>
|
||||
<prompt phrase="uncut" filename="uncut.wav"/>
|
||||
<prompt phrase="undaunted" filename="undaunted.wav"/>
|
||||
<prompt phrase="underfoot" filename="underfoot.wav"/>
|
||||
<prompt phrase="unearth" filename="unearth.wav"/>
|
||||
<prompt phrase="unicorn" filename="unicorn.wav"/>
|
||||
<prompt phrase="unify" filename="unify.wav"/>
|
||||
<prompt phrase="universe" filename="universe.wav"/>
|
||||
<prompt phrase="unravel" filename="unravel.wav"/>
|
||||
<prompt phrase="unwind" filename="unwind.wav"/>
|
||||
<prompt phrase="upcoming" filename="upcoming.wav"/>
|
||||
<prompt phrase="uproot" filename="uproot.wav"/>
|
||||
<prompt phrase="upset" filename="upset.wav"/>
|
||||
<prompt phrase="upshot" filename="upshot.wav"/>
|
||||
<prompt phrase="vacancy" filename="vacancy.wav"/>
|
||||
<prompt phrase="vagabond" filename="vagabond.wav"/>
|
||||
<prompt phrase="vapor" filename="vapor.wav"/>
|
||||
<prompt phrase="vertigo" filename="vertigo.wav"/>
|
||||
<prompt phrase="village" filename="village.wav"/>
|
||||
<prompt phrase="virus" filename="virus.wav"/>
|
||||
<prompt phrase="visitor" filename="visitor.wav"/>
|
||||
<prompt phrase="vocalist" filename="vocalist.wav"/>
|
||||
<prompt phrase="voyager" filename="voyager.wav"/>
|
||||
<prompt phrase="waffle" filename="waffle.wav"/>
|
||||
<prompt phrase="wallet" filename="wallet.wav"/>
|
||||
<prompt phrase="warranty" filename="warranty.wav"/>
|
||||
<prompt phrase="watchword" filename="watchword.wav"/>
|
||||
<prompt phrase="wayside" filename="wayside.wav"/>
|
||||
<prompt phrase="whimsical" filename="whimsical.wav"/>
|
||||
<prompt phrase="willow" filename="willow.wav"/>
|
||||
<prompt phrase="woodlark" filename="woodlark.wav"/>
|
||||
<prompt phrase="yesteryear" filename="yesteryear.wav"/>
|
||||
<!-- Event prompts -->
|
||||
<prompt phrase="Bienvenidos al servicio de inscripción ZRTP." filename="zrtp-enroll_welcome.wav"/>
|
||||
<prompt phrase="Usted debe verificar la cadena de carácteres con su destino. Si no coincide, indica la presencia de una escucha telefónica." filename="zrtp-check_sas.wav"/>
|
||||
<prompt phrase="Solo teléfonos autenticados pueden confiar en llamadas securizadas con ZRTP. Su teléfono no está autenticado con este sistema, por lo que esta llamada no estará securizada." filename="zrtp-enroll_not_sip_registered.wav"/>
|
||||
<prompt phrase="Su teléfono indica que confia en este sistema para realizar llamadas seguras con ZRTP, no necesita hacer nada más." filename="zrtp-enroll_already_enrolled.wav"/>
|
||||
<prompt phrase="Solo teléfonos soportando el protócolo ZRTP pueden usar esta extensión. Su teléfono no tiene ZRTP habilitado, por lo que esta llamada no estará securizada." filename="zrtp-enroll_notzrtp.wav"/>
|
||||
<prompt phrase="Este sistema esta configurado para manejar llamadas cifradas con ZRTP. Decida si permite al sistema tener la posibilidad de interceptar o monitorizar su llamada. Puede colgar una vez confirmado." filename="zrtp-enroll_confirmed.wav"/>
|
||||
<prompt phrase="Compara verbalmente este código de autenticación con su destino." filename="zrtp-is_secure.wav"/>
|
||||
<prompt phrase="El código de autenticación no está verificado." filename="zrtp-is_unverified.wav"/>
|
||||
<prompt phrase="El código de autenticación está verificado." filename="zrtp-is_verified.wav"/>
|
||||
<prompt phrase="Gracias por llamar. Adiós." filename="zrtp-thankyou_goodbye.wav"/>
|
||||
<prompt phrase="Algún error ha ocurrido." filename="zrtp-somethings_wrong.wav"/>
|
||||
<prompt phrase="Error." filename="zrtp-status_error.wav"/>
|
||||
<prompt phrase="Esta llamada no está protegida." filename="zrtp-status_notsecure.wav"/>
|
||||
<prompt phrase="Esta llamada está protegida." filename="zrtp-status_secure.wav"/>
|
||||
<prompt phrase="Securizando su llamada." filename="zrtp-status_securing.wav"/>
|
||||
</zrtp>
|
||||
</es_ES>
|
||||
<language>
|
|
@ -0,0 +1,993 @@
|
|||
<language>
|
||||
<es_MX>
|
||||
<ascii>
|
||||
<prompt phrase="Espacio" filename="32.wav"/>
|
||||
<prompt phrase="Signo de número" filename="35.wav"/>
|
||||
<prompt phrase="Asterisco" filename="42.wav"/>
|
||||
<prompt phrase="Punto" filename="46.wav"/>
|
||||
<prompt phrase="A" filename="97.wav"/>
|
||||
<prompt phrase="B" filename="98.wav"/>
|
||||
<prompt phrase="C" filename="99.wav"/>
|
||||
<prompt phrase="D" filename="100.wav"/>
|
||||
<prompt phrase="E" filename="101.wav"/>
|
||||
<prompt phrase="F" filename="102.wav"/>
|
||||
<prompt phrase="G" filename="103.wav"/>
|
||||
<prompt phrase="H" filename="104.wav"/>
|
||||
<prompt phrase="I" filename="105.wav"/>
|
||||
<prompt phrase="J" filename="106.wav"/>
|
||||
<prompt phrase="K" filename="107.wav"/>
|
||||
<prompt phrase="L" filename="108.wav"/>
|
||||
<prompt phrase="M" filename="109.wav"/>
|
||||
<prompt phrase="N" filename="110.wav"/>
|
||||
<prompt phrase="Ñ" filename="Ñ.wav"/>
|
||||
<prompt phrase="O" filename="111.wav"/>
|
||||
<prompt phrase="P" filename="112.wav"/>
|
||||
<prompt phrase="Q" filename="113.wav"/>
|
||||
<prompt phrase="R" filename="114.wav"/>
|
||||
<prompt phrase="S" filename="115.wav"/>
|
||||
<prompt phrase="T" filename="116.wav"/>
|
||||
<prompt phrase="U" filename="117.wav"/>
|
||||
<prompt phrase="V" filename="118.wav"/>
|
||||
<prompt phrase="W" filename="119.wav"/>
|
||||
<prompt phrase="X" filename="120.wav"/>
|
||||
<prompt phrase="Y" filename="121.wav"/>
|
||||
<prompt phrase="Z" filename="122.wav"/>
|
||||
</ascii>
|
||||
<phonetic-ascii>
|
||||
<prompt phrase="Espacio" filename="32.wav"/>
|
||||
<prompt phrase="Punto" filename="46.wav"/>
|
||||
<prompt phrase="Alpha" filename="97.wav"/>
|
||||
<prompt phrase="Bravo" filename="98.wav"/>
|
||||
<prompt phrase="Charlie" filename="99.wav"/>
|
||||
<prompt phrase="Delta" filename="100.wav"/>
|
||||
<prompt phrase="Echo" filename="101.wav"/>
|
||||
<prompt phrase="Foxtrot" filename="102.wav"/>
|
||||
<prompt phrase="Golf" filename="103.wav"/>
|
||||
<prompt phrase="Hotel" filename="104.wav"/>
|
||||
<prompt phrase="India" filename="105.wav"/>
|
||||
<prompt phrase="Juliet" filename="106.wav"/>
|
||||
<prompt phrase="Kilo" filename="107.wav"/>
|
||||
<prompt phrase="Lima" filename="108.wav"/>
|
||||
<prompt phrase="Mike" filename="109.wav"/>
|
||||
<prompt phrase="November" filename="110.wav"/>
|
||||
<prompt phrase="Oscar" filename="111.wav"/>
|
||||
<prompt phrase="Papa" filename="112.wav"/>
|
||||
<prompt phrase="Quebec" filename="113.wav"/>
|
||||
<prompt phrase="Romeo" filename="114.wav"/>
|
||||
<prompt phrase="Sierra" filename="115.wav"/>
|
||||
<prompt phrase="Tango" filename="116.wav"/>
|
||||
<prompt phrase="Unifor" filename="117.wav"/>
|
||||
<prompt phrase="Victor" filename="118.wav"/>
|
||||
<prompt phrase="Whiskey" filename="119.wav"/>
|
||||
<prompt phrase="Xray" filename="120.wav"/>
|
||||
<prompt phrase="Yankee" filename="121.wav"/>
|
||||
<prompt phrase="Zulu" filename="122.wav"/>
|
||||
</phonetic-ascii>
|
||||
<digits>
|
||||
<prompt phrase="Cero" filename="0.wav"/>
|
||||
<prompt phrase="Uno" filename="1.wav"/>
|
||||
<prompt phrase="Dos" filename="2.wav"/>
|
||||
<prompt phrase="Tres" filename="3.wav"/>
|
||||
<prompt phrase="Cuatro" filename="4.wav"/>
|
||||
<prompt phrase="Cinco" filename="5.wav"/>
|
||||
<prompt phrase="Seis" filename="6.wav"/>
|
||||
<prompt phrase="Siete" filename="7.wav"/>
|
||||
<prompt phrase="Ocho" filename="8.wav"/>
|
||||
<prompt phrase="Nueve" filename="9.wav"/>
|
||||
<prompt phrase="Diez" filename="10.wav"/>
|
||||
<prompt phrase="Once" filename="11.wav"/>
|
||||
<prompt phrase="Doce" filename="12.wav"/>
|
||||
<prompt phrase="Trece" filename="13.wav"/>
|
||||
<prompt phrase="Catorce" filename="14.wav"/>
|
||||
<prompt phrase="Quince" filename="15.wav"/>
|
||||
<prompt phrase="Dieciséis" filename="16.wav"/>
|
||||
<prompt phrase="Diecisiete" filename="17.wav"/>
|
||||
<prompt phrase="Dieciocho" filename="18.wav"/>
|
||||
<prompt phrase="Diecinueve" filename="19.wav"/>
|
||||
<prompt phrase="Veinte" filename="20.wav"/>
|
||||
<prompt phrase="Veinti" filename="veinti.wav"/>
|
||||
<prompt phrase="Treinta" filename="30.wav"/>
|
||||
<prompt phrase="Cuarenta" filename="40.wav"/>
|
||||
<prompt phrase="Cincuenta" filename="50.wav"/>
|
||||
<prompt phrase="Sesenta" filename="60.wav"/>
|
||||
<prompt phrase="Setenta" filename="70.wav"/>
|
||||
<prompt phrase="Ochenta" filename="80.wav"/>
|
||||
<prompt phrase="Noventa" filename="90.wav"/>
|
||||
<prompt phrase="Cien" filename="100.wav"/>
|
||||
<prompt phrase="Quinientos" filename="500.wav"/>
|
||||
<prompt phrase="Setecientos" filename="700.wav"/>
|
||||
<prompt phrase="Novecientos" filename="900.wav"/>
|
||||
<prompt phrase="Punto" filename="dot.wav"/>
|
||||
<prompt phrase="Primero" filename="h-1.wav"/>
|
||||
<prompt phrase="Segundo" filename="h-2.wav"/>
|
||||
<prompt phrase="Tercero" filename="h-3.wav"/>
|
||||
<prompt phrase="Cuarto" filename="h-4.wav"/>
|
||||
<prompt phrase="Quinto" filename="h-5.wav"/>
|
||||
<prompt phrase="Sexto" filename="h-6.wav"/>
|
||||
<prompt phrase="Séptimo" filename="h-7.wav"/>
|
||||
<prompt phrase="Octavo" filename="h-8.wav"/>
|
||||
<prompt phrase="Noveno" filename="h-9.wav"/>
|
||||
<prompt phrase="Décimo" filename="h-10.wav"/>
|
||||
<prompt phrase="Undécimo" filename="h-11.wav"/>
|
||||
<prompt phrase="Duodécimo" filename="h-12.wav"/>
|
||||
<prompt phrase="Decimotercero" filename="h-13.wav"/>
|
||||
<prompt phrase="Decimocuarto" filename="h-14.wav"/>
|
||||
<prompt phrase="Decimoquinto" filename="h-15.wav"/>
|
||||
<prompt phrase="Decimosexto" filename="h-16.wav"/>
|
||||
<prompt phrase="Decimoséptimo" filename="h-17.wav"/>
|
||||
<prompt phrase="Decimoctavo" filename="h-18.wav"/>
|
||||
<prompt phrase="Decimonoveno" filename="h-19.wav"/>
|
||||
<prompt phrase="Vigésimo" filename="h-20.wav"/>
|
||||
<prompt phrase="Trigésimo" filename="h-30.wav"/>
|
||||
<prompt phrase="Un" filename="un.wav"/>
|
||||
<prompt phrase="Ciento" filename="hundred.wav"/>
|
||||
<prompt phrase="Cientos" filename="hundreds.wav"/>
|
||||
<prompt phrase="Mil" filename="thousand.wav"/>
|
||||
<prompt phrase="Millón" filename="million.wav"/>
|
||||
<prompt phrase="Millones" filename="millions.wav"/>
|
||||
<prompt phrase="Período" filename="period.wav"/>
|
||||
<prompt phrase="Punto" filename="point.wav"/>
|
||||
<prompt phrase="Signo de número" filename="pound.wav"/>
|
||||
<prompt phrase="Asterisco" filename="star.wav"/>
|
||||
</digits>
|
||||
<currency>
|
||||
<prompt phrase="Y" filename="and.wav"/>
|
||||
<prompt phrase="Centavo" filename="cent.wav"/>
|
||||
<prompt phrase="Central" filename="central.wav"/>
|
||||
<prompt phrase="Centavos por minuto" filename="cents-per-minute.wav"/>
|
||||
<prompt phrase="Centavos" filename="cents.wav"/>
|
||||
<prompt phrase="Dólar" filename="dollar.wav"/>
|
||||
<prompt phrase="Dólares" filename="dollars.wav"/>
|
||||
<prompt phrase="Menos" filename="minus.wav"/>
|
||||
<prompt phrase="Negativo" filename="negative.wav"/>
|
||||
</currency>
|
||||
<time>
|
||||
<prompt phrase="A.M." filename="a-m.wav"/>
|
||||
<prompt phrase="A" filename="at.wav"/>
|
||||
<prompt phrase="Domingo" filename="day-0.wav"/>
|
||||
<prompt phrase="Lunes" filename="day-1.wav"/>
|
||||
<prompt phrase="Martes" filename="day-2.wav"/>
|
||||
<prompt phrase="Miércoles" filename="day-3.wav"/>
|
||||
<prompt phrase="Jueves" filename="day-4.wav"/>
|
||||
<prompt phrase="Viernes" filename="day-5.wav"/>
|
||||
<prompt phrase="Sábado" filename="day-6.wav"/>
|
||||
<prompt phrase="Hora" filename="hour.wav"/>
|
||||
<prompt phrase="Horas" filename="hours.wav"/>
|
||||
<prompt phrase="Minuto" filename="minute.wav"/>
|
||||
<prompt phrase="Minutos" filename="minutes.wav"/>
|
||||
<prompt phrase="Enero" filename="mon-0.wav"/>
|
||||
<prompt phrase="Febrero" filename="mon-1.wav"/>
|
||||
<prompt phrase="Marzo" filename="mon-2.wav"/>
|
||||
<prompt phrase="Abril" filename="mon-3.wav"/>
|
||||
<prompt phrase="Mayo" filename="mon-4.wav"/>
|
||||
<prompt phrase="Junio" filename="mon-5.wav"/>
|
||||
<prompt phrase="Julio" filename="mon-6.wav"/>
|
||||
<prompt phrase="Agosto" filename="mon-7.wav"/>
|
||||
<prompt phrase="Septiembre" filename="mon-8.wav"/>
|
||||
<prompt phrase="Octubre" filename="mon-9.wav"/>
|
||||
<prompt phrase="Noviembre" filename="mon-10.wav"/>
|
||||
<prompt phrase="Diciembre" filename="mon-11.wav"/>
|
||||
<prompt phrase="En punto" filename="oclock.wav"/>
|
||||
<prompt phrase="P.M." filename="p-m.wav"/>
|
||||
<prompt phrase="Segundo" filename="second.wav"/>
|
||||
<prompt phrase="Segundos" filename="seconds.wav"/>
|
||||
<prompt phrase="Hoy" filename="today.wav"/>
|
||||
<prompt phrase="Mañana" filename="tomorrow.wav"/>
|
||||
<prompt phrase="Ayer" filename="yesterday.wav"/>
|
||||
</time>
|
||||
<voicemail>
|
||||
<prompt phrase="La persona en la extensión..." filename="vm-person.wav"/>
|
||||
<prompt phrase="Marcado urgente." filename="vm-marked-urgent.wav"/>
|
||||
<prompt phrase="Mandado por correo electrónico." filename="vm-emailed.wav"/>
|
||||
<prompt phrase="Usted tiene..." filename="vm-you_have.wav"/>
|
||||
<prompt phrase="Por favor ingrese su número de usuario, seguido por..." filename="vm-enter_id.wav"/>
|
||||
<prompt phrase="Por favor ingrese su contraseña, seguido por..." filename="vm-enter_pass.wav"/>
|
||||
<prompt phrase="Inicio de sesión incorrectos." filename="vm-fail_auth.wav"/>
|
||||
<prompt phrase="Bienvenido a su buzon de voz." filename="vm-hello.wav"/>
|
||||
<prompt phrase="Adiós." filename="vm-goodbye.wav"/>
|
||||
<prompt phrase="Después del tono, por favor anote su nombre, pulse cualquier tecla o deje de hablar para poner fin a la grabación." filename="vm-record_name1.wav"/>
|
||||
<prompt phrase="Elija un saludo entre 1 y 9." filename="vm-choose_greeting_choose.wav"/>
|
||||
<prompt phrase="Valor inválido." filename="vm-choose_greeting_fail.wav"/>
|
||||
<prompt phrase="Demasiados intentos fallidos." filename="vm-abort.wav"/>
|
||||
<prompt phrase="Para cambiar su clave." filename="vm-change_password.wav"/>
|
||||
<prompt phrase="Grabe su saludo después del tono, pulse cualquier tecla o deje de hablar para poner fin a la grabación" filename="vm-record_greeting.wav"/>
|
||||
<prompt phrase="Grabe su mensaje después del tono, pulse cualquier tecla o deje de hablar para poner fin a la grabación" filename="vm-record_message.wav"/>
|
||||
<prompt phrase="...no está disponible." filename="vm-play_greeting.wav"/>
|
||||
<prompt phrase="Urgente nuevo" filename="vm-urgent-new.wav"/>
|
||||
<prompt phrase="Nuevo" filename="vm-new.wav"/>
|
||||
<prompt phrase="Urgente guardado" filename="vm-urgent-saved.wav"/>
|
||||
<prompt phrase="Guardado" filename="vm-saved.wav"/>
|
||||
<prompt phrase="Mensaje" filename="vm-message.wav"/>
|
||||
<prompt phrase="Mensajes" filename="vm-messages.wav"/>
|
||||
<prompt phrase="Presione" filename="vm-press.wav"/>
|
||||
<prompt phrase="Para escuchar mensajes nuevos..." filename="vm-listen_new.wav"/>
|
||||
<prompt phrase="Para escuchar mensajes guardados..." filename="vm-listen_saved.wav"/>
|
||||
<prompt phrase="Para opciones avanzadas..." filename="vm-advanced.wav"/>
|
||||
<prompt phrase="Para salir..." filename="vm-to_exit.wav"/>
|
||||
<prompt phrase="Para guardar un saludo..." filename="vm-record_greeting.wav"/>
|
||||
<prompt phrase="Para elegir un saludo..." filename="vm-choose_greeting.wav"/>
|
||||
<prompt phrase="Para grabar su nombre..." filename="vm-record_name2.wav"/>
|
||||
<prompt phrase="Para el menú principal..." filename="vm-main_menu.wav"/>
|
||||
<prompt phrase="Para escuchar la grabación..." filename="vm-listen_to_recording.wav"/>
|
||||
<prompt phrase="Para guardar la grabación..." filename="vm-save_recording.wav"/>
|
||||
<prompt phrase="Para regrabar..." filename="vm-rerecord.wav"/>
|
||||
<prompt phrase="Para marcar este mensaje como urgente..." filename="vm-mark-urgent.wav"/>
|
||||
<prompt phrase="Para continuar..." filename="vm-continue.wav"/>
|
||||
<prompt phrase="Para escuchar la grabación de nuevo..." filename="vm-listen_to_recording_again.wav"/>
|
||||
<prompt phrase="Para eliminar la grabación..." filename="vm-delete_recording.wav"/>
|
||||
<prompt phrase="Para enviar la grabación a su e-mail..." filename="vm-forward_to_email.wav"/>
|
||||
<prompt phrase="Saludo" filename="vm-greeting.wav"/>
|
||||
<prompt phrase="Seleccionado" filename="vm-selected.wav"/>
|
||||
<prompt phrase="...no está disponible." filename="vm-not_available.wav"/>
|
||||
<prompt phrase="Mensaje número..." filename="vm-message_number.wav"/>
|
||||
<prompt phrase="Eliminado" filename="vm-deleted.wav"/>
|
||||
<prompt phrase="Su grabación es demasiado corta, por favor intente de nuevo." filename="vm-too-small.wav"/>
|
||||
<prompt phrase="...en la bandeja de entrada." filename="vm-in_folder.wav"/>
|
||||
<prompt phrase="Para devolver la llamada..." filename="vm-return_call.wav"/>
|
||||
<prompt phrase="Urgente" filename="vm-urgent.wav"/>
|
||||
<prompt phrase="Este buzón está lleno. Por favor intente llamar mas tarde." filename="vm-mailbox_full.wav"/>
|
||||
<prompt phrase="Bienvenido a su nuevo buzón de voz. Para escuchar el tutorial y configurar su buzón, pulse 1. Para saltarlo pulse 2." filename="vm-tutorial_yes_no.wav"/>
|
||||
<prompt phrase="Necesito grabar su nombre y apellido. Esta grabación se usará entre otros en el servicio de directorio." filename="vm-tutorial_record_name.wav"/>
|
||||
<prompt phrase="Su número de identificación personal o PIN sirve para impedir a terceros el acceso a sus mensajes. Desea cambiar su PIN ahora?" filename="vm-tutorial_change_pin.wav"/>
|
||||
</voicemail>
|
||||
<directory>
|
||||
<prompt phrase="Por favor introduzca las primeras letras del nombre buscado." filename="dir-enter_person.wav"/>
|
||||
<prompt phrase="...apellido..." filename="dir-last_name.wav"/>
|
||||
<prompt phrase="Para buscar por..." filename="dir-to_search_by.wav"/>
|
||||
<prompt phrase="...nombre..." filename="dir-first_name.wav"/>
|
||||
<prompt phrase="No hay resultados que coincidan con su busqueda." filename="dir-no_matching_results.wav"/>
|
||||
<prompt phrase="...resultados coinciden con su busqueda." filename="dir-result_match.wav"/>
|
||||
<prompt phrase="Su busqueda genera demasiados resultados." filename="dir-too_many_result.wav"/>
|
||||
<prompt phrase="No hay más resultados." filename="dir-no_more_results.wav"/>
|
||||
<prompt phrase="Resultado número..." filename="dir-result_number.wav"/>
|
||||
<prompt phrase="...en la extensión..." filename="dir-at_extension.wav"/>
|
||||
<prompt phrase="Para seleccionar este resultado..." filename="dir-to_select_entry.wav"/>
|
||||
<prompt phrase="Para el resultado siguiente..." filename="dir-for_next.wav"/>
|
||||
<prompt phrase="Para el resultado previo..." filename="dir-for_prev.wav"/>
|
||||
<prompt phrase="Para empezar una nueva busqueda..." filename="dir-start_new_search.wav"/>
|
||||
<prompt phrase="Necesita especificar un mínimo de..." filename="dir-specify_mininum.wav"/>
|
||||
<prompt phrase="...letras del nombre buscado." filename="dir-letters_of_person_name.wav"/>
|
||||
<prompt phrase="Por favor intentelo de nuevo." filename="dir-please_try_again.wav"/>
|
||||
<prompt phrase="Pulse..." filename="dir-press.wav" info="we can copy vm/vm-press.wav"/>
|
||||
</directory>
|
||||
<conference>
|
||||
<prompt phrase="NULL" filename="conf-ack.wav" type="tone"/>
|
||||
<prompt phrase="NULL" filename="conf-nack.wav" type="tone"/>
|
||||
<prompt phrase="Usted ahora está silenciado." filename="conf-muted.wav"/>
|
||||
<prompt phrase="Usted ya no está silenciado." filename="conf-unmuted.wav"/>
|
||||
<prompt phrase="En este momento usted es la única persona en la conferencia." filename="conf-alone.wav"/>
|
||||
<prompt phrase="NULL" filename="conf-perpetual.wav" type="music"/>
|
||||
<prompt phrase="NULL" filename="conf-enter.wav" type="tone"/>
|
||||
<prompt phrase="NULL" filename="conf-exit.wav" type="tone"/>
|
||||
<prompt phrase="Usted ha sido expulsado de la conferencia." filename="conf-kicked.wav"/>
|
||||
<prompt phrase="Esta conferencia está bloqueada." filename="conf-locked.wav"/>
|
||||
<prompt phrase="La conferencia está ahora bloqueada." filename="conf-is-locked.wav"/>
|
||||
<prompt phrase="La conferencia está ahora desbloqueada." filename="conf-is-unlocked.wav"/>
|
||||
<prompt phrase="Por favor ingrese el PIN de la conferencia." filename="conf-pin.wav"/>
|
||||
<prompt phrase="PIN inválido, intente de nuevo." filename="conf-bad-pin.wav"/>
|
||||
<prompt phrase="Hasta luego." filename="conf-goodbye.wav"/>
|
||||
<prompt phrase="Bienvenido a la conferencia." filename="conf-welcome.wav"/>
|
||||
</conference>
|
||||
<ivr>
|
||||
<prompt phrase="Número de cuenta" filename="ivr-account_number.wav"/>
|
||||
<prompt phrase="Conectar con quien llama" filename="ivr-connect_to_caller.wav"/>
|
||||
<prompt phrase="Si conoce la extensión, por favor ingrésela ahora" filename="ivr-enter_ext_pound.wav"/>
|
||||
<prompt phrase="por favor ingrese el número de una extensión seguido del signo de número" filename="ivr-enter_ext.wav"/>
|
||||
<prompt phrase="Para esta persona..." filename="ivr-for_this_person.wav"/>
|
||||
<prompt phrase="Por favor espere mientras conecto su llamada." filename="ivr-hold_connect_call.wav"/>
|
||||
<prompt phrase="Lo siento..." filename="ivr-im_sorry.wav"/>
|
||||
<prompt phrase="Por favor..." filename="ivr-please.wav"/>
|
||||
<prompt phrase="Por favor devuelva nuestra llamada al..." filename="ivr-please_return_our_call_at.wav"/>
|
||||
<prompt phrase="Acerca del número de referencia" filename="ivr-regarding_reference_number.wav"/>
|
||||
<prompt phrase="Este es un ejemplo de un submenú de audio respuesta..." filename="ivr-sample_submenu.wav"/>
|
||||
<prompt phrase="Por favor diga su nombre después del tono." filename="ivr-say_name.wav"/>
|
||||
<prompt phrase="Enviar a esta persona que llama al buzón de voz." filename="ivr-send_to_voicemail.wav"/>
|
||||
<prompt phrase="Para hablar con un representante de servicio al cliente..." filename="ivr-speak_to_a_customer_service_representative.wav"/>
|
||||
<prompt phrase="Tomar un mensaje" filename="ivr-take_a_message.wav"/>
|
||||
<prompt phrase="Gracias" filename="ivr-thank_you.wav"/>
|
||||
<prompt phrase="Esa fue una entrada inválida." filename="ivr-that_was_an_invalid_entry.wav"/>
|
||||
<prompt phrase="Esta es una llamada de..." filename="ivr-this_is_a_call_from.wav"/>
|
||||
<prompt phrase="Este menú de audiorrespuesta le permitirá probar algunas de las características..." filename="ivr-this_ivr_will_let_you_test_features.wav"/>
|
||||
<prompt phrase="Para llamar a la conferencia de FreeSWITCH..." filename="ivr-to_call_the_freeswitch_conference.wav"/>
|
||||
<prompt phrase="Para hacer una prueba de eco de FreeSWITCH..." filename="ivr-to_do_a_freeswitch_echo_test.wav"/>
|
||||
<prompt phrase="Para hacer una prueba de eco de FWD..." filename="ivr-to_do_a_fwd_echo_test.wav"/>
|
||||
<prompt phrase="Para escuchar un ejemplo de un submenú de audio respuesta..." filename="ivr-to_hear_sample_submenu.wav"/>
|
||||
<prompt phrase="Para escuchar simios gritando..." filename="ivr-to_hear_screaming_monkeys.wav"/>
|
||||
<prompt phrase="Para escuchar música de llamada en espera..." filename="ivr-to_listen_to_moh.wav"/>
|
||||
<prompt phrase="Para repetir estas opciones..." filename="ivr-to_repeat_these_options.wav"/>
|
||||
<prompt phrase="Para regresar al menú anterior..." filename="ivr-to_return_to_previous_menu.wav"/>
|
||||
<prompt phrase="Para hablar con un operador..." filename="ivr-to_speak_with_an_operator.wav"/>
|
||||
<prompt phrase="Bienvenido a FreeSWITCH, el futuro de la telefonía." filename="ivr-welcome_to_freeswitch.wav"/>
|
||||
<prompt phrase="Usted puede colgar en cualquier momento para salir." filename="ivr-you_may_exit_by_hanging_up.wav"/>
|
||||
<prompt phrase="O" filename="ivr-or.wav"/>
|
||||
<prompt phrase="No" filename="ivr-not.wav"/>
|
||||
<prompt phrase="Llamar" filename="ivr-call.wav"/>
|
||||
<prompt phrase="Usted puede..." filename="ivr-you_may.wav"/>
|
||||
<prompt phrase="Hola" filename="ivr-hello.wav"/>
|
||||
<prompt phrase="Usando el teclado de su teléfono..." filename="ivr-use_telephone_keypad.wav"/>
|
||||
<prompt phrase="por favor deletree el nombre de la persona a la cual está intentando contactar." filename="ivr-spell_name.wav"/>
|
||||
<prompt phrase="Primero el apellido" filename="ivr-last_name_first.wav"/>
|
||||
<prompt phrase="Primero el nombre" filename="ivr-first_name_first.wav"/>
|
||||
<prompt phrase="Presione 1 para Q ó Z." filename="ivr-press_one_q_or_z.wav"/>
|
||||
<prompt phrase="Ventas" filename="ivr-sales.wav"/>
|
||||
<prompt phrase="Servicio al cliente" filename="ivr-customer_service.wav"/>
|
||||
<prompt phrase="Soporte técnico" filename="ivr-technical_support.wav"/>
|
||||
<prompt phrase="Operador" filename="ivr-operator.wav"/>
|
||||
<prompt phrase="Usted marcó una extensión inválida." filename="ivr-you_have_dialed_an_invalid_extension.wav"/>
|
||||
<prompt phrase="Por favor introduzca su número de extensión, seguido de la tecla almohadilla." filename="ivr-please_enter_extension_followed_by_pound.wav"/>
|
||||
<prompt phrase="Por favor introduzca su contraseña, seguido de la tecla almohadilla." filename="ivr-please_enter_pin_followed_by_pound.wav"/>
|
||||
<prompt phrase="Su contraseña o extensión es inválida." filename="ivr-pin_or_extension_is-invalid.wav"/>
|
||||
<prompt phrase="Usted esta a punto de asociar este teléfono a su cuenta..." filename="ivr-you_are_about_to_provision_this_phone.wav"/>
|
||||
<prompt phrase="Por favor vuelva a introducir su contraseña para confirmar." filename="ivr-please_reenter_your_pin.wav"/>
|
||||
<prompt phrase="Para registrarse en ClueCon, por favor pulse..." filename="ivr-register_for_cluecon.wav"/>
|
||||
<prompt phrase="Para conectarse..." filename="ivr-to_log_in.wav"/>
|
||||
<prompt phrase="Para desconectarse..." filename="ivr-to_log_out.wav"/>
|
||||
<prompt phrase="Usted está ahora conectado." filename="ivr-you_are_now_logged_in.wav"/>
|
||||
<prompt phrase="Usted está ahora desconectado." filename="ivr-you_are_now_logged_out.wav"/>
|
||||
<prompt phrase="Por favor intentelo de nuevo." filename="ivr-please_try_again.wav"/>
|
||||
<prompt phrase="Usted está a punto de asociar este teléfono a su cuenta de forma permanente." filename="ivr-provision_phone_permanently_to_extension.wav"/>
|
||||
<prompt phrase="Por favor introduzca su número de extensión con la cual desea asociar su teléfono, seguido de la tecla almohadilla." filename="ivr-extension_to_provision_this_phone.wav"/>
|
||||
<prompt phrase="Gracias, este teléfono va a reiniciarse ahora." filename="ivr-this_phone_will_now_reboot.wav"/>
|
||||
<prompt phrase="Gracias, su grabación ha sido guardada." filename="ivr-recording_saved.wav"/>
|
||||
<prompt phrase="Pulse 1 para guardar su grabación. Pulse 2 para escuchar su grabación. Pulse 3 para volver a grabar." filename="ivr-save_review_record.wav"/>
|
||||
<prompt phrase="En este momento, el sistema no puede guardar su fichero de audio. Por favor intentelo de nuevo." filename="ivr-unable_save.wav"/>
|
||||
<prompt phrase="Usted está en la posición..." filename="ivr-you_are_number.wav"/>
|
||||
<prompt phrase="...en la cola de espera." filename="ivr-in_line.wav"/>
|
||||
<prompt phrase="Gracias por permanecer en espera." filename="ivr-thank_you_for_holding.wav"/>
|
||||
<prompt phrase="El tiempo estimado de espera es..." filename="ivr-estimated_hold_time.wav"/>
|
||||
<prompt phrase="Más de..." filename="ivr-more_than.wav"/>
|
||||
<prompt phrase="Menos de..." filename="ivr-less_than.wav"/>
|
||||
<prompt phrase="Empieze a grabar." filename="ivr-begin_recording.wav "/>
|
||||
<prompt phrase="El desvío de llamada ha sido desactivado." filename="ivr-call_forwarding_has_been_cancelled.wav"/>
|
||||
<prompt phrase="El desvío de llamada ha sido activado." filename="ivr-call_forwarding_has_been_set.wav"/>
|
||||
<prompt phrase="Por favor introduzca el número de teléfono." filename="ivr-please_enter_the_phone_number.wav"/>
|
||||
<prompt phrase="Por favor diga su nombre, y la razón de la llamada." filename="ivr-please_state_your_name_and_reason_for_calling.wav"/>
|
||||
<prompt phrase="Para aceptar, pulse 1. Para rechazar, pulse 2. Para mandar a buzón de voz, pulse 3." filename="ivr-accept_reject_voicemail.wav"/>
|
||||
<prompt phrase="Llamada entrante." filename="ivr-incoming_call.wav"/>
|
||||
<prompt phrase="Gracias por llamar." filename="ivr-thank_you_for_calling.wav"/>
|
||||
<prompt phrase="Por favor mentengase a la espera. Su llamada será atendida en un momento." filename="ivr-stay_on_line_call_answered_momentarily.wav"/>
|
||||
<prompt phrase="Su llamada está siendo procesada." filename="ivr-call_being_transferred.wav"/>
|
||||
<prompt phrase="Por favor disfrute de la música mientras su llamada está siendo procesada..." filename="ivr-enjoy_music_while_transfer.wav"/>
|
||||
<prompt phrase="Usted tiene una llamada de..." filename="ivr-call_from.wav"/>
|
||||
<prompt phrase="Este menú no tiene entradas. Por favor contacte con el administrador." filename="ivr-no_menu_items.wav"/>
|
||||
<prompt phrase="Para el servicio de directorio, pulse..." filename="ivr-for_directory_press.wav"/>
|
||||
<prompt phrase="Usando las teclas de su teléfono..." filename="ivr-using_telephone_keypad.wav"/>
|
||||
<prompt phrase="Introduzca las primeras letras del apellido de la persona." filename="ivr-enter_letters_last_name.wav"/>
|
||||
<prompt phrase="Introduzca las primeras letras del nombre de la persona." filename="ivr-enter_letters_first_name.wav"/>
|
||||
<prompt phrase="Introduzca las primeras letras del nombre o apellido de la persona." filename="ivr-enter_letters_first_or_last_name.wav"/>
|
||||
<prompt phrase="Si es correcto, pulse..." filename="ivr-if_correct_press.wav"/>
|
||||
<prompt phrase="Sino, pulse..." filename="ivr-if_not_press.wav"/>
|
||||
<prompt phrase="Cuando termine, pulse la tecla almohadilla." filename="ivr-finished_pound_hash_key.wav"/>
|
||||
<prompt phrase="La función de No Molestar ha sido activada." filename="ivr-dnd_activated.wav"/>
|
||||
<prompt phrase="La función de No Molestar ha sido desactivada." filename="ivr-dnd_cancelled.wav"/>
|
||||
<prompt phrase="Pulse cualquier otro dígito..." filename="ivr-any_other_digit.wav"/>
|
||||
<prompt phrase="Pulse uno si su respuesta es sí. Pulse dos si su respuesta es no." filename="ivr-one_yes_two_no.wav"/>
|
||||
<prompt phrase="Por favor introduzca el número de la cola, seguido de la tecla almohadilla." filename="ivr-enter_queue_number.wav"/>
|
||||
<prompt phrase="Por favor introduzca el..." filename="ivr-please_enter_the.wav"/>
|
||||
<prompt phrase="Número." filename="ivr-number.wav"/>
|
||||
<prompt phrase="...seguido de la tecla almohadilla." filename="ivr-followed_by_pound.wav"/>
|
||||
<prompt phrase="El balance de la cuenta es..." filename="ivr-account_balance_is.wav"/>
|
||||
<prompt phrase="Gracias por llamar. Si conoce la extensión de su destino, por favor marquela ahora. Para acceder al directorio, pulse..." filename="ivr-generic_greeting.wav"/>
|
||||
<prompt phrase="...fichero..." filename="ivr-file.wav"/>
|
||||
<prompt phrase="...ficheros..." filename="ivr-files-.wav"/>
|
||||
<prompt phrase="Para una llamada de despertador..." filename="ivr-for_a_wakeup_call.wav"/>
|
||||
<prompt phrase="Este es el servicio de despertador." filename="ivr-this_is_your_wakeup_call.wav"/>
|
||||
<prompt phrase="Para solicitar una llamada de despertador..." filename="ivr-request_wakeup_call.wav"/>
|
||||
<prompt phrase="Para confirmar la llamada de despertador..." filename="ivr-confirm_wakeup_call.wav"/>
|
||||
<prompt phrase="Para anular la llamada de despertador..." filename="ivr-cancel_wakeup_call.wav"/>
|
||||
<prompt phrase="Usted ha solicitado una llamada de despertador para..." filename="ivr-requested_wakeup_call_for.wav"/>
|
||||
<prompt phrase="Usted no ha solicitado llamadas de despertador." filename="ivr-not_requested_wakeup_call.wav"/>
|
||||
<prompt phrase="Su llamada de despertador ha sido anulada." filename="ivr-wakeup_call_cancelled.wav"/>
|
||||
<prompt phrase="Para una llamada diaria de despertador..." filename="ivr-for_daily_wakeup_call.wav"/>
|
||||
<prompt phrase="Llamada diaria de despertador..." filename="ivr-daily_wakeup_call.wav"/>
|
||||
<prompt phrase="Para llamadas diarias de despertador..." filename="ivr-for_daily_wakeup_calls.wav"/>
|
||||
<prompt phrase="Para una llamada de despertador única..." filename="ivr-for_one_time_wakeup_call.wav"/>
|
||||
<prompt phrase="Llamada de despertador única..." filename="ivr-one_time_wakeup_call.wav"/>
|
||||
<prompt phrase="...llamada de despertador..." filename="ivr-wakeup_call.wav"/>
|
||||
<prompt phrase="¡Vamos despierta cielo!" filename="ivr-wakey_wakey_sunshine.wav"/>
|
||||
<prompt phrase="Bienvenido." filename="ivr-welcome.wav"/>
|
||||
<prompt phrase="Bienvenido a..." filename="ivr-welcome_to.wav"/>
|
||||
<prompt phrase="Buenos días." filename="ivr-good_morning.wav"/>
|
||||
<prompt phrase="Buenas tardes." filename="ivr-good_afternoon.wav"/>
|
||||
<prompt phrase="Buenas noches." filename="ivr-good_evening.wav"/>
|
||||
<prompt phrase="Gracias." filename="ivr-Thank_you.wav"/>
|
||||
<prompt phrase="Para..." filename="ivr-for.wav"/>
|
||||
<prompt phrase="El tiempo de espera esta siendo anormalmente elevado." filename="ivr-longer_than_usual_hold_times.wav"/>
|
||||
<prompt phrase="Usted es el..." filename="ivr-you_are_the.wav"/>
|
||||
<prompt phrase="Un momento por favor." filename="ivr-one_moment_please.wav"/>
|
||||
<prompt phrase="Su llamada será atendida según el orden de entrada." filename="ivr-call_answered_order_received.wav"/>
|
||||
<prompt phrase="Por favor introduzca el número de conferencia, seguido de la tecla almohadilla." filename="conf-enter_conf_number.wav"/>
|
||||
<prompt phrase="Introduzca el PIN de la conferencia, seguido de la tecla almohadilla." filename="conf-enter_conf_pin.wav"/>
|
||||
<prompt phrase="...se incorporó a la conferencia." filename="conf-has_joined.wav"/>
|
||||
<prompt phrase="...ha abandonado la conferencia." filename="conf-has_left.wav"/>
|
||||
<prompt phrase="Usted entró..." filename="ivr-you_entered.wav"/>
|
||||
<prompt phrase="Número de extensión..." filename="ivr-extension_number.wav"/>
|
||||
<prompt phrase="Por favor mantengase a la espera mientras contactamos con su destino." filename="ivr-please_hold_while_party_contacted.wav"/>
|
||||
<prompt phrase="Por favor disfrute de la música mientras le conectamos con su destino." filename="ivr-please_enjoy_music_while_party_reached.wav"/>
|
||||
<prompt phrase="Gracias por llamar. Si conoce la extensión de su destino, por favor marquela ahora, o marque nueve para el servicio de directorio." filename="ivr-generic_greeting.wav"/>
|
||||
<prompt phrase="Si es correcto, pulse 1. Sino, pulse 2." filename="ivr-if_correct_one_if_not_two.wav"/>
|
||||
<prompt phrase="Para repetir esta información..." filename="ivr-repeat_this_information.wav"/>
|
||||
<prompt phrase="No no no!" filename="ivr-no_no_no.wav"/>
|
||||
<prompt phrase="Era su intención pulsar esta tecla?" filename="ivr-did_you_mean_to_press_key.wav"/>
|
||||
<prompt phrase="Pensaba Usted DE VERDAD pulsar esta tecla?" filename="ivr-seriously_mean_to_press_key.wav"/>
|
||||
<prompt phrase="Oh DA IGUAL." filename="ivr-oh_whatever.wav"/>
|
||||
<prompt phrase="No más! Un error más y le colgaré a la cara." filename="ivr-one_more_mistake.wav"/>
|
||||
<prompt phrase="Felicitaciones. Ha pulsado estrella. Esto no significa que ES una estrella. Tan solo significa que puede pulsar teclas y probablemente tiene dedos." filename="ivr-congratulations_you_pressed_star.wav"/>
|
||||
<prompt phrase="Todos nuestros ingenieros están ocupados en demostrar lo impresionante que es el CudaTel." filename="ivr-engineers_busy_assisting_other_sales.wav"/>
|
||||
<prompt phrase="La persona con la que intenta hablar no está disponible y no tiene buzón de voz." filename="vm-not_available_no_voicemail.wav"/>
|
||||
<prompt phrase="Este mensaje se auto-destruira en 5, 4, 3, 2, 1..." filename="ivr-message_self_destruct.wav"/>
|
||||
<prompt phrase="Su llamada ya está silenciada." filename="conf-you_are_already_muted.wav"/>
|
||||
<prompt phrase="Su llamada ha sido silenciada en ambos sentidos." filename="conf-you_are_now_bidirectionally_muted.wav"/>
|
||||
<prompt phrase="Todas sus llamadas nos pertenecen." filename="ivr-all_your_call_are_belong_to_us.wav"/>
|
||||
<prompt phrase="Me encanta como está pulsando estas teclas!" filename="ivr-love_those_touch_tones.wav"/>
|
||||
<prompt phrase="No, no tenemos bananas." filename="ivr-yes_we_have_no_bananas.wav"/>
|
||||
<prompt phrase="Hombre, estas siendo ridículo!" filename="ivr-dude_you_suck.wav"/>
|
||||
<prompt phrase="Su llamada es muy importante para nosotros, pero su bienestar mental no lo es, asi que estamos felices mantenerle a la espera, torturandole indefinidamente con nuestra péssima música en espera." filename="ivr-on_hold_indefinitely.wav"/>
|
||||
<prompt phrase="...ha dejado el edificio." filename="ivr-has_left_the_building.wav"/>
|
||||
<prompt phrase="Este teléfono no está asignado y no puede ser usado para realizar llamadas externas." filename="ivr-phone_is_unassigned.wav"/>
|
||||
<prompt phrase="Este teléfono no está configurado correctamente." filename="ivr-phone_not_configured.wav"/>
|
||||
<prompt phrase="Felicitaciones! Este teléfono está configurado correctamente y puede ahora ser asociado a un usuario." filename="ivr-phone_is_configured_properly.wav"/>
|
||||
<prompt phrase="Por favor contacte con el administrador del sistema para obtener asistencia." filename="ivr-contact_system_administrator.wav"/>
|
||||
<prompt phrase="Barracuda Networks" filename="ivr-barracuda_networks.wav"/>
|
||||
<prompt phrase="CudaTel Communication Server" filename="ivr-cudatel_communication_server.wav"/>
|
||||
<prompt phrase="Por favor introduzca las primeras letras del nombre o apellido de la persona." filename="dir-enter_person_first_or_last.wav"/>
|
||||
<prompt phrase="No hay llamadas en espera en esta cola." filename="ivr-no_calls_waiting_in_queue.wav"/>
|
||||
<prompt phrase="Brian West" filename="misc-Brian_West.wav"/>
|
||||
<prompt phrase="Anthony Minessale" filename="misc-Anthony_Minessale.wav"/>
|
||||
<prompt phrase="Michael Jerris" filename="misc-Michael_Jerris.wav"/>
|
||||
<prompt phrase="Raymond Chandler" filename="misc-Raymond_Chandler.wav"/>
|
||||
<prompt phrase="Michael Collins" filename="misc-Michael_Collins.wav"/>
|
||||
<prompt phrase="Mark Mann" filename="misc-Mark_Mann.wav"/>
|
||||
<prompt phrase="William King" filename="misc-William_King.wav"/>
|
||||
<prompt phrase="Rudy Fleminger" filename="misc-Rudy_Fleminger.wav"/>
|
||||
<prompt phrase="Andrew Thompson" filename="misc-Andrew_Thompson.wav"/>
|
||||
<prompt phrase="Graham Saathoff" filename="misc-Graham_Saathoff.wav"/>
|
||||
<prompt phrase="Nicholaus Belluni" filename="misc-Nicholaus_Belluni.wav"/>
|
||||
<prompt phrase="Sean Heiney" filename="misc-Sean_Heiney.wav"/>
|
||||
</ivr>
|
||||
<misc>
|
||||
<prompt phrase="Esta llamada ha sido asegurada." filename="call_secured.wav"/>
|
||||
<prompt phrase="...seguido del signo de número." filename="followed.wav"/>
|
||||
<prompt phrase="Si usted es esta persona..." filename="if_you_are_this_person.wav"/>
|
||||
<prompt phrase="Si usted desea..." filename="if_you_would_like_to.wav"/>
|
||||
<prompt phrase="Diga el número de referencia..." filename="provide_reference_number.wav"/>
|
||||
<prompt phrase="Por favor pulse la extensión a la cual desea transferir." filename="transfer1.wav"/>
|
||||
<prompt phrase="Transferir" filename="transfer2.wav"/>
|
||||
<prompt phrase="Estamos tratando de contactar..." filename="we_are_trying_to_reach.wav"/>
|
||||
<prompt phrase="Un error ha ocurrido, por favor contacte al administrador." filename="error.wav"/>
|
||||
<prompt phrase="Su llamada será terminada en..." filename="misc-your_call_will_be_terminated_in.wav"/>
|
||||
<prompt phrase="Su llamada ha sido terminada." filename="misc-your_call_has_been_terminated.wav"/>
|
||||
</misc>
|
||||
<zrtp>
|
||||
<!-- base256 prompts for SAS -->
|
||||
<prompt phrase="Algol" filename="Algol.wav"/>
|
||||
<prompt phrase="Apollo" filename="Apollo.wav"/>
|
||||
<prompt phrase="Athens" filename="Athens.wav"/>
|
||||
<prompt phrase="Atlantic" filename="Atlantic.wav"/>
|
||||
<prompt phrase="Aztec" filename="Aztec.wav"/>
|
||||
<prompt phrase="Babylon" filename="Babylon.wav"/>
|
||||
<prompt phrase="Belfast" filename="Belfast.wav"/>
|
||||
<prompt phrase="Bradbury" filename="Bradbury.wav"/>
|
||||
<prompt phrase="Brazilian" filename="Brazilian.wav"/>
|
||||
<prompt phrase="Burbank" filename="Burbank.wav"/>
|
||||
<prompt phrase="Burlington" filename="Burlington.wav"/>
|
||||
<prompt phrase="Camelot" filename="Camelot.wav"/>
|
||||
<prompt phrase="Capricorn" filename="Capricorn.wav"/>
|
||||
<prompt phrase="Cherokee" filename="Cherokee.wav"/>
|
||||
<prompt phrase="Chicago" filename="Chicago.wav"/>
|
||||
<prompt phrase="Christmas" filename="Christmas.wav"/>
|
||||
<prompt phrase="Dakota" filename="Dakota.wav"/>
|
||||
<prompt phrase="December" filename="December.wav"/>
|
||||
<prompt phrase="Dupont" filename="Dupont.wav"/>
|
||||
<prompt phrase="Eskimo" filename="Eskimo.wav"/>
|
||||
<prompt phrase="Galveston" filename="Galveston.wav"/>
|
||||
<prompt phrase="Geiger" filename="Geiger.wav"/>
|
||||
<prompt phrase="Hamilton" filename="Hamilton.wav"/>
|
||||
<prompt phrase="Istanbul" filename="Istanbul.wav"/>
|
||||
<prompt phrase="Jamaica" filename="Jamaica.wav"/>
|
||||
<prompt phrase="Jupiter" filename="Jupiter.wav"/>
|
||||
<prompt phrase="Medusa" filename="Medusa.wav"/>
|
||||
<prompt phrase="Mohawk" filename="Mohawk.wav"/>
|
||||
<prompt phrase="Montana" filename="Montana.wav"/>
|
||||
<prompt phrase="Neptune" filename="Neptune.wav"/>
|
||||
<prompt phrase="Norwegian" filename="Norwegian.wav"/>
|
||||
<prompt phrase="Oakland" filename="Oakland.wav"/>
|
||||
<prompt phrase="October" filename="October.wav"/>
|
||||
<prompt phrase="Ohio" filename="Ohio.wav"/>
|
||||
<prompt phrase="Orlando" filename="Orlando.wav"/>
|
||||
<prompt phrase="Pacific" filename="Pacific.wav"/>
|
||||
<prompt phrase="Pandora" filename="Pandora.wav"/>
|
||||
<prompt phrase="Pegasus" filename="Pegasus.wav"/>
|
||||
<prompt phrase="Pluto" filename="Pluto.wav"/>
|
||||
<prompt phrase="Saturday" filename="Saturday.wav"/>
|
||||
<prompt phrase="Scotland" filename="Scotland.wav"/>
|
||||
<prompt phrase="Trojan" filename="Trojan.wav"/>
|
||||
<prompt phrase="Virginia" filename="Virginia.wav"/>
|
||||
<prompt phrase="Vulcan" filename="Vulcan.wav"/>
|
||||
<prompt phrase="Waterloo" filename="Waterloo.wav"/>
|
||||
<prompt phrase="Wichita" filename="Wichita.wav"/>
|
||||
<prompt phrase="Wilmington" filename="Wilmington.wav"/>
|
||||
<prompt phrase="Wyoming" filename="Wyoming.wav"/>
|
||||
<prompt phrase="Yucatan" filename="Yucatan.wav"/>
|
||||
<prompt phrase="Zulu" filename="Zulu.wav"/>
|
||||
<prompt phrase="aardvark" filename="aardvark.wav"/>
|
||||
<prompt phrase="absurd" filename="absurd.wav"/>
|
||||
<prompt phrase="accrue" filename="accrue.wav"/>
|
||||
<prompt phrase="acme" filename="acme.wav"/>
|
||||
<prompt phrase="adrift" filename="adrift.wav"/>
|
||||
<prompt phrase="adroitness" filename="adroitness.wav"/>
|
||||
<prompt phrase="adult" filename="adult.wav"/>
|
||||
<prompt phrase="adviser" filename="adviser.wav"/>
|
||||
<prompt phrase="afflict" filename="afflict.wav"/>
|
||||
<prompt phrase="aftermath" filename="aftermath.wav"/>
|
||||
<prompt phrase="aggregate" filename="aggregate.wav"/>
|
||||
<prompt phrase="ahead" filename="ahead.wav"/>
|
||||
<prompt phrase="aimless" filename="aimless.wav"/>
|
||||
<prompt phrase="alkali" filename="alkali.wav"/>
|
||||
<prompt phrase="allow" filename="allow.wav"/>
|
||||
<prompt phrase="almighty" filename="almighty.wav"/>
|
||||
<prompt phrase="alone" filename="alone.wav"/>
|
||||
<prompt phrase="ammo" filename="ammo.wav"/>
|
||||
<prompt phrase="amulet" filename="amulet.wav"/>
|
||||
<prompt phrase="amusement" filename="amusement.wav"/>
|
||||
<prompt phrase="ancient" filename="ancient.wav"/>
|
||||
<prompt phrase="antenna" filename="antenna.wav"/>
|
||||
<prompt phrase="apple" filename="apple.wav"/>
|
||||
<prompt phrase="applicant" filename="applicant.wav"/>
|
||||
<prompt phrase="armistice" filename="armistice.wav"/>
|
||||
<prompt phrase="article" filename="article.wav"/>
|
||||
<prompt phrase="artist" filename="artist.wav"/>
|
||||
<prompt phrase="assume" filename="assume.wav"/>
|
||||
<prompt phrase="asteroid" filename="asteroid.wav"/>
|
||||
<prompt phrase="atlas" filename="atlas.wav"/>
|
||||
<prompt phrase="atmosphere" filename="atmosphere.wav"/>
|
||||
<prompt phrase="autopsy" filename="autopsy.wav"/>
|
||||
<prompt phrase="baboon" filename="baboon.wav"/>
|
||||
<prompt phrase="backfield" filename="backfield.wav"/>
|
||||
<prompt phrase="backward" filename="backward.wav"/>
|
||||
<prompt phrase="backwater" filename="backwater.wav"/>
|
||||
<prompt phrase="banjo" filename="banjo.wav"/>
|
||||
<prompt phrase="barbecue" filename="barbecue.wav"/>
|
||||
<prompt phrase="beaming" filename="beaming.wav"/>
|
||||
<prompt phrase="bedlamp" filename="bedlamp.wav"/>
|
||||
<prompt phrase="beehive" filename="beehive.wav"/>
|
||||
<prompt phrase="beeswax" filename="beeswax.wav"/>
|
||||
<prompt phrase="befriend" filename="befriend.wav"/>
|
||||
<prompt phrase="belowground" filename="belowground.wav"/>
|
||||
<prompt phrase="berserk" filename="berserk.wav"/>
|
||||
<prompt phrase="bifocals" filename="bifocals.wav"/>
|
||||
<prompt phrase="billiard" filename="billiard.wav"/>
|
||||
<prompt phrase="bison" filename="bison.wav"/>
|
||||
<prompt phrase="blackjack" filename="blackjack.wav"/>
|
||||
<prompt phrase="blockade" filename="blockade.wav"/>
|
||||
<prompt phrase="blowtorch" filename="blowtorch.wav"/>
|
||||
<prompt phrase="bluebird" filename="bluebird.wav"/>
|
||||
<prompt phrase="bodyguard" filename="bodyguard.wav"/>
|
||||
<prompt phrase="bombast" filename="bombast.wav"/>
|
||||
<prompt phrase="bookseller" filename="bookseller.wav"/>
|
||||
<prompt phrase="bookshelf" filename="bookshelf.wav"/>
|
||||
<prompt phrase="borderline" filename="borderline.wav"/>
|
||||
<prompt phrase="bottomless" filename="bottomless.wav"/>
|
||||
<prompt phrase="brackish" filename="brackish.wav"/>
|
||||
<prompt phrase="bravado" filename="bravado.wav"/>
|
||||
<prompt phrase="breadline" filename="breadline.wav"/>
|
||||
<prompt phrase="breakaway" filename="breakaway.wav"/>
|
||||
<prompt phrase="breakup" filename="breakup.wav"/>
|
||||
<prompt phrase="brickyard" filename="brickyard.wav"/>
|
||||
<prompt phrase="briefcase" filename="briefcase.wav"/>
|
||||
<prompt phrase="businessman" filename="businessman.wav"/>
|
||||
<prompt phrase="butterfat" filename="butterfat.wav"/>
|
||||
<prompt phrase="button" filename="button.wav"/>
|
||||
<prompt phrase="buzzard" filename="buzzard.wav"/>
|
||||
<prompt phrase="candidate" filename="candidate.wav"/>
|
||||
<prompt phrase="cannonball" filename="cannonball.wav"/>
|
||||
<prompt phrase="caravan" filename="caravan.wav"/>
|
||||
<prompt phrase="caretaker" filename="caretaker.wav"/>
|
||||
<prompt phrase="celebrate" filename="celebrate.wav"/>
|
||||
<prompt phrase="cellulose" filename="cellulose.wav"/>
|
||||
<prompt phrase="cement" filename="cement.wav"/>
|
||||
<prompt phrase="certify" filename="certify.wav"/>
|
||||
<prompt phrase="chairlift" filename="chairlift.wav"/>
|
||||
<prompt phrase="chambermaid" filename="chambermaid.wav"/>
|
||||
<prompt phrase="chatter" filename="chatter.wav"/>
|
||||
<prompt phrase="checkup" filename="checkup.wav"/>
|
||||
<prompt phrase="chisel" filename="chisel.wav"/>
|
||||
<prompt phrase="choking" filename="choking.wav"/>
|
||||
<prompt phrase="chopper" filename="chopper.wav"/>
|
||||
<prompt phrase="clamshell" filename="clamshell.wav"/>
|
||||
<prompt phrase="classic" filename="classic.wav"/>
|
||||
<prompt phrase="classroom" filename="classroom.wav"/>
|
||||
<prompt phrase="cleanup" filename="cleanup.wav"/>
|
||||
<prompt phrase="clergyman" filename="clergyman.wav"/>
|
||||
<prompt phrase="clockwork" filename="clockwork.wav"/>
|
||||
<prompt phrase="cobra" filename="cobra.wav"/>
|
||||
<prompt phrase="coherence" filename="coherence.wav"/>
|
||||
<prompt phrase="combustion" filename="combustion.wav"/>
|
||||
<prompt phrase="commando" filename="commando.wav"/>
|
||||
<prompt phrase="commence" filename="commence.wav"/>
|
||||
<prompt phrase="company" filename="company.wav"/>
|
||||
<prompt phrase="component" filename="component.wav"/>
|
||||
<prompt phrase="concert" filename="concert.wav"/>
|
||||
<prompt phrase="concurrent" filename="concurrent.wav"/>
|
||||
<prompt phrase="confidence" filename="confidence.wav"/>
|
||||
<prompt phrase="conformist" filename="conformist.wav"/>
|
||||
<prompt phrase="congregate" filename="congregate.wav"/>
|
||||
<prompt phrase="consensus" filename="consensus.wav"/>
|
||||
<prompt phrase="consulting" filename="consulting.wav"/>
|
||||
<prompt phrase="corporate" filename="corporate.wav"/>
|
||||
<prompt phrase="corrosion" filename="corrosion.wav"/>
|
||||
<prompt phrase="councilman" filename="councilman.wav"/>
|
||||
<prompt phrase="cowbell" filename="cowbell.wav"/>
|
||||
<prompt phrase="crackdown" filename="crackdown.wav"/>
|
||||
<prompt phrase="cranky" filename="cranky.wav"/>
|
||||
<prompt phrase="crossover" filename="crossover.wav"/>
|
||||
<prompt phrase="crowfoot" filename="crowfoot.wav"/>
|
||||
<prompt phrase="crucial" filename="crucial.wav"/>
|
||||
<prompt phrase="crucifix" filename="crucifix.wav"/>
|
||||
<prompt phrase="crumpled" filename="crumpled.wav"/>
|
||||
<prompt phrase="crusade" filename="crusade.wav"/>
|
||||
<prompt phrase="cubic" filename="cubic.wav"/>
|
||||
<prompt phrase="cumbersome" filename="cumbersome.wav"/>
|
||||
<prompt phrase="customer" filename="customer.wav"/>
|
||||
<prompt phrase="dashboard" filename="dashboard.wav"/>
|
||||
<prompt phrase="deadbolt" filename="deadbolt.wav"/>
|
||||
<prompt phrase="decadence" filename="decadence.wav"/>
|
||||
<prompt phrase="decimal" filename="decimal.wav"/>
|
||||
<prompt phrase="deckhand" filename="deckhand.wav"/>
|
||||
<prompt phrase="designing" filename="designing.wav"/>
|
||||
<prompt phrase="detector" filename="detector.wav"/>
|
||||
<prompt phrase="detergent" filename="detergent.wav"/>
|
||||
<prompt phrase="determine" filename="determine.wav"/>
|
||||
<prompt phrase="dictator" filename="dictator.wav"/>
|
||||
<prompt phrase="dinosaur" filename="dinosaur.wav"/>
|
||||
<prompt phrase="direction" filename="direction.wav"/>
|
||||
<prompt phrase="disable" filename="disable.wav"/>
|
||||
<prompt phrase="disbelief" filename="disbelief.wav"/>
|
||||
<prompt phrase="disruptive" filename="disruptive.wav"/>
|
||||
<prompt phrase="distortion" filename="distortion.wav"/>
|
||||
<prompt phrase="document" filename="document.wav"/>
|
||||
<prompt phrase="dogsled" filename="dogsled.wav"/>
|
||||
<prompt phrase="dragnet" filename="dragnet.wav"/>
|
||||
<prompt phrase="drainage" filename="drainage.wav"/>
|
||||
<prompt phrase="dreadful" filename="dreadful.wav"/>
|
||||
<prompt phrase="drifter" filename="drifter.wav"/>
|
||||
<prompt phrase="dropper" filename="dropper.wav"/>
|
||||
<prompt phrase="drumbeat" filename="drumbeat.wav"/>
|
||||
<prompt phrase="drunken" filename="drunken.wav"/>
|
||||
<prompt phrase="dwelling" filename="dwelling.wav"/>
|
||||
<prompt phrase="eating" filename="eating.wav"/>
|
||||
<prompt phrase="edict" filename="edict.wav"/>
|
||||
<prompt phrase="egghead" filename="egghead.wav"/>
|
||||
<prompt phrase="eightball" filename="eightball.wav"/>
|
||||
<prompt phrase="embezzle" filename="embezzle.wav"/>
|
||||
<prompt phrase="enchanting" filename="enchanting.wav"/>
|
||||
<prompt phrase="endorse" filename="endorse.wav"/>
|
||||
<prompt phrase="endow" filename="endow.wav"/>
|
||||
<prompt phrase="enlist" filename="enlist.wav"/>
|
||||
<prompt phrase="enrollment" filename="enrollment.wav"/>
|
||||
<prompt phrase="enterprise" filename="enterprise.wav"/>
|
||||
<prompt phrase="equation" filename="equation.wav"/>
|
||||
<prompt phrase="equipment" filename="equipment.wav"/>
|
||||
<prompt phrase="erase" filename="erase.wav"/>
|
||||
<prompt phrase="escapade" filename="escapade.wav"/>
|
||||
<prompt phrase="escape" filename="escape.wav"/>
|
||||
<prompt phrase="everyday" filename="everyday.wav"/>
|
||||
<prompt phrase="examine" filename="examine.wav"/>
|
||||
<prompt phrase="exceed" filename="exceed.wav"/>
|
||||
<prompt phrase="existence" filename="existence.wav"/>
|
||||
<prompt phrase="exodus" filename="exodus.wav"/>
|
||||
<prompt phrase="eyeglass" filename="eyeglass.wav"/>
|
||||
<prompt phrase="eyetooth" filename="eyetooth.wav"/>
|
||||
<prompt phrase="facial" filename="facial.wav"/>
|
||||
<prompt phrase="fallout" filename="fallout.wav"/>
|
||||
<prompt phrase="fascinate" filename="fascinate.wav"/>
|
||||
<prompt phrase="filament" filename="filament.wav"/>
|
||||
<prompt phrase="finicky" filename="finicky.wav"/>
|
||||
<prompt phrase="flagpole" filename="flagpole.wav"/>
|
||||
<prompt phrase="flatfoot" filename="flatfoot.wav"/>
|
||||
<prompt phrase="flytrap" filename="flytrap.wav"/>
|
||||
<prompt phrase="forever" filename="forever.wav"/>
|
||||
<prompt phrase="fortitude" filename="fortitude.wav"/>
|
||||
<prompt phrase="fracture" filename="fracture.wav"/>
|
||||
<prompt phrase="framework" filename="framework.wav"/>
|
||||
<prompt phrase="freedom" filename="freedom.wav"/>
|
||||
<prompt phrase="frequency" filename="frequency.wav"/>
|
||||
<prompt phrase="frighten" filename="frighten.wav"/>
|
||||
<prompt phrase="gadgetry" filename="gadgetry.wav"/>
|
||||
<prompt phrase="gazelle" filename="gazelle.wav"/>
|
||||
<prompt phrase="getaway" filename="getaway.wav"/>
|
||||
<prompt phrase="glitter" filename="glitter.wav"/>
|
||||
<prompt phrase="glossary" filename="glossary.wav"/>
|
||||
<prompt phrase="glucose" filename="glucose.wav"/>
|
||||
<prompt phrase="goggles" filename="goggles.wav"/>
|
||||
<prompt phrase="goldfish" filename="goldfish.wav"/>
|
||||
<prompt phrase="gossamer" filename="gossamer.wav"/>
|
||||
<prompt phrase="graduate" filename="graduate.wav"/>
|
||||
<prompt phrase="gravity" filename="gravity.wav"/>
|
||||
<prompt phrase="gremlin" filename="gremlin.wav"/>
|
||||
<prompt phrase="guidance" filename="guidance.wav"/>
|
||||
<prompt phrase="guitarist" filename="guitarist.wav"/>
|
||||
<prompt phrase="hamburger" filename="hamburger.wav"/>
|
||||
<prompt phrase="hamlet" filename="hamlet.wav"/>
|
||||
<prompt phrase="handiwork" filename="handiwork.wav"/>
|
||||
<prompt phrase="hazardous" filename="hazardous.wav"/>
|
||||
<prompt phrase="headwaters" filename="headwaters.wav"/>
|
||||
<prompt phrase="hemisphere" filename="hemisphere.wav"/>
|
||||
<prompt phrase="hesitate" filename="hesitate.wav"/>
|
||||
<prompt phrase="hideaway" filename="hideaway.wav"/>
|
||||
<prompt phrase="highchair" filename="highchair.wav"/>
|
||||
<prompt phrase="hockey" filename="hockey.wav"/>
|
||||
<prompt phrase="holiness" filename="holiness.wav"/>
|
||||
<prompt phrase="hurricane" filename="hurricane.wav"/>
|
||||
<prompt phrase="hydraulic" filename="hydraulic.wav"/>
|
||||
<prompt phrase="impartial" filename="impartial.wav"/>
|
||||
<prompt phrase="impetus" filename="impetus.wav"/>
|
||||
<prompt phrase="inception" filename="inception.wav"/>
|
||||
<prompt phrase="indigo" filename="indigo.wav"/>
|
||||
<prompt phrase="indoors" filename="indoors.wav"/>
|
||||
<prompt phrase="indulge" filename="indulge.wav"/>
|
||||
<prompt phrase="inertia" filename="inertia.wav"/>
|
||||
<prompt phrase="infancy" filename="infancy.wav"/>
|
||||
<prompt phrase="inferno" filename="inferno.wav"/>
|
||||
<prompt phrase="informant" filename="informant.wav"/>
|
||||
<prompt phrase="insincere" filename="insincere.wav"/>
|
||||
<prompt phrase="insurgent" filename="insurgent.wav"/>
|
||||
<prompt phrase="integrate" filename="integrate.wav"/>
|
||||
<prompt phrase="intention" filename="intention.wav"/>
|
||||
<prompt phrase="inventive" filename="inventive.wav"/>
|
||||
<prompt phrase="inverse" filename="inverse.wav"/>
|
||||
<prompt phrase="involve" filename="involve.wav"/>
|
||||
<prompt phrase="island" filename="island.wav"/>
|
||||
<prompt phrase="jawbone" filename="jawbone.wav"/>
|
||||
<prompt phrase="keyboard" filename="keyboard.wav"/>
|
||||
<prompt phrase="kickoff" filename="kickoff.wav"/>
|
||||
<prompt phrase="kiwi" filename="kiwi.wav"/>
|
||||
<prompt phrase="klaxon" filename="klaxon.wav"/>
|
||||
<prompt phrase="leprosy" filename="leprosy.wav"/>
|
||||
<prompt phrase="letterhead" filename="letterhead.wav"/>
|
||||
<prompt phrase="liberty" filename="liberty.wav"/>
|
||||
<prompt phrase="locale" filename="locale.wav"/>
|
||||
<prompt phrase="lockup" filename="lockup.wav"/>
|
||||
<prompt phrase="maritime" filename="maritime.wav"/>
|
||||
<prompt phrase="matchmaker" filename="matchmaker.wav"/>
|
||||
<prompt phrase="maverick" filename="maverick.wav"/>
|
||||
<prompt phrase="megaton" filename="megaton.wav"/>
|
||||
<prompt phrase="merit" filename="merit.wav"/>
|
||||
<prompt phrase="microscope" filename="microscope.wav"/>
|
||||
<prompt phrase="microwave" filename="microwave.wav"/>
|
||||
<prompt phrase="midsummer" filename="midsummer.wav"/>
|
||||
<prompt phrase="millionaire" filename="millionaire.wav"/>
|
||||
<prompt phrase="minnow" filename="minnow.wav"/>
|
||||
<prompt phrase="miracle" filename="miracle.wav"/>
|
||||
<prompt phrase="miser" filename="miser.wav"/>
|
||||
<prompt phrase="misnomer" filename="misnomer.wav"/>
|
||||
<prompt phrase="molasses" filename="molasses.wav"/>
|
||||
<prompt phrase="molecule" filename="molecule.wav"/>
|
||||
<prompt phrase="monument" filename="monument.wav"/>
|
||||
<prompt phrase="mosquito" filename="mosquito.wav"/>
|
||||
<prompt phrase="mural" filename="mural.wav"/>
|
||||
<prompt phrase="music" filename="music.wav"/>
|
||||
<prompt phrase="narrative" filename="narrative.wav"/>
|
||||
<prompt phrase="nebula" filename="nebula.wav"/>
|
||||
<prompt phrase="necklace" filename="necklace.wav"/>
|
||||
<prompt phrase="newborn" filename="newborn.wav"/>
|
||||
<prompt phrase="newsletter" filename="newsletter.wav"/>
|
||||
<prompt phrase="nightbird" filename="nightbird.wav"/>
|
||||
<prompt phrase="obtuse" filename="obtuse.wav"/>
|
||||
<prompt phrase="offload" filename="offload.wav"/>
|
||||
<prompt phrase="onlooker" filename="onlooker.wav"/>
|
||||
<prompt phrase="optic" filename="optic.wav"/>
|
||||
<prompt phrase="opulent" filename="opulent.wav"/>
|
||||
<prompt phrase="orca" filename="orca.wav"/>
|
||||
<prompt phrase="outfielder" filename="outfielder.wav"/>
|
||||
<prompt phrase="pandemic" filename="pandemic.wav"/>
|
||||
<prompt phrase="paperweight" filename="paperweight.wav"/>
|
||||
<prompt phrase="paragon" filename="paragon.wav"/>
|
||||
<prompt phrase="paragraph" filename="paragraph.wav"/>
|
||||
<prompt phrase="paramount" filename="paramount.wav"/>
|
||||
<prompt phrase="passenger" filename="passenger.wav"/>
|
||||
<prompt phrase="payday" filename="payday.wav"/>
|
||||
<prompt phrase="peachy" filename="peachy.wav"/>
|
||||
<prompt phrase="pedigree" filename="pedigree.wav"/>
|
||||
<prompt phrase="penetrate" filename="penetrate.wav"/>
|
||||
<prompt phrase="perceptive" filename="perceptive.wav"/>
|
||||
<prompt phrase="performance" filename="performance.wav"/>
|
||||
<prompt phrase="pharmacy" filename="pharmacy.wav"/>
|
||||
<prompt phrase="pheasant" filename="pheasant.wav"/>
|
||||
<prompt phrase="phonetic" filename="phonetic.wav"/>
|
||||
<prompt phrase="photograph" filename="photograph.wav"/>
|
||||
<prompt phrase="physique" filename="physique.wav"/>
|
||||
<prompt phrase="pioneer" filename="pioneer.wav"/>
|
||||
<prompt phrase="playhouse" filename="playhouse.wav"/>
|
||||
<prompt phrase="pocketful" filename="pocketful.wav"/>
|
||||
<prompt phrase="politeness" filename="politeness.wav"/>
|
||||
<prompt phrase="positive" filename="positive.wav"/>
|
||||
<prompt phrase="potato" filename="potato.wav"/>
|
||||
<prompt phrase="preclude" filename="preclude.wav"/>
|
||||
<prompt phrase="prefer" filename="prefer.wav"/>
|
||||
<prompt phrase="preshrunk" filename="preshrunk.wav"/>
|
||||
<prompt phrase="printer" filename="printer.wav"/>
|
||||
<prompt phrase="processor" filename="processor.wav"/>
|
||||
<prompt phrase="provincial" filename="provincial.wav"/>
|
||||
<prompt phrase="prowler" filename="prowler.wav"/>
|
||||
<prompt phrase="proximate" filename="proximate.wav"/>
|
||||
<prompt phrase="puberty" filename="puberty.wav"/>
|
||||
<prompt phrase="publisher" filename="publisher.wav"/>
|
||||
<prompt phrase="pupil" filename="pupil.wav"/>
|
||||
<prompt phrase="puppy" filename="puppy.wav"/>
|
||||
<prompt phrase="pyramid" filename="pyramid.wav"/>
|
||||
<prompt phrase="python" filename="python.wav"/>
|
||||
<prompt phrase="quadrant" filename="quadrant.wav"/>
|
||||
<prompt phrase="quantity" filename="quantity.wav"/>
|
||||
<prompt phrase="quiver" filename="quiver.wav"/>
|
||||
<prompt phrase="quota" filename="quota.wav"/>
|
||||
<prompt phrase="racketeer" filename="racketeer.wav"/>
|
||||
<prompt phrase="ragtime" filename="ragtime.wav"/>
|
||||
<prompt phrase="ratchet" filename="ratchet.wav"/>
|
||||
<prompt phrase="rebellion" filename="rebellion.wav"/>
|
||||
<prompt phrase="rebirth" filename="rebirth.wav"/>
|
||||
<prompt phrase="recipe" filename="recipe.wav"/>
|
||||
<prompt phrase="recover" filename="recover.wav"/>
|
||||
<prompt phrase="reform" filename="reform.wav"/>
|
||||
<prompt phrase="regain" filename="regain.wav"/>
|
||||
<prompt phrase="reindeer" filename="reindeer.wav"/>
|
||||
<prompt phrase="rematch" filename="rematch.wav"/>
|
||||
<prompt phrase="repay" filename="repay.wav"/>
|
||||
<prompt phrase="repellent" filename="repellent.wav"/>
|
||||
<prompt phrase="replica" filename="replica.wav"/>
|
||||
<prompt phrase="reproduce" filename="reproduce.wav"/>
|
||||
<prompt phrase="resistor" filename="resistor.wav"/>
|
||||
<prompt phrase="responsive" filename="responsive.wav"/>
|
||||
<prompt phrase="retouch" filename="retouch.wav"/>
|
||||
<prompt phrase="retraction" filename="retraction.wav"/>
|
||||
<prompt phrase="retrieval" filename="retrieval.wav"/>
|
||||
<prompt phrase="retrospect" filename="retrospect.wav"/>
|
||||
<prompt phrase="revenge" filename="revenge.wav"/>
|
||||
<prompt phrase="revenue" filename="revenue.wav"/>
|
||||
<prompt phrase="revival" filename="revival.wav"/>
|
||||
<prompt phrase="revolver" filename="revolver.wav"/>
|
||||
<prompt phrase="reward" filename="reward.wav"/>
|
||||
<prompt phrase="rhythm" filename="rhythm.wav"/>
|
||||
<prompt phrase="ribcage" filename="ribcage.wav"/>
|
||||
<prompt phrase="ringbolt" filename="ringbolt.wav"/>
|
||||
<prompt phrase="robust" filename="robust.wav"/>
|
||||
<prompt phrase="rocker" filename="rocker.wav"/>
|
||||
<prompt phrase="ruffled" filename="ruffled.wav"/>
|
||||
<prompt phrase="sailboat" filename="sailboat.wav"/>
|
||||
<prompt phrase="sandalwood" filename="sandalwood.wav"/>
|
||||
<prompt phrase="sardonic" filename="sardonic.wav"/>
|
||||
<prompt phrase="savagery" filename="savagery.wav"/>
|
||||
<prompt phrase="sawdust" filename="sawdust.wav"/>
|
||||
<prompt phrase="scallion" filename="scallion.wav"/>
|
||||
<prompt phrase="scavenger" filename="scavenger.wav"/>
|
||||
<prompt phrase="scenic" filename="scenic.wav"/>
|
||||
<prompt phrase="scorecard" filename="scorecard.wav"/>
|
||||
<prompt phrase="seabird" filename="seabird.wav"/>
|
||||
<prompt phrase="select" filename="select.wav"/>
|
||||
<prompt phrase="sensation" filename="sensation.wav"/>
|
||||
<prompt phrase="sentence" filename="sentence.wav"/>
|
||||
<prompt phrase="shadow" filename="shadow.wav"/>
|
||||
<prompt phrase="shamrock" filename="shamrock.wav"/>
|
||||
<prompt phrase="showgirl" filename="showgirl.wav"/>
|
||||
<prompt phrase="skullcap" filename="skullcap.wav"/>
|
||||
<prompt phrase="skydive" filename="skydive.wav"/>
|
||||
<prompt phrase="slingshot" filename="slingshot.wav"/>
|
||||
<prompt phrase="slowdown" filename="slowdown.wav"/>
|
||||
<prompt phrase="snapline" filename="snapline.wav"/>
|
||||
<prompt phrase="snapshot" filename="snapshot.wav"/>
|
||||
<prompt phrase="snowcap" filename="snowcap.wav"/>
|
||||
<prompt phrase="snowslide" filename="snowslide.wav"/>
|
||||
<prompt phrase="sociable" filename="sociable.wav"/>
|
||||
<prompt phrase="solo" filename="solo.wav"/>
|
||||
<prompt phrase="southward" filename="southward.wav"/>
|
||||
<prompt phrase="souvenir" filename="souvenir.wav"/>
|
||||
<prompt phrase="soybean" filename="soybean.wav"/>
|
||||
<prompt phrase="spaniel" filename="spaniel.wav"/>
|
||||
<prompt phrase="spearhead" filename="spearhead.wav"/>
|
||||
<prompt phrase="specialist" filename="specialist.wav"/>
|
||||
<prompt phrase="speculate" filename="speculate.wav"/>
|
||||
<prompt phrase="spellbind" filename="spellbind.wav"/>
|
||||
<prompt phrase="spheroid" filename="spheroid.wav"/>
|
||||
<prompt phrase="spigot" filename="spigot.wav"/>
|
||||
<prompt phrase="spindle" filename="spindle.wav"/>
|
||||
<prompt phrase="spyglass" filename="spyglass.wav"/>
|
||||
<prompt phrase="stagehand" filename="stagehand.wav"/>
|
||||
<prompt phrase="stagnate" filename="stagnate.wav"/>
|
||||
<prompt phrase="stairway" filename="stairway.wav"/>
|
||||
<prompt phrase="standard" filename="standard.wav"/>
|
||||
<prompt phrase="stapler" filename="stapler.wav"/>
|
||||
<prompt phrase="steamship" filename="steamship.wav"/>
|
||||
<prompt phrase="sterling" filename="sterling.wav"/>
|
||||
<prompt phrase="stethoscope" filename="stethoscope.wav"/>
|
||||
<prompt phrase="stockman" filename="stockman.wav"/>
|
||||
<prompt phrase="stopwatch" filename="stopwatch.wav"/>
|
||||
<prompt phrase="stormy" filename="stormy.wav"/>
|
||||
<prompt phrase="stupendous" filename="stupendous.wav"/>
|
||||
<prompt phrase="sugar" filename="sugar.wav"/>
|
||||
<prompt phrase="supportive" filename="supportive.wav"/>
|
||||
<prompt phrase="surmount" filename="surmount.wav"/>
|
||||
<prompt phrase="surrender" filename="surrender.wav"/>
|
||||
<prompt phrase="suspense" filename="suspense.wav"/>
|
||||
<prompt phrase="suspicious" filename="suspicious.wav"/>
|
||||
<prompt phrase="sweatband" filename="sweatband.wav"/>
|
||||
<prompt phrase="swelter" filename="swelter.wav"/>
|
||||
<prompt phrase="sympathy" filename="sympathy.wav"/>
|
||||
<prompt phrase="tactics" filename="tactics.wav"/>
|
||||
<prompt phrase="talon" filename="talon.wav"/>
|
||||
<prompt phrase="tambourine" filename="tambourine.wav"/>
|
||||
<prompt phrase="tapeworm" filename="tapeworm.wav"/>
|
||||
<prompt phrase="telephone" filename="telephone.wav"/>
|
||||
<prompt phrase="tempest" filename="tempest.wav"/>
|
||||
<prompt phrase="therapist" filename="therapist.wav"/>
|
||||
<prompt phrase="tiger" filename="tiger.wav"/>
|
||||
<prompt phrase="tissue" filename="tissue.wav"/>
|
||||
<prompt phrase="tobacco" filename="tobacco.wav"/>
|
||||
<prompt phrase="tolerance" filename="tolerance.wav"/>
|
||||
<prompt phrase="tomorrow" filename="tomorrow.wav"/>
|
||||
<prompt phrase="tonic" filename="tonic.wav"/>
|
||||
<prompt phrase="topmost" filename="topmost.wav"/>
|
||||
<prompt phrase="torpedo" filename="torpedo.wav"/>
|
||||
<prompt phrase="tracker" filename="tracker.wav"/>
|
||||
<prompt phrase="tradition" filename="tradition.wav"/>
|
||||
<prompt phrase="transit" filename="transit.wav"/>
|
||||
<prompt phrase="trauma" filename="trauma.wav"/>
|
||||
<prompt phrase="travesty" filename="travesty.wav"/>
|
||||
<prompt phrase="treadmill" filename="treadmill.wav"/>
|
||||
<prompt phrase="trombonist" filename="trombonist.wav"/>
|
||||
<prompt phrase="trouble" filename="trouble.wav"/>
|
||||
<prompt phrase="truncated" filename="truncated.wav"/>
|
||||
<prompt phrase="tumor" filename="tumor.wav"/>
|
||||
<prompt phrase="tunnel" filename="tunnel.wav"/>
|
||||
<prompt phrase="tycoon" filename="tycoon.wav"/>
|
||||
<prompt phrase="typewriter" filename="typewriter.wav"/>
|
||||
<prompt phrase="ultimate" filename="ultimate.wav"/>
|
||||
<prompt phrase="uncut" filename="uncut.wav"/>
|
||||
<prompt phrase="undaunted" filename="undaunted.wav"/>
|
||||
<prompt phrase="underfoot" filename="underfoot.wav"/>
|
||||
<prompt phrase="unearth" filename="unearth.wav"/>
|
||||
<prompt phrase="unicorn" filename="unicorn.wav"/>
|
||||
<prompt phrase="unify" filename="unify.wav"/>
|
||||
<prompt phrase="universe" filename="universe.wav"/>
|
||||
<prompt phrase="unravel" filename="unravel.wav"/>
|
||||
<prompt phrase="unwind" filename="unwind.wav"/>
|
||||
<prompt phrase="upcoming" filename="upcoming.wav"/>
|
||||
<prompt phrase="uproot" filename="uproot.wav"/>
|
||||
<prompt phrase="upset" filename="upset.wav"/>
|
||||
<prompt phrase="upshot" filename="upshot.wav"/>
|
||||
<prompt phrase="vacancy" filename="vacancy.wav"/>
|
||||
<prompt phrase="vagabond" filename="vagabond.wav"/>
|
||||
<prompt phrase="vapor" filename="vapor.wav"/>
|
||||
<prompt phrase="vertigo" filename="vertigo.wav"/>
|
||||
<prompt phrase="village" filename="village.wav"/>
|
||||
<prompt phrase="virus" filename="virus.wav"/>
|
||||
<prompt phrase="visitor" filename="visitor.wav"/>
|
||||
<prompt phrase="vocalist" filename="vocalist.wav"/>
|
||||
<prompt phrase="voyager" filename="voyager.wav"/>
|
||||
<prompt phrase="waffle" filename="waffle.wav"/>
|
||||
<prompt phrase="wallet" filename="wallet.wav"/>
|
||||
<prompt phrase="warranty" filename="warranty.wav"/>
|
||||
<prompt phrase="watchword" filename="watchword.wav"/>
|
||||
<prompt phrase="wayside" filename="wayside.wav"/>
|
||||
<prompt phrase="whimsical" filename="whimsical.wav"/>
|
||||
<prompt phrase="willow" filename="willow.wav"/>
|
||||
<prompt phrase="woodlark" filename="woodlark.wav"/>
|
||||
<prompt phrase="yesteryear" filename="yesteryear.wav"/>
|
||||
<!-- Event prompts -->
|
||||
<prompt phrase="Bienvenidos al servicio de inscripción ZRTP." filename="zrtp-enroll_welcome.wav"/>
|
||||
<prompt phrase="Usted debe verificar la cadena de carácteres con su destino. Si no coincide, indica la presencia de una escucha telefónica." filename="zrtp-check_sas.wav"/>
|
||||
<prompt phrase="Solo teléfonos autenticados pueden confiar en llamadas seguras con ZRTP. Su teléfono no está autenticado con este sistema, su llamada no estará securizada." filename="zrtp-enroll_not_sip_registered.wav"/>
|
||||
<prompt phrase="Su teléfono indica que confia en este sistema para realizar llamadas seguras con ZRTP, no necesita hacer nada más." filename="zrtp-enroll_already_enrolled.wav"/>
|
||||
<prompt phrase="Solo teléfonos soportando el protócolo ZRTP pueden usar esta extensión. Su teléfono no tiene ZRTP habilitado, y está llamada no será securizada." filename="zrtp-enroll_notzrtp.wav"/>
|
||||
<prompt phrase="Este sistema esta configurado para manejar llamadas cifradas con ZRTP. Decida si permite al sistema tener la posibilidad de interceptar o monitorizar su llamada. Puede colgar una vez confirmado." filename="zrtp-enroll_confirmed.wav"/>
|
||||
<prompt phrase="Compara verbalmente este código de autenticación con su destino." filename="zrtp-is_secure.wav"/>
|
||||
<prompt phrase="El código de autenticación no está verificado." filename="zrtp-is_unverified.wav"/>
|
||||
<prompt phrase="El código de autenticación está verificado." filename="zrtp-is_verified.wav"/>
|
||||
<prompt phrase="Gracias por llamar. Adiós." filename="zrtp-thankyou_goodbye.wav"/>
|
||||
<prompt phrase="Algún error ha ocurrido." filename="zrtp-somethings_wrong.wav"/>
|
||||
<prompt phrase="Error." filename="zrtp-status_error.wav"/>
|
||||
<prompt phrase="Esta llamada no está protegida." filename="zrtp-status_notsecure.wav"/>
|
||||
<prompt phrase="Esta llamada está protegida." filename="zrtp-status_secure.wav"/>
|
||||
<prompt phrase="Securizando su llamada." filename="zrtp-status_securing.wav"/>
|
||||
</zrtp>
|
||||
</es_MX>
|
||||
</language>
|
|
@ -0,0 +1,987 @@
|
|||
<language>
|
||||
<pt_BR>
|
||||
<ascii>
|
||||
<prompt phrase="Espaço" filename="32.wav"/>
|
||||
<prompt phrase="Sustenido" filename="35.wav"/>
|
||||
<prompt phrase="Asterisco" filename="42.wav"/>
|
||||
<prompt phrase="Ponto" filename="46.wav"/>
|
||||
<prompt phrase="A" filename="97.wav"/>
|
||||
<prompt phrase="B" filename="98.wav"/>
|
||||
<prompt phrase="C" filename="99.wav"/>
|
||||
<prompt phrase="D" filename="100.wav"/>
|
||||
<prompt phrase="E" filename="101.wav"/>
|
||||
<prompt phrase="F" filename="102.wav"/>
|
||||
<prompt phrase="G" filename="103.wav"/>
|
||||
<prompt phrase="H" filename="104.wav"/>
|
||||
<prompt phrase="I" filename="105.wav"/>
|
||||
<prompt phrase="J" filename="106.wav"/>
|
||||
<prompt phrase="K" filename="107.wav"/>
|
||||
<prompt phrase="L" filename="108.wav"/>
|
||||
<prompt phrase="M" filename="109.wav"/>
|
||||
<prompt phrase="N" filename="110.wav"/>
|
||||
<prompt phrase="O" filename="111.wav"/>
|
||||
<prompt phrase="P" filename="112.wav"/>
|
||||
<prompt phrase="Q" filename="113.wav"/>
|
||||
<prompt phrase="R" filename="114.wav"/>
|
||||
<prompt phrase="S" filename="115.wav"/>
|
||||
<prompt phrase="T" filename="116.wav"/>
|
||||
<prompt phrase="U" filename="117.wav"/>
|
||||
<prompt phrase="V" filename="118.wav"/>
|
||||
<prompt phrase="W" filename="119.wav"/>
|
||||
<prompt phrase="X" filename="120.wav"/>
|
||||
<prompt phrase="Y" filename="121.wav"/>
|
||||
<prompt phrase="Z" filename="122.wav"/>
|
||||
</ascii>
|
||||
<phonetic-ascii>
|
||||
<prompt phrase="Espaço" filename="32.wav"/>
|
||||
<prompt phrase="Ponto" filename="46.wav"/>
|
||||
<prompt phrase="Alpha" filename="97.wav"/>
|
||||
<prompt phrase="Bravo" filename="98.wav"/>
|
||||
<prompt phrase="Charlie" filename="99.wav"/>
|
||||
<prompt phrase="Delta" filename="100.wav"/>
|
||||
<prompt phrase="Echo" filename="101.wav"/>
|
||||
<prompt phrase="Foxtrot" filename="102.wav"/>
|
||||
<prompt phrase="Golf" filename="103.wav"/>
|
||||
<prompt phrase="Hotel" filename="104.wav"/>
|
||||
<prompt phrase="India" filename="105.wav"/>
|
||||
<prompt phrase="Juliet" filename="106.wav"/>
|
||||
<prompt phrase="Kilo" filename="107.wav"/>
|
||||
<prompt phrase="Lima" filename="108.wav"/>
|
||||
<prompt phrase="Mike" filename="109.wav"/>
|
||||
<prompt phrase="November" filename="110.wav"/>
|
||||
<prompt phrase="Oscar" filename="111.wav"/>
|
||||
<prompt phrase="Papa" filename="112.wav"/>
|
||||
<prompt phrase="Quebec" filename="113.wav"/>
|
||||
<prompt phrase="Romeo" filename="114.wav"/>
|
||||
<prompt phrase="Sierra" filename="115.wav"/>
|
||||
<prompt phrase="Tango" filename="116.wav"/>
|
||||
<prompt phrase="Unifor" filename="117.wav"/>
|
||||
<prompt phrase="Victor" filename="118.wav"/>
|
||||
<prompt phrase="Whiskey" filename="119.wav"/>
|
||||
<prompt phrase="Xray" filename="120.wav"/>
|
||||
<prompt phrase="Yankee" filename="121.wav"/>
|
||||
<prompt phrase="Zulu" filename="122.wav"/>
|
||||
</phonetic-ascii>
|
||||
<digits>
|
||||
<prompt phrase="Zero" filename="0.wav"/>
|
||||
<prompt phrase="Um" filename="1.wav"/>
|
||||
<prompt phrase="Dois" filename="2.wav"/>
|
||||
<prompt phrase="Tręs" filename="3.wav"/>
|
||||
<prompt phrase="Quatro" filename="4.wav"/>
|
||||
<prompt phrase="Cinco" filename="5.wav"/>
|
||||
<prompt phrase="Seis" filename="6.wav"/>
|
||||
<prompt phrase="Sete" filename="7.wav"/>
|
||||
<prompt phrase="Oito" filename="8.wav"/>
|
||||
<prompt phrase="Nove" filename="9.wav"/>
|
||||
<prompt phrase="Dez" filename="10.wav"/>
|
||||
<prompt phrase="Onze" filename="11.wav"/>
|
||||
<prompt phrase="Doze" filename="12.wav"/>
|
||||
<prompt phrase="Treze" filename="13.wav"/>
|
||||
<prompt phrase="Catorze" filename="14.wav"/>
|
||||
<prompt phrase="Quinze" filename="15.wav"/>
|
||||
<prompt phrase="Dezesseis" filename="16.wav"/>
|
||||
<prompt phrase="Dezessete" filename="17.wav"/>
|
||||
<prompt phrase="Dezoito" filename="18.wav"/>
|
||||
<prompt phrase="Dezenove" filename="19.wav"/>
|
||||
<prompt phrase="Vinte" filename="20.wav"/>
|
||||
<prompt phrase="Trinta" filename="30.wav"/>
|
||||
<prompt phrase="Quarenta" filename="40.wav"/>
|
||||
<prompt phrase="Cinquenta" filename="50.wav"/>
|
||||
<prompt phrase="Sessenta" filename="60.wav"/>
|
||||
<prompt phrase="Setenta" filename="70.wav"/>
|
||||
<prompt phrase="Oitenta" filename="80.wav"/>
|
||||
<prompt phrase="Noventa" filename="90.wav"/>
|
||||
<prompt phrase="Cem" filename="100.wav"/>
|
||||
<prompt phrase="Duzentos" filename="200.wav"/>
|
||||
<prompt phrase="Trezentos" filename="300.wav"/>
|
||||
<prompt phrase="Quinhentos" filename="500.wav"/>
|
||||
<prompt phrase="Ponto" filename="dot.wav"/>
|
||||
<prompt phrase="Primeiro" filename="h-1.wav"/>
|
||||
<prompt phrase="Segundo" filename="h-2.wav"/>
|
||||
<prompt phrase="Terceiro" filename="h-3.wav"/>
|
||||
<prompt phrase="Quarto" filename="h-4.wav"/>
|
||||
<prompt phrase="Quinto" filename="h-5.wav"/>
|
||||
<prompt phrase="Sexto" filename="h-6.wav"/>
|
||||
<prompt phrase="Sétimo" filename="h-7.wav"/>
|
||||
<prompt phrase="Oitavo" filename="h-8.wav"/>
|
||||
<prompt phrase="Nono" filename="h-9.wav"/>
|
||||
<prompt phrase="Décimo" filename="h-10.wav"/>
|
||||
<prompt phrase="Vigésimo" filename="h-20.wav"/>
|
||||
<prompt phrase="Trigésimo" filename="h-30.wav"/>
|
||||
<prompt phrase="Quadragésimo" filename="h-40.wav"/>
|
||||
<prompt phrase="Quinquagésimo" filename="h-50.wav"/>
|
||||
<prompt phrase="Sexagésimo" filename="h-60.wav"/>
|
||||
<prompt phrase="Septuagésimo" filename="h-70.wav"/>
|
||||
<prompt phrase="Octogésimo" filename="h-80.wav"/>
|
||||
<prompt phrase="Nonagésimo" filename="h-90.wav"/>
|
||||
<prompt phrase="Cento" filename="hundred.wav"/>
|
||||
<prompt phrase="Centos" filename="hundreds.wav"/>
|
||||
<prompt phrase="Mil" filename="thousand.wav"/>
|
||||
<prompt phrase="Milhăo" filename="million.wav"/>
|
||||
<prompt phrase="Milhőes" filename="millions.wav"/>
|
||||
<prompt phrase="Período" filename="period.wav"/>
|
||||
<prompt phrase="Ponto" filename="point.wav"/>
|
||||
<prompt phrase="Sustenido" filename="pound.wav"/>
|
||||
<prompt phrase="Asterisco" filename="star.wav"/>
|
||||
</digits>
|
||||
<currency>
|
||||
<prompt phrase="E" filename="and.wav"/>
|
||||
<prompt phrase="Centavo" filename="cent.wav"/>
|
||||
<prompt phrase="Central" filename="central.wav"/>
|
||||
<prompt phrase="Centavos por minuto" filename="cents-per-minute.wav"/>
|
||||
<prompt phrase="Centavos" filename="cents.wav"/>
|
||||
<prompt phrase="Dólar" filename="dollar.wav"/>
|
||||
<prompt phrase="Dólares" filename="dollars.wav"/>
|
||||
<prompt phrase="Menos" filename="minus.wav"/>
|
||||
<prompt phrase="Negativo" filename="negative.wav"/>
|
||||
</currency>
|
||||
<time>
|
||||
<prompt phrase="A.M." filename="a-m.wav"/>
|
||||
<prompt phrase="a" filename="at.wav"/>
|
||||
<prompt phrase="ŕs" filename="ats.wav"/>
|
||||
<prompt phrase="Domingo" filename="day-0.wav"/>
|
||||
<prompt phrase="Segunda-feira" filename="day-1.wav"/>
|
||||
<prompt phrase="Terça-feira" filename="day-2.wav"/>
|
||||
<prompt phrase="Quarta-feira" filename="day-3.wav"/>
|
||||
<prompt phrase="Quinta-feira" filename="day-4.wav"/>
|
||||
<prompt phrase="Sexta-feira" filename="day-5.wav"/>
|
||||
<prompt phrase="Sábado" filename="day-6.wav"/>
|
||||
<prompt phrase="Hora" filename="hour.wav"/>
|
||||
<prompt phrase="Horas" filename="hours.wav"/>
|
||||
<prompt phrase="Minuto" filename="minute.wav"/>
|
||||
<prompt phrase="Minutos" filename="minutes.wav"/>
|
||||
<prompt phrase="Janeiro" filename="mon-0.wav"/>
|
||||
<prompt phrase="Fevereiro" filename="mon-1.wav"/>
|
||||
<prompt phrase="Março" filename="mon-2.wav"/>
|
||||
<prompt phrase="Abril" filename="mon-3.wav"/>
|
||||
<prompt phrase="Maio" filename="mon-4.wav"/>
|
||||
<prompt phrase="Junho" filename="mon-5.wav"/>
|
||||
<prompt phrase="Julho" filename="mon-6.wav"/>
|
||||
<prompt phrase="Agosto" filename="mon-7.wav"/>
|
||||
<prompt phrase="Setembro" filename="mon-8.wav"/>
|
||||
<prompt phrase="Outubro" filename="mon-9.wav"/>
|
||||
<prompt phrase="Novembro" filename="mon-10.wav"/>
|
||||
<prompt phrase="Dezembro" filename="mon-11.wav"/>
|
||||
<prompt phrase="Em ponto" filename="oclock.wav"/>
|
||||
<prompt phrase="P.M." filename="p-m.wav"/>
|
||||
<prompt phrase="Segundo" filename="second.wav"/>
|
||||
<prompt phrase="Segundos" filename="seconds.wav"/>
|
||||
<prompt phrase="Hoje" filename="today.wav"/>
|
||||
<prompt phrase="Amanhă" filename="tomorrow.wav"/>
|
||||
<prompt phrase="Ontem" filename="yesterday.wav"/>
|
||||
</time>
|
||||
<voicemail>
|
||||
<prompt phrase="A pessoa na extensăo..." filename="vm-person.wav"/>
|
||||
<prompt phrase="marcada como urgente" filename="vm-marked-urgent.wav"/>
|
||||
<prompt phrase="email enviado" filename="vm-emailed.wav"/>
|
||||
<prompt phrase="Vocę tem..." filename="vm-you_have.wav"/>
|
||||
<prompt phrase="Por favor digite o seu número de usuario, e depois..." filename="vm-enter_id.wav"/>
|
||||
<prompt phrase="Por favor digite a sua contrasenha, e depois..." filename="vm-enter_pass.wav"/>
|
||||
<prompt phrase="Inicio incorreto da sessao." filename="vm-fail_auth.wav"/>
|
||||
<prompt phrase="Bem-vindo ao seu correio de voz." filename="vm-hello.wav"/>
|
||||
<prompt phrase="Até logo." filename="vm-goodbye.wav"/>
|
||||
<prompt phrase="Grave a sua mensagem depois de ouvir o sinal, diga o seu nome e pressione qualquer tecla ou pare de falar para finalizar a gravaçăo." filename="vm-record_name1.wav"/>
|
||||
<prompt phrase="Escolha uma saudaçao entre as opçőes 1 e 9" filename="vm-choose_greeting_choose.wav"/>
|
||||
<prompt phrase="Número invalido." filename="vm-choose_greeting_fail.wav"/>
|
||||
<prompt phrase="Muitas tentativas fracassadas." filename="vm-abort.wav"/>
|
||||
<prompt phrase="Para mudar a sua senha..." filename="vm-change_password.wav"/>
|
||||
<prompt phrase="Apos o sinal grave a sua saudaçăo, digite qualquer tecla ou deixe de falar para finalizar a gravaçăo." filename="vm-record_greeting.wav"/>
|
||||
<prompt phrase="Apos o sinal grave a sua mensagem, digite qualquer tecla ou deixe de falar para finalizar a gravaçăo." filename="vm-record_message.wav"/>
|
||||
<prompt phrase="Năo está disponível." filename="vm-play_greeting.wav"/>
|
||||
<prompt phrase="nova e urgente" filename="vm-urgent-new.wav"/>
|
||||
<prompt phrase="nova" filename="vm-new.wav"/>
|
||||
<prompt phrase="guardada e urgente" filename="vm-urgent-saved.wav"/>
|
||||
<prompt phrase="guardada" filename="vm-saved.wav"/>
|
||||
<prompt phrase="mensagem" filename="vm-message.wav"/>
|
||||
<prompt phrase="mensagens" filename="vm-messages.wav"/>
|
||||
<prompt phrase="marque" filename="vm-press.wav"/>
|
||||
<prompt phrase="Para ouvir as mensagens novas..." filename="vm-listen_new.wav"/>
|
||||
<prompt phrase="Para ouvir as mensagens armazenadas..." filename="vm-listen_saved.wav"/>
|
||||
<prompt phrase="Para opçőes avançadas..." filename="vm-advanced.wav"/>
|
||||
<prompt phrase="Para sair..." filename="vm-to_exit.wav"/>
|
||||
<prompt phrase="Para gravar a sua saudaçăo..." filename="vm-record_greeting.wav"/>
|
||||
<prompt phrase="Para escolher a sua saudaçăo..." filename="vm-choose_greeting.wav"/>
|
||||
<prompt phrase="Para gravar o seu nome..." filename="vm-record_name2.wav"/>
|
||||
<prompt phrase="Para o menu principal..." filename="vm-main_menu.wav"/>
|
||||
<prompt phrase="Para ouvir a gravaçao..." filename="vm-listen_to_recording.wav"/>
|
||||
<prompt phrase="Para guardar a gravaçao..." filename="vm-save_recording.wav"/>
|
||||
<prompt phrase="Para gravar novamente..." filename="vm-rerecord.wav"/>
|
||||
<prompt phrase="Para marcar esta mensagem como urgente..." filename="vm-mark_urgent.wav"/>
|
||||
<prompt phrase="Para continuar..." filename="vm-continue.wav"/>
|
||||
<prompt phrase="Para ouvir a gravaçăo novamente..." filename="vm-listen_to_recording_again.wav"/>
|
||||
<prompt phrase="Para borrar a gravaçăo..." filename="vm-delete_recording.wav"/>
|
||||
<prompt phrase="Para enviar a gravaçăo para o seu email..." filename="vm-forward_to_email.wav"/>
|
||||
<prompt phrase="saudaçăo" filename="vm-greeting.wav"/>
|
||||
<prompt phrase="selecionada" filename="vm-selected.wav"/>
|
||||
<prompt phrase="Năo está disponível." filename="vm-not_available.wav"/>
|
||||
<prompt phrase="Mensagem número..." filename="vm-message_number.wav"/>
|
||||
<prompt phrase="apagada" filename="vm-deleted.wav"/>
|
||||
<prompt phrase="A sua gravaçăo é muito curta, por favor tente novamente." filename="vm-too-small.wav"/>
|
||||
<prompt phrase="na caixa de mensagens" filename="vm-in_folder.wav"/>
|
||||
<prompt phrase="Para devolver a ligaçăo agora..." filename="vm-return_call.wav"/>
|
||||
<prompt phrase="urgente" filename="vm-urgent.wav"/>
|
||||
<prompt phrase="Esta caixa de mensagens está lotada, por favor tente mais tarde." filename="vm-mailbox_full.wav"/>
|
||||
<prompt phrase="Bem-vindo a sua caixa de mensagens. Para escutar o menu e configurar a sua caixa de mensagens, digite um. Para năo considera-lo, digite dois." filename="vm-tutorial_yes_no.wav"/>
|
||||
<prompt phrase="Vocę precisa gravar o seu nome e sobrenome. Esta gravaçăo é usada entre outras, no serviço de diretório." filename="vm-tutorial_record_name.wav"/>
|
||||
<prompt phrase="O número de identificaçăo pessoal ou PIN serve para impedir o acesso de terceiros as suas mensagens. Vocę deseja mudar o seu PIN agora?" filename="vm-tutorial_change_pin.wav"/>
|
||||
</voicemail>
|
||||
<directory>
|
||||
<prompt phrase="Por favor marque as primeiras letras do nome da pessoa." filename="dir-enter-person.wav"/>
|
||||
<prompt phrase="...último nome..." filename="dir-last_name.wav"/>
|
||||
<prompt phrase="Para procurar por..." filename="dir-to_search_by.wav"/>
|
||||
<prompt phrase="...primeiro nome..." filename="dir-first_name.wav"/>
|
||||
<prompt phrase="Năo foram encontradas as respostas, tente novamente." filename="dir-no_match_entry.wav"/>
|
||||
<prompt phrase="...respostas encontradas para a sua pergunta." filename="dir-result_match.wav"/>
|
||||
<prompt phrase="A sua pergunta devolveu muitas respostas, por favor tente novamente." filename="dir-to_many_result.wav"/>
|
||||
<prompt phrase="Năo há mais opçőes." filename="dir-no_more_results.wav"/>
|
||||
<prompt phrase="Opçăo número..." filename="dir-result_number.wav"/>
|
||||
<prompt phrase="...no ramal..." filename="dir-at_extension.wav"/>
|
||||
<prompt phrase="Para escolher essa opçăo..." filename="dir-to_select_entry.wav"/>
|
||||
<prompt phrase="Para a opçăo seguinte..." filename="dir-for_next.wav"/>
|
||||
<prompt phrase="Para a opçăo anterior..." filename="dir-for_prev.wav"/>
|
||||
<prompt phrase="Para uma nova busca..." filename="dir-start_new_search.wav"/>
|
||||
<prompt phrase="Vocę precisa dizer um mínimo de..." filename="dir-specify_mininum_first.wav"/>
|
||||
<prompt phrase="...letras do nome da pessoa, tente novamente." filename="dir-letters_of_person_name.wav"/>
|
||||
<prompt phrase="marque" filename="dir-press.wav"/>
|
||||
</directory>
|
||||
<conference>
|
||||
<prompt phrase="NULL" filename="conf-ack.wav" type="tone"/>
|
||||
<prompt phrase="NULL" filename="conf-nack.wav" type="tone"/>
|
||||
<prompt phrase="Vocę agora está mudo." filename="conf-muted.wav"/>
|
||||
<prompt phrase="Vocę năo está mais mudo." filename="conf-unmuted.wav"/>
|
||||
<prompt phrase="Neste momento vocę é a única pessoa na conferęncia." filename="conf-alone.wav"/>
|
||||
<prompt phrase="NULL" filename="conf-perpetual.wav" type="music"/>
|
||||
<prompt phrase="NULL" filename="conf-enter.wav" type="tone"/>
|
||||
<prompt phrase="NULL" filename="conf-exit.wav" type="tone"/>
|
||||
<prompt phrase="Vocę foi retirado da conferęncia." filename="conf-kicked.wav"/>
|
||||
<prompt phrase="Esta confęrencia está bloqueada." filename="conf-locked.wav"/>
|
||||
<prompt phrase="A conferęncia está bloqueada." filename="conf-is-locked.wav"/>
|
||||
<prompt phrase="A conferęncia está liberada." filename="conf-is-unlocked.wav"/>
|
||||
<prompt phrase="Por favor insira o PIN da conferęncia." filename="conf-pin.wav"/>
|
||||
<prompt phrase="Este PIN năo e válido, tente novamente." filename="conf-bad-pin.wav"/>
|
||||
<prompt phrase="Até logo." filename="conf-goodbye.wav"/>
|
||||
<prompt phrase="Bem-vindo a conferęncia." filename="conf-welcome.wav"/>
|
||||
</conference>
|
||||
<ivr>
|
||||
<prompt phrase="Número da conta" filename="ivr-account_number.wav"/>
|
||||
<prompt phrase="Contatar com a pessoa que telefona" filename="ivr-connect_to_caller.wav"/>
|
||||
<prompt phrase="Se conhece o ramal da pessoa com quem deseja falar, por favor digite agora." filename="ivr-enter_ext_pound.wav"/>
|
||||
<prompt phrase="Por favor digite o ramal e a continuaçăo a tecla sustenido." filename="ivr-enter_ext.wav"/>
|
||||
<prompt phrase="Para a pessoa..." filename="ivr-for_this_person.wav"/>
|
||||
<prompt phrase="Por favor aguarde enquanto realizamos a sua chamada." filename="ivr-hold_connect_call.wav"/>
|
||||
<prompt phrase="Desculpe" filename="ivr-im_sorry.wav"/>
|
||||
<prompt phrase="Por favor" filename="ivr-please.wav"/>
|
||||
<prompt phrase="Por favor devolva a nossa ligaçăo ŕ..." filename="ivr-please_return_our_call_at.wav"/>
|
||||
<prompt phrase="De acordo com o número de referęncia." filename="ivr-regarding_reference_number.wav"/>
|
||||
<prompt phrase="Este é um exemplo de um submenu IVR..." filename="ivr-sample_submenu.wav"/>
|
||||
<prompt phrase="Por favor diga o seu nome depois do sinal." filename="ivr-say_name.wav"/>
|
||||
<prompt phrase="Enviar esta ligaçăo para a caixa de mensagens de voz." filename="ivr-send_to_voicemail.wav"/>
|
||||
<prompt phrase="Para falar com o responsavel do atençao a clientes..." filename="ivr-speak_to_a_customer_service_representative.wav"/>
|
||||
<prompt phrase="Deixe uma mensagem" filename="ivr-take_a_message.wav"/>
|
||||
<prompt phrase="Obrigado" filename="ivr-thank_you.wav"/>
|
||||
<prompt phrase="Essa opçăo nao é valida." filename="ivr-that_was_an_invalid_entry.wav"/>
|
||||
<prompt phrase="Esta é uma ligaçăo de..." filename="ivr-this_is_a_call_from.wav"/>
|
||||
<prompt phrase="Este IVR lher permite testar algumas das opçőes..." filename="ivr-this_ivr_will_let_you_test_features.wav"/>
|
||||
<prompt phrase="Para ligar ŕ conferencia FreeSWITCH..." filename="ivr-to_call_the_freeswitch_conference.wav"/>
|
||||
<prompt phrase="Para realizar um teste FreeSWITCH eco..." filename="ivr-to_do_a_freeswitch_echo_test.wav"/>
|
||||
<prompt phrase="Para realizar um teste FWD eco..." filename="ivr-to_do_a_fwd_echo_test.wav"/>
|
||||
<prompt phrase="Para ouvir o exemplo de um submenu IVR..." filename="ivr-to_hear_sample_submenu.wav"/>
|
||||
<prompt phrase="Para ouvir gritos de macacos..." filename="ivr-to_hear_screaming_monkeys.wav"/>
|
||||
<prompt phrase="Para ouvir música de espera..." filename="ivr-to_listen_to_moh.wav"/>
|
||||
<prompt phrase="Para ouvir novamente estas opçőes..." filename="ivr-to_repeat_these_options.wav"/>
|
||||
<prompt phrase="Para voltar ao menu anterior..." filename="ivr-to_return_to_previous_menu.wav"/>
|
||||
<prompt phrase="Para falar com um atendente..." filename="ivr-to_speak_with_an_operator.wav"/>
|
||||
<prompt phrase="Bem-vindo a FreeSWITCH, o futuro da telefonia." filename="ivr-welcome_to_freeswitch.wav"/>
|
||||
<prompt phrase="Vocę pode sair a qualquer momento, simplesmente terminando a ligaçăo." filename="ivr-you_may_exit_by_hanging_up.wav"/>
|
||||
<prompt phrase="ou" filename="ivr-or.wav"/>
|
||||
<prompt phrase="năo" filename="ivr-not.wav"/>
|
||||
<prompt phrase="ligaçăo" filename="ivr-call.wav"/>
|
||||
<prompt phrase="Vocę pode" filename="ivr-you_may.wav"/>
|
||||
<prompt phrase="Oi?" filename="ivr-hello.wav"/>
|
||||
<prompt phrase="Usando as teclas do seu telefone..." filename="ivr-use_telephone_keypad.wav"/>
|
||||
<prompt phrase="Por favor soletre o nome da pessoa que vocę deseja contatar." filename="ivr-spell_name.wav"/>
|
||||
<prompt phrase="Sobrenome primeiro" filename="ivr-last_name_first.wav"/>
|
||||
<prompt phrase="Primeiro nome primeiro" filename="ivr-first_name_first.wav"/>
|
||||
<prompt phrase="Marque 1 para Q ou Z." filename="ivr-press_one_q_or_z.wav"/>
|
||||
<prompt phrase="Vendas" filename="ivr-sales.wav"/>
|
||||
<prompt phrase="Atençăo a clientes" filename="ivr-customer_service.wav"/>
|
||||
<prompt phrase="Suporte tecnico" filename="ivr-technical_support.wav"/>
|
||||
<prompt phrase="Atendente" filename="ivr-operator.wav"/>
|
||||
<prompt phrase="Vocę teclou um ramal inválido." filename="ivr-you_have_dialed_an_invalid_extension.wav"/>
|
||||
<prompt phrase="Por favor digite o seu ramal, depois a tecla sustenido." filename="ivr-please_enter_extension_followed_by_pound.wav"/>
|
||||
<prompt phrase="Por favor digite o seu número PIN, depois a tecla sustenido." filename="ivr-please_enter_pin_followed_by_pound.wav"/>
|
||||
<prompt phrase="O seu número PIN ou ramal năo é válido." filename="ivr-pin_or_extension_is-invalid.wav"/>
|
||||
<prompt phrase="Vocę está a ponto de associar este telefone ŕ sua conta..." filename="ivr-you_are_about_to_provision_this_phone.wav"/>
|
||||
<prompt phrase="Por favor digite novamente o seu número PIN para confirmar." filename="ivr-please_reenter_your_pin.wav"/>
|
||||
<prompt phrase="Para registar em ClueCon, por favor digite..." filename="ivr-register_for_cluecon.wav"/>
|
||||
<prompt phrase="Para contatar..." filename="ivr-to_log_in.wav"/>
|
||||
<prompt phrase="Para desligar..." filename="ivr-to_log_out.wav"/>
|
||||
<prompt phrase="Vocę agora está conetado." filename="ivr-you_are_now_logged_in.wav"/>
|
||||
<prompt phrase="Vocę agora está desconetado." filename="ivr-you_are_now_logged_out.wav"/>
|
||||
<prompt phrase="Por favor tente novamente." filename="ivr-please_try_again.wav"/>
|
||||
<prompt phrase="Vocę está a ponto de associar permanentemente este telefone ao seu ramal." filename="ivr-provision_phone_permanently_to_extension.wav"/>
|
||||
<prompt phrase="Por favor digite o numero do ramal que vocę pretende associar a este telefone, logo digite sustenido." filename="ivr-extension_to_provision_this_phone.wav"/>
|
||||
<prompt phrase="Obrigado, este telefone vai ser reiniciado." filename="ivr-this_phone_will_now_reboot.wav"/>
|
||||
<prompt phrase="Obrigado. A sua gravaçăo foi guardada." filename="ivr-recording_saved.wav"/>
|
||||
<prompt phrase="Digite 1 para guardar a sua gravaçăo. Digite 2 para ouvir á sua gravaçăo. Digite 3 para gravar novamente." filename="ivr-save_review_record.wav"/>
|
||||
<prompt phrase="Neste momento o sistema é incapaz de guardar a sua gravaçăo. Por favor tente novamente mais tarde." filename="ivr-unable_save.wav"/>
|
||||
<prompt phrase="Vocę é o número" filename="ivr-you_are_number.wav"/>
|
||||
<prompt phrase="...em linha" filename="ivr-in_line.wav"/>
|
||||
<prompt phrase="Obrigado por esperar." filename="ivr-thank_you_for_holding.wav"/>
|
||||
<prompt phrase="O seu tempo estimado de espera é..." filename="ivr-estimated_hold_time.wav"/>
|
||||
<prompt phrase="Mais de..." filename="ivr-more_than.wav"/>
|
||||
<prompt phrase="Menos de..." filename="ivr-less_than.wav"/>
|
||||
<prompt phrase="Iniciar a gravaçăo." filename="ivr-begin_recording.wav "/>
|
||||
<prompt phrase="O encaminhamento da ligaçăo foi cancelada." filename="ivr-call_forwarding_has_been_cancelled.wav"/>
|
||||
<prompt phrase="O encaminhamento da ligaçăo foi ativada." filename="ivr-call_forwarding_has_been_set.wav"/>
|
||||
<prompt phrase="Por favor, introduza o número de telefone." filename="ivr-please_enter_the_phone_number.wav"/>
|
||||
<prompt phrase="Por favor, diga o seu nome e o motivo da sua ligaçăo." filename="ivr-please_state_your_name_and_reason_for_calling.wav"/>
|
||||
<prompt phrase="Para aceitar, digite 1. Para rejeitar, digite 2. Para enviar para o correio de voz, digite 3." filename="ivr-accept_reject_voicemail.wav"/>
|
||||
<prompt phrase="Entrada da ligaçăo." filename="ivr-incoming_call.wav"/>
|
||||
<prompt phrase="Obrigado pela sua ligaçăo." filename="ivr-thank_you_for_calling.wav"/>
|
||||
<prompt phrase="Por favor permaneça em linha. A sua ligaçăo será atendida brevemente." filename="ivr-stay_on_line_call_answered_momentarily.wav"/>
|
||||
<prompt phrase="A sua ligaçăo está sendo transferida." filename="ivr-call_being_transferred.wav"/>
|
||||
<prompt phrase="Por favor, desfrute da música enquanto a sua ligaçăo é transferida." filename="ivr-enjoy_music_while_transfer.wav"/>
|
||||
<prompt phrase="Vocę tem uma ligaçăo de..." filename="ivr-call_from.wav"/>
|
||||
<prompt phrase="Este menú năo tem opçőes. Por favor entre em contato com o administrador." filename="ivr-no_menu_items.wav"/>
|
||||
<prompt phrase="Para diretório, digite..." filename="ivr-for_directory_press.wav"/>
|
||||
<prompt phrase="Usando o teclado do seu telefone..." filename="ivr-using_telephone_keypad.wav"/>
|
||||
<prompt phrase="Introduza as primeiras letras do último nome da pessoa." filename="ivr-enter_letters_last_name.wav"/>
|
||||
<prompt phrase="Introduza as primeiras letras do primeiro nome da pessoa." filename="ivr-enter_letters_first_name.wav"/>
|
||||
<prompt phrase="Introduza as primeiras letras do primeiro ou último nome da pessoa." filename="ivr-enter_letters_first_or_last_name.wav"/>
|
||||
<prompt phrase="Se isso é correcto, digite..." filename="ivr-if_correct_press.wav"/>
|
||||
<prompt phrase="Se năo, digite..." filename="ivr-if_not_press.wav"/>
|
||||
<prompt phrase="Quando terminar, digite sustenido." filename="ivr-finished_pound_hash_key.wav"/>
|
||||
<prompt phrase="O modo Năo Incomodar agora está ativado." filename="ivr-dnd_activated.wav"/>
|
||||
<prompt phrase="O modo Năo Incomodar foi desativado." filename="ivr-dnd_cancelled.wav"/>
|
||||
<prompt phrase="Marque qualquer outro dígito..." filename="ivr-any_other_digit.wav"/>
|
||||
<prompt phrase="Digite um para sim. Digite dois para năo." filename="ivr-one_yes_two_no.wav"/>
|
||||
<prompt phrase="Por favor digite o número da fila, e logo a tecla sustenido." filename="ivr-enter_queue_number.wav"/>
|
||||
<prompt phrase="Por favor digite o..." filename="ivr-please_enter_the.wav"/>
|
||||
<prompt phrase="Número." filename="ivr-number.wav"/>
|
||||
<prompt phrase="...e depois sustenido." filename="ivr-followed_by_pound.wav"/>
|
||||
<prompt phrase="O saldo da conta é..." filename="ivr-account_balance_is.wav"/>
|
||||
<prompt phrase="Obrigado por telefonar. Se conhece a ramal do destinatário, por favor digite-o agora. Para ir para o diretório, digite..." filename="ivr-generic_greeting.wav"/>
|
||||
<prompt phrase="...ficheiro..." filename="ivr-file.wav"/>
|
||||
<prompt phrase="...ficheiros..." filename="ivr-files-.wav"/>
|
||||
<prompt phrase="Para uma ligaçăo de despertar..." filename="ivr-for_a_wakeup_call.wav"/>
|
||||
<prompt phrase="Esta é a sua ligaçăo de despertar." filename="ivr-this_is_your_wakeup_call.wav"/>
|
||||
<prompt phrase="Para solicitar uma ligaçăo de despertar..." filename="ivr-request_wakeup_call.wav"/>
|
||||
<prompt phrase="Para confirmar uma ligaçăo de despertar..." filename="ivr-confirm_wakeup_call.wav"/>
|
||||
<prompt phrase="Para cancelar uma ligaçăo de despertar..." filename="ivr-cancel_wakeup_call.wav"/>
|
||||
<prompt phrase="Vocę solicitou uma ligaçăo de despertar..." filename="ivr-requested_wakeup_call_for.wav"/>
|
||||
<prompt phrase="Vocę năo solicitou uma ligaçăo de despertar." filename="ivr-not_requested_wakeup_call.wav"/>
|
||||
<prompt phrase="A sua ligaçăo de despertar foi cancelada." filename="ivr-wakeup_call_cancelled.wav"/>
|
||||
<prompt phrase="Para uma ligaçăo de despertar por dia..." filename="ivr-for_daily_wakeup_call.wav"/>
|
||||
<prompt phrase="ligaçăo de despertar diária..." filename="ivr-daily_wakeup_call.wav"/>
|
||||
<prompt phrase="Para ligaçőes de despertar diárias..." filename="ivr-for_daily_wakeup_calls.wav"/>
|
||||
<prompt phrase="Para apenas uma ligaçăo de despertar..." filename="ivr-for_one_time_wakeup_call.wav"/>
|
||||
<prompt phrase="Apenas uma ligaçăo de despertar..." filename="ivr-one_time_wakeup_call.wav"/>
|
||||
<prompt phrase="...ligaçăo de despertar..." filename="ivr-wakeup_call.wav"/>
|
||||
<prompt phrase="Acorda! Acorda raio de sol!!" filename="ivr-wakey_wakey_sunshine.wav"/>
|
||||
<prompt phrase="Bem-vindo." filename="ivr-welcome.wav"/>
|
||||
<prompt phrase="Bem-vindo a..." filename="ivr-welcome_to.wav"/>
|
||||
<prompt phrase="Bom dia." filename="ivr-good_morning.wav"/>
|
||||
<prompt phrase="Boa tarde." filename="ivr-good_afternoon.wav"/>
|
||||
<prompt phrase="Boa noite." filename="ivr-good_evening.wav"/>
|
||||
<prompt phrase="Obrigado." filename="ivr-Thank_you.wav"/>
|
||||
<prompt phrase="Para..." filename="ivr-for.wav"/>
|
||||
<prompt phrase="Estamos a observar tempos de espera superiores ao normal." filename="ivr-longer_than_usual_hold_times.wav"/>
|
||||
<prompt phrase="Vocę é o..." filename="ivr-you_are_the.wav"/>
|
||||
<prompt phrase="Um momento por favor." filename="ivr-one_moment_please.wav"/>
|
||||
<prompt phrase="A sua ligaçăo será atendida pela ordem que foi recebida." filename="ivr-call_answered_order_received.wav"/>
|
||||
<prompt phrase="Por favor digite o número da conferęncia, seguido de sustenido." filename="conf-enter_conf_number.wav"/>
|
||||
<prompt phrase="Introduza o número PIN da conferęncia, seguido de sustenido." filename="conf-enter_conf_pin.wav"/>
|
||||
<prompt phrase="...entrou na conferęncia." filename="conf-has_joined.wav"/>
|
||||
<prompt phrase="...abandonou a conferęncia." filename="conf-has_left.wav"/>
|
||||
<prompt phrase="Vocę entrou..." filename="ivr-you_entered.wav"/>
|
||||
<prompt phrase="Número do ramal..." filename="ivr-extension_number.wav"/>
|
||||
<prompt phrase="Por favor aguarde enquanto contatamos com o destinatário." filename="ivr-please_hold_while_party_contacted.wav"/>
|
||||
<prompt phrase="Por favor desfrute da música enquanto contatamos com o destinatário." filename="ivr-please_enjoy_music_while_party_reached.wav"/>
|
||||
<prompt phrase="Obrigado por telefonar. Se conhece a ramal do destinatário, digite-o agora, ou digite nove para ir para o diretório." filename="ivr-generic_greeting.wav"/>
|
||||
<prompt phrase="Se isto é correcto, digite 1. Se năo é correcto, digite 2." filename="ivr-if_correct_one_if_not_two.wav"/>
|
||||
<prompt phrase="Para ouvir novamente esta informaçăo.." filename="ivr-repeat_this_information.wav"/>
|
||||
<prompt phrase="Năo năo năo!" filename="ivr-no_no_no.wav"/>
|
||||
<prompt phrase="Vocę pretendia marcar esta tecla?" filename="ivr-did_you_mean_to_press_key.wav"/>
|
||||
<prompt phrase="É sério? Pretendia MESMO marcar esta tecla?" filename="ivr-seriously_mean_to_press_key.wav"/>
|
||||
<prompt phrase="Oh, tanto faz." filename="ivr-oh_whatever.wav"/>
|
||||
<prompt phrase="Já chega! Um erro mais e corto a ligaçăo." filename="ivr-one_more_mistake.wav"/>
|
||||
<prompt phrase="Felicidades, vocę pressionou estrela. Isto năo significa que vocę é uma estrela. Apenas significa que pode pressionar teclas e que provavelmente tens dedos." filename="ivr-congratulations_you_pressed_star.wav"/>
|
||||
<prompt phrase="Todos os nossos engenheiros estăo ocupados demonstrando como é impressionante CudaTel." filename="ivr-engineers_busy_assisting_other_sales.wav"/>
|
||||
<prompt phrase="O destino que deseja contatar năo está disponível e năo tem correio de voz." filename="vm-not_available_no_voicemail.wav"/>
|
||||
<prompt phrase="Esta mensagem vai se auto-destruir em 5, 4, 3, 2, 1..." filename="ivr-message_self_destruct.wav"/>
|
||||
<prompt phrase="Vocę já está em silęncio." filename="conf-you_are_already_muted.wav"/>
|
||||
<prompt phrase="Vocę está agora em silęncio em ambos sentidos." filename="conf-you_are_now_bidirectionally_muted.wav"/>
|
||||
<prompt phrase="Todas as suas ligaçőes nos pertence." filename="ivr-all_your_call_are_belong_to_us.wav"/>
|
||||
<prompt phrase="Adoro a forma como vocę pressiona as teclas!" filename="ivr-love_those_touch_tones.wav"/>
|
||||
<prompt phrase="Sim, nós năo temos bananas." filename="ivr-yes_we_have_no_bananas.wav"/>
|
||||
<prompt phrase="Homem, vocę está sendo ridículo!" filename="ivr-dude_you_suck.wav"/>
|
||||
<prompt phrase="A sua ligaçăo é muito importante para nós, mas a sua saúde mental năo, por isso estamos felizes em fazę-lo esperar, torturando-o com a irritante música de espera." filename="ivr-on_hold_indefinitely.wav"/>
|
||||
<prompt phrase="...deixou o edifício." filename="ivr-has_left_the_building.wav"/>
|
||||
<prompt phrase="Este telefone năo está associado e năo pode realizar ligaçőes externas." filename="ivr-phone_is_unassigned.wav"/>
|
||||
<prompt phrase="Este telefone năo está configurado corretamente." filename="ivr-phone_not_configured.wav"/>
|
||||
<prompt phrase="Parabéns! Este telefone está configurado corretamente e agora pode ser associado a um utilizador." filename="ivr-phone_is_configured_properly.wav"/>
|
||||
<prompt phrase="Por favor contate o administrador do sistema para assistęncia." filename="ivr-contact_system_administrator.wav"/>
|
||||
<prompt phrase="Barracuda Networks" filename="ivr-barracuda_networks.wav"/>
|
||||
<prompt phrase="CudaTel Communication Server" filename="ivr-cudatel_communication_server.wav"/>
|
||||
<prompt phrase="Por favor, introduza as primeiras letras do primeiro ou último nome da pessoa" filename="dir-enter_person_first_or_last.wav"/>
|
||||
<prompt phrase="Năo há mais ligaçőes em espera nesta fila." filename="ivr-no_calls_waiting_in_queue.wav"/>
|
||||
<prompt phrase="Brian West" filename="misc-Brian_West.wav"/>
|
||||
<prompt phrase="Anthony Minessale" filename="misc-Anthony_Minessale.wav"/>
|
||||
<prompt phrase="Michael Jerris" filename="misc-Michael_Jerris.wav"/>
|
||||
<prompt phrase="Raymond Chandler" filename="misc-Raymond_Chandler.wav"/>
|
||||
<prompt phrase="Michael Collins" filename="misc-Michael_Collins.wav"/>
|
||||
<prompt phrase="Mark Mann" filename="misc-Mark_Mann.wav"/>
|
||||
<prompt phrase="William King" filename="misc-William_King.wav"/>
|
||||
<prompt phrase="Rudy Fleminger" filename="misc-Rudy_Fleminger.wav"/>
|
||||
<prompt phrase="Andrew Thompson" filename="misc-Andrew_Thompson.wav"/>
|
||||
<prompt phrase="Graham Saathoff" filename="misc-Graham_Saathoff.wav"/>
|
||||
<prompt phrase="Nicholaus Belluni" filename="misc-Nicholaus_Belluni.wav"/>
|
||||
<prompt phrase="Sean Heiney" filename="misc-Sean_Heiney.wav"/>
|
||||
</ivr>
|
||||
<misc>
|
||||
<prompt phrase="Foi ativada a segurança para esta ligaçăo." filename="call_secured.wav"/>
|
||||
<prompt phrase="...depois a tecla sustenido." filename="followed.wav"/>
|
||||
<prompt phrase="Se vocę é esta pessoa..." filename="if_you_are_this_person.wav"/>
|
||||
<prompt phrase="Se vocę deseja..." filename="if_you_would_like_to.wav"/>
|
||||
<prompt phrase="Indique o número de referęncia" filename="provide_reference_number.wav"/>
|
||||
<prompt phrase="Por favor, digite o ramal que deseja transferir." filename="transfer1.wav"/>
|
||||
<prompt phrase="Transferir" filename="transfer2.wav"/>
|
||||
<prompt phrase="Estamos tentando contatar..." filename="we_are_trying_to_reach.wav"/>
|
||||
<prompt phrase="Houve uma falha, por favor entre em contato com o administrador." filename="error.wav"/>
|
||||
<prompt phrase="A sua ligaçăo vai terminar em..." filename="misc-your_call_will_be_terminated_in.wav"/>
|
||||
<prompt phrase="A sua ligaçăo foi finalizada." filename="misc-your_call_has_been_terminated.wav"/>
|
||||
</misc>
|
||||
<zrtp>
|
||||
<!-- base256 prompts for SAS -->
|
||||
<prompt phrase="Algol" filename="Algol.wav"/>
|
||||
<prompt phrase="Apollo" filename="Apollo.wav"/>
|
||||
<prompt phrase="Athens" filename="Athens.wav"/>
|
||||
<prompt phrase="Atlantic" filename="Atlantic.wav"/>
|
||||
<prompt phrase="Aztec" filename="Aztec.wav"/>
|
||||
<prompt phrase="Babylon" filename="Babylon.wav"/>
|
||||
<prompt phrase="Belfast" filename="Belfast.wav"/>
|
||||
<prompt phrase="Bradbury" filename="Bradbury.wav"/>
|
||||
<prompt phrase="Brazilian" filename="Brazilian.wav"/>
|
||||
<prompt phrase="Burbank" filename="Burbank.wav"/>
|
||||
<prompt phrase="Burlington" filename="Burlington.wav"/>
|
||||
<prompt phrase="Camelot" filename="Camelot.wav"/>
|
||||
<prompt phrase="Capricorn" filename="Capricorn.wav"/>
|
||||
<prompt phrase="Cherokee" filename="Cherokee.wav"/>
|
||||
<prompt phrase="Chicago" filename="Chicago.wav"/>
|
||||
<prompt phrase="Christmas" filename="Christmas.wav"/>
|
||||
<prompt phrase="Dakota" filename="Dakota.wav"/>
|
||||
<prompt phrase="December" filename="December.wav"/>
|
||||
<prompt phrase="Dupont" filename="Dupont.wav"/>
|
||||
<prompt phrase="Eskimo" filename="Eskimo.wav"/>
|
||||
<prompt phrase="Galveston" filename="Galveston.wav"/>
|
||||
<prompt phrase="Geiger" filename="Geiger.wav"/>
|
||||
<prompt phrase="Hamilton" filename="Hamilton.wav"/>
|
||||
<prompt phrase="Istanbul" filename="Istanbul.wav"/>
|
||||
<prompt phrase="Jamaica" filename="Jamaica.wav"/>
|
||||
<prompt phrase="Jupiter" filename="Jupiter.wav"/>
|
||||
<prompt phrase="Medusa" filename="Medusa.wav"/>
|
||||
<prompt phrase="Mohawk" filename="Mohawk.wav"/>
|
||||
<prompt phrase="Montana" filename="Montana.wav"/>
|
||||
<prompt phrase="Neptune" filename="Neptune.wav"/>
|
||||
<prompt phrase="Norwegian" filename="Norwegian.wav"/>
|
||||
<prompt phrase="Oakland" filename="Oakland.wav"/>
|
||||
<prompt phrase="October" filename="October.wav"/>
|
||||
<prompt phrase="Ohio" filename="Ohio.wav"/>
|
||||
<prompt phrase="Orlando" filename="Orlando.wav"/>
|
||||
<prompt phrase="Pacific" filename="Pacific.wav"/>
|
||||
<prompt phrase="Pandora" filename="Pandora.wav"/>
|
||||
<prompt phrase="Pegasus" filename="Pegasus.wav"/>
|
||||
<prompt phrase="Pluto" filename="Pluto.wav"/>
|
||||
<prompt phrase="Saturday" filename="Saturday.wav"/>
|
||||
<prompt phrase="Scotland" filename="Scotland.wav"/>
|
||||
<prompt phrase="Trojan" filename="Trojan.wav"/>
|
||||
<prompt phrase="Virginia" filename="Virginia.wav"/>
|
||||
<prompt phrase="Vulcan" filename="Vulcan.wav"/>
|
||||
<prompt phrase="Waterloo" filename="Waterloo.wav"/>
|
||||
<prompt phrase="Wichita" filename="Wichita.wav"/>
|
||||
<prompt phrase="Wilmington" filename="Wilmington.wav"/>
|
||||
<prompt phrase="Wyoming" filename="Wyoming.wav"/>
|
||||
<prompt phrase="Yucatan" filename="Yucatan.wav"/>
|
||||
<prompt phrase="Zulu" filename="Zulu.wav"/>
|
||||
<prompt phrase="aardvark" filename="aardvark.wav"/>
|
||||
<prompt phrase="absurd" filename="absurd.wav"/>
|
||||
<prompt phrase="accrue" filename="accrue.wav"/>
|
||||
<prompt phrase="acme" filename="acme.wav"/>
|
||||
<prompt phrase="adrift" filename="adrift.wav"/>
|
||||
<prompt phrase="adroitness" filename="adroitness.wav"/>
|
||||
<prompt phrase="adult" filename="adult.wav"/>
|
||||
<prompt phrase="adviser" filename="adviser.wav"/>
|
||||
<prompt phrase="afflict" filename="afflict.wav"/>
|
||||
<prompt phrase="aftermath" filename="aftermath.wav"/>
|
||||
<prompt phrase="aggregate" filename="aggregate.wav"/>
|
||||
<prompt phrase="ahead" filename="ahead.wav"/>
|
||||
<prompt phrase="aimless" filename="aimless.wav"/>
|
||||
<prompt phrase="alkali" filename="alkali.wav"/>
|
||||
<prompt phrase="allow" filename="allow.wav"/>
|
||||
<prompt phrase="almighty" filename="almighty.wav"/>
|
||||
<prompt phrase="alone" filename="alone.wav"/>
|
||||
<prompt phrase="ammo" filename="ammo.wav"/>
|
||||
<prompt phrase="amulet" filename="amulet.wav"/>
|
||||
<prompt phrase="amusement" filename="amusement.wav"/>
|
||||
<prompt phrase="ancient" filename="ancient.wav"/>
|
||||
<prompt phrase="antenna" filename="antenna.wav"/>
|
||||
<prompt phrase="apple" filename="apple.wav"/>
|
||||
<prompt phrase="applicant" filename="applicant.wav"/>
|
||||
<prompt phrase="armistice" filename="armistice.wav"/>
|
||||
<prompt phrase="article" filename="article.wav"/>
|
||||
<prompt phrase="artist" filename="artist.wav"/>
|
||||
<prompt phrase="assume" filename="assume.wav"/>
|
||||
<prompt phrase="asteroid" filename="asteroid.wav"/>
|
||||
<prompt phrase="atlas" filename="atlas.wav"/>
|
||||
<prompt phrase="atmosphere" filename="atmosphere.wav"/>
|
||||
<prompt phrase="autopsy" filename="autopsy.wav"/>
|
||||
<prompt phrase="baboon" filename="baboon.wav"/>
|
||||
<prompt phrase="backfield" filename="backfield.wav"/>
|
||||
<prompt phrase="backward" filename="backward.wav"/>
|
||||
<prompt phrase="backwater" filename="backwater.wav"/>
|
||||
<prompt phrase="banjo" filename="banjo.wav"/>
|
||||
<prompt phrase="barbecue" filename="barbecue.wav"/>
|
||||
<prompt phrase="beaming" filename="beaming.wav"/>
|
||||
<prompt phrase="bedlamp" filename="bedlamp.wav"/>
|
||||
<prompt phrase="beehive" filename="beehive.wav"/>
|
||||
<prompt phrase="beeswax" filename="beeswax.wav"/>
|
||||
<prompt phrase="befriend" filename="befriend.wav"/>
|
||||
<prompt phrase="belowground" filename="belowground.wav"/>
|
||||
<prompt phrase="berserk" filename="berserk.wav"/>
|
||||
<prompt phrase="bifocals" filename="bifocals.wav"/>
|
||||
<prompt phrase="billiard" filename="billiard.wav"/>
|
||||
<prompt phrase="bison" filename="bison.wav"/>
|
||||
<prompt phrase="blackjack" filename="blackjack.wav"/>
|
||||
<prompt phrase="blockade" filename="blockade.wav"/>
|
||||
<prompt phrase="blowtorch" filename="blowtorch.wav"/>
|
||||
<prompt phrase="bluebird" filename="bluebird.wav"/>
|
||||
<prompt phrase="bodyguard" filename="bodyguard.wav"/>
|
||||
<prompt phrase="bombast" filename="bombast.wav"/>
|
||||
<prompt phrase="bookseller" filename="bookseller.wav"/>
|
||||
<prompt phrase="bookshelf" filename="bookshelf.wav"/>
|
||||
<prompt phrase="borderline" filename="borderline.wav"/>
|
||||
<prompt phrase="bottomless" filename="bottomless.wav"/>
|
||||
<prompt phrase="brackish" filename="brackish.wav"/>
|
||||
<prompt phrase="bravado" filename="bravado.wav"/>
|
||||
<prompt phrase="breadline" filename="breadline.wav"/>
|
||||
<prompt phrase="breakaway" filename="breakaway.wav"/>
|
||||
<prompt phrase="breakup" filename="breakup.wav"/>
|
||||
<prompt phrase="brickyard" filename="brickyard.wav"/>
|
||||
<prompt phrase="briefcase" filename="briefcase.wav"/>
|
||||
<prompt phrase="businessman" filename="businessman.wav"/>
|
||||
<prompt phrase="butterfat" filename="butterfat.wav"/>
|
||||
<prompt phrase="button" filename="button.wav"/>
|
||||
<prompt phrase="buzzard" filename="buzzard.wav"/>
|
||||
<prompt phrase="candidate" filename="candidate.wav"/>
|
||||
<prompt phrase="cannonball" filename="cannonball.wav"/>
|
||||
<prompt phrase="caravan" filename="caravan.wav"/>
|
||||
<prompt phrase="caretaker" filename="caretaker.wav"/>
|
||||
<prompt phrase="celebrate" filename="celebrate.wav"/>
|
||||
<prompt phrase="cellulose" filename="cellulose.wav"/>
|
||||
<prompt phrase="cement" filename="cement.wav"/>
|
||||
<prompt phrase="certify" filename="certify.wav"/>
|
||||
<prompt phrase="chairlift" filename="chairlift.wav"/>
|
||||
<prompt phrase="chambermaid" filename="chambermaid.wav"/>
|
||||
<prompt phrase="chatter" filename="chatter.wav"/>
|
||||
<prompt phrase="checkup" filename="checkup.wav"/>
|
||||
<prompt phrase="chisel" filename="chisel.wav"/>
|
||||
<prompt phrase="choking" filename="choking.wav"/>
|
||||
<prompt phrase="chopper" filename="chopper.wav"/>
|
||||
<prompt phrase="clamshell" filename="clamshell.wav"/>
|
||||
<prompt phrase="classic" filename="classic.wav"/>
|
||||
<prompt phrase="classroom" filename="classroom.wav"/>
|
||||
<prompt phrase="cleanup" filename="cleanup.wav"/>
|
||||
<prompt phrase="clergyman" filename="clergyman.wav"/>
|
||||
<prompt phrase="clockwork" filename="clockwork.wav"/>
|
||||
<prompt phrase="cobra" filename="cobra.wav"/>
|
||||
<prompt phrase="coherence" filename="coherence.wav"/>
|
||||
<prompt phrase="combustion" filename="combustion.wav"/>
|
||||
<prompt phrase="commando" filename="commando.wav"/>
|
||||
<prompt phrase="commence" filename="commence.wav"/>
|
||||
<prompt phrase="company" filename="company.wav"/>
|
||||
<prompt phrase="component" filename="component.wav"/>
|
||||
<prompt phrase="concert" filename="concert.wav"/>
|
||||
<prompt phrase="concurrent" filename="concurrent.wav"/>
|
||||
<prompt phrase="confidence" filename="confidence.wav"/>
|
||||
<prompt phrase="conformist" filename="conformist.wav"/>
|
||||
<prompt phrase="congregate" filename="congregate.wav"/>
|
||||
<prompt phrase="consensus" filename="consensus.wav"/>
|
||||
<prompt phrase="consulting" filename="consulting.wav"/>
|
||||
<prompt phrase="corporate" filename="corporate.wav"/>
|
||||
<prompt phrase="corrosion" filename="corrosion.wav"/>
|
||||
<prompt phrase="councilman" filename="councilman.wav"/>
|
||||
<prompt phrase="cowbell" filename="cowbell.wav"/>
|
||||
<prompt phrase="crackdown" filename="crackdown.wav"/>
|
||||
<prompt phrase="cranky" filename="cranky.wav"/>
|
||||
<prompt phrase="crossover" filename="crossover.wav"/>
|
||||
<prompt phrase="crowfoot" filename="crowfoot.wav"/>
|
||||
<prompt phrase="crucial" filename="crucial.wav"/>
|
||||
<prompt phrase="crucifix" filename="crucifix.wav"/>
|
||||
<prompt phrase="crumpled" filename="crumpled.wav"/>
|
||||
<prompt phrase="crusade" filename="crusade.wav"/>
|
||||
<prompt phrase="cubic" filename="cubic.wav"/>
|
||||
<prompt phrase="cumbersome" filename="cumbersome.wav"/>
|
||||
<prompt phrase="customer" filename="customer.wav"/>
|
||||
<prompt phrase="dashboard" filename="dashboard.wav"/>
|
||||
<prompt phrase="deadbolt" filename="deadbolt.wav"/>
|
||||
<prompt phrase="decadence" filename="decadence.wav"/>
|
||||
<prompt phrase="decimal" filename="decimal.wav"/>
|
||||
<prompt phrase="deckhand" filename="deckhand.wav"/>
|
||||
<prompt phrase="designing" filename="designing.wav"/>
|
||||
<prompt phrase="detector" filename="detector.wav"/>
|
||||
<prompt phrase="detergent" filename="detergent.wav"/>
|
||||
<prompt phrase="determine" filename="determine.wav"/>
|
||||
<prompt phrase="dictator" filename="dictator.wav"/>
|
||||
<prompt phrase="dinosaur" filename="dinosaur.wav"/>
|
||||
<prompt phrase="direction" filename="direction.wav"/>
|
||||
<prompt phrase="disable" filename="disable.wav"/>
|
||||
<prompt phrase="disbelief" filename="disbelief.wav"/>
|
||||
<prompt phrase="disruptive" filename="disruptive.wav"/>
|
||||
<prompt phrase="distortion" filename="distortion.wav"/>
|
||||
<prompt phrase="document" filename="document.wav"/>
|
||||
<prompt phrase="dogsled" filename="dogsled.wav"/>
|
||||
<prompt phrase="dragnet" filename="dragnet.wav"/>
|
||||
<prompt phrase="drainage" filename="drainage.wav"/>
|
||||
<prompt phrase="dreadful" filename="dreadful.wav"/>
|
||||
<prompt phrase="drifter" filename="drifter.wav"/>
|
||||
<prompt phrase="dropper" filename="dropper.wav"/>
|
||||
<prompt phrase="drumbeat" filename="drumbeat.wav"/>
|
||||
<prompt phrase="drunken" filename="drunken.wav"/>
|
||||
<prompt phrase="dwelling" filename="dwelling.wav"/>
|
||||
<prompt phrase="eating" filename="eating.wav"/>
|
||||
<prompt phrase="edict" filename="edict.wav"/>
|
||||
<prompt phrase="egghead" filename="egghead.wav"/>
|
||||
<prompt phrase="eightball" filename="eightball.wav"/>
|
||||
<prompt phrase="embezzle" filename="embezzle.wav"/>
|
||||
<prompt phrase="enchanting" filename="enchanting.wav"/>
|
||||
<prompt phrase="endorse" filename="endorse.wav"/>
|
||||
<prompt phrase="endow" filename="endow.wav"/>
|
||||
<prompt phrase="enlist" filename="enlist.wav"/>
|
||||
<prompt phrase="enrollment" filename="enrollment.wav"/>
|
||||
<prompt phrase="enterprise" filename="enterprise.wav"/>
|
||||
<prompt phrase="equation" filename="equation.wav"/>
|
||||
<prompt phrase="equipment" filename="equipment.wav"/>
|
||||
<prompt phrase="erase" filename="erase.wav"/>
|
||||
<prompt phrase="escapade" filename="escapade.wav"/>
|
||||
<prompt phrase="escape" filename="escape.wav"/>
|
||||
<prompt phrase="everyday" filename="everyday.wav"/>
|
||||
<prompt phrase="examine" filename="examine.wav"/>
|
||||
<prompt phrase="exceed" filename="exceed.wav"/>
|
||||
<prompt phrase="existence" filename="existence.wav"/>
|
||||
<prompt phrase="exodus" filename="exodus.wav"/>
|
||||
<prompt phrase="eyeglass" filename="eyeglass.wav"/>
|
||||
<prompt phrase="eyetooth" filename="eyetooth.wav"/>
|
||||
<prompt phrase="facial" filename="facial.wav"/>
|
||||
<prompt phrase="fallout" filename="fallout.wav"/>
|
||||
<prompt phrase="fascinate" filename="fascinate.wav"/>
|
||||
<prompt phrase="filament" filename="filament.wav"/>
|
||||
<prompt phrase="finicky" filename="finicky.wav"/>
|
||||
<prompt phrase="flagpole" filename="flagpole.wav"/>
|
||||
<prompt phrase="flatfoot" filename="flatfoot.wav"/>
|
||||
<prompt phrase="flytrap" filename="flytrap.wav"/>
|
||||
<prompt phrase="forever" filename="forever.wav"/>
|
||||
<prompt phrase="fortitude" filename="fortitude.wav"/>
|
||||
<prompt phrase="fracture" filename="fracture.wav"/>
|
||||
<prompt phrase="framework" filename="framework.wav"/>
|
||||
<prompt phrase="freedom" filename="freedom.wav"/>
|
||||
<prompt phrase="frequency" filename="frequency.wav"/>
|
||||
<prompt phrase="frighten" filename="frighten.wav"/>
|
||||
<prompt phrase="gadgetry" filename="gadgetry.wav"/>
|
||||
<prompt phrase="gazelle" filename="gazelle.wav"/>
|
||||
<prompt phrase="getaway" filename="getaway.wav"/>
|
||||
<prompt phrase="glitter" filename="glitter.wav"/>
|
||||
<prompt phrase="glossary" filename="glossary.wav"/>
|
||||
<prompt phrase="glucose" filename="glucose.wav"/>
|
||||
<prompt phrase="goggles" filename="goggles.wav"/>
|
||||
<prompt phrase="goldfish" filename="goldfish.wav"/>
|
||||
<prompt phrase="gossamer" filename="gossamer.wav"/>
|
||||
<prompt phrase="graduate" filename="graduate.wav"/>
|
||||
<prompt phrase="gravity" filename="gravity.wav"/>
|
||||
<prompt phrase="gremlin" filename="gremlin.wav"/>
|
||||
<prompt phrase="guidance" filename="guidance.wav"/>
|
||||
<prompt phrase="guitarist" filename="guitarist.wav"/>
|
||||
<prompt phrase="hamburger" filename="hamburger.wav"/>
|
||||
<prompt phrase="hamlet" filename="hamlet.wav"/>
|
||||
<prompt phrase="handiwork" filename="handiwork.wav"/>
|
||||
<prompt phrase="hazardous" filename="hazardous.wav"/>
|
||||
<prompt phrase="headwaters" filename="headwaters.wav"/>
|
||||
<prompt phrase="hemisphere" filename="hemisphere.wav"/>
|
||||
<prompt phrase="hesitate" filename="hesitate.wav"/>
|
||||
<prompt phrase="hideaway" filename="hideaway.wav"/>
|
||||
<prompt phrase="highchair" filename="highchair.wav"/>
|
||||
<prompt phrase="hockey" filename="hockey.wav"/>
|
||||
<prompt phrase="holiness" filename="holiness.wav"/>
|
||||
<prompt phrase="hurricane" filename="hurricane.wav"/>
|
||||
<prompt phrase="hydraulic" filename="hydraulic.wav"/>
|
||||
<prompt phrase="impartial" filename="impartial.wav"/>
|
||||
<prompt phrase="impetus" filename="impetus.wav"/>
|
||||
<prompt phrase="inception" filename="inception.wav"/>
|
||||
<prompt phrase="indigo" filename="indigo.wav"/>
|
||||
<prompt phrase="indoors" filename="indoors.wav"/>
|
||||
<prompt phrase="indulge" filename="indulge.wav"/>
|
||||
<prompt phrase="inertia" filename="inertia.wav"/>
|
||||
<prompt phrase="infancy" filename="infancy.wav"/>
|
||||
<prompt phrase="inferno" filename="inferno.wav"/>
|
||||
<prompt phrase="informant" filename="informant.wav"/>
|
||||
<prompt phrase="insincere" filename="insincere.wav"/>
|
||||
<prompt phrase="insurgent" filename="insurgent.wav"/>
|
||||
<prompt phrase="integrate" filename="integrate.wav"/>
|
||||
<prompt phrase="intention" filename="intention.wav"/>
|
||||
<prompt phrase="inventive" filename="inventive.wav"/>
|
||||
<prompt phrase="inverse" filename="inverse.wav"/>
|
||||
<prompt phrase="involve" filename="involve.wav"/>
|
||||
<prompt phrase="island" filename="island.wav"/>
|
||||
<prompt phrase="jawbone" filename="jawbone.wav"/>
|
||||
<prompt phrase="keyboard" filename="keyboard.wav"/>
|
||||
<prompt phrase="kickoff" filename="kickoff.wav"/>
|
||||
<prompt phrase="kiwi" filename="kiwi.wav"/>
|
||||
<prompt phrase="klaxon" filename="klaxon.wav"/>
|
||||
<prompt phrase="leprosy" filename="leprosy.wav"/>
|
||||
<prompt phrase="letterhead" filename="letterhead.wav"/>
|
||||
<prompt phrase="liberty" filename="liberty.wav"/>
|
||||
<prompt phrase="locale" filename="locale.wav"/>
|
||||
<prompt phrase="lockup" filename="lockup.wav"/>
|
||||
<prompt phrase="maritime" filename="maritime.wav"/>
|
||||
<prompt phrase="matchmaker" filename="matchmaker.wav"/>
|
||||
<prompt phrase="maverick" filename="maverick.wav"/>
|
||||
<prompt phrase="megaton" filename="megaton.wav"/>
|
||||
<prompt phrase="merit" filename="merit.wav"/>
|
||||
<prompt phrase="microscope" filename="microscope.wav"/>
|
||||
<prompt phrase="microwave" filename="microwave.wav"/>
|
||||
<prompt phrase="midsummer" filename="midsummer.wav"/>
|
||||
<prompt phrase="millionaire" filename="millionaire.wav"/>
|
||||
<prompt phrase="minnow" filename="minnow.wav"/>
|
||||
<prompt phrase="miracle" filename="miracle.wav"/>
|
||||
<prompt phrase="miser" filename="miser.wav"/>
|
||||
<prompt phrase="misnomer" filename="misnomer.wav"/>
|
||||
<prompt phrase="molasses" filename="molasses.wav"/>
|
||||
<prompt phrase="molecule" filename="molecule.wav"/>
|
||||
<prompt phrase="monument" filename="monument.wav"/>
|
||||
<prompt phrase="mosquito" filename="mosquito.wav"/>
|
||||
<prompt phrase="mural" filename="mural.wav"/>
|
||||
<prompt phrase="music" filename="music.wav"/>
|
||||
<prompt phrase="narrative" filename="narrative.wav"/>
|
||||
<prompt phrase="nebula" filename="nebula.wav"/>
|
||||
<prompt phrase="necklace" filename="necklace.wav"/>
|
||||
<prompt phrase="newborn" filename="newborn.wav"/>
|
||||
<prompt phrase="newsletter" filename="newsletter.wav"/>
|
||||
<prompt phrase="nightbird" filename="nightbird.wav"/>
|
||||
<prompt phrase="obtuse" filename="obtuse.wav"/>
|
||||
<prompt phrase="offload" filename="offload.wav"/>
|
||||
<prompt phrase="onlooker" filename="onlooker.wav"/>
|
||||
<prompt phrase="optic" filename="optic.wav"/>
|
||||
<prompt phrase="opulent" filename="opulent.wav"/>
|
||||
<prompt phrase="orca" filename="orca.wav"/>
|
||||
<prompt phrase="outfielder" filename="outfielder.wav"/>
|
||||
<prompt phrase="pandemic" filename="pandemic.wav"/>
|
||||
<prompt phrase="paperweight" filename="paperweight.wav"/>
|
||||
<prompt phrase="paragon" filename="paragon.wav"/>
|
||||
<prompt phrase="paragraph" filename="paragraph.wav"/>
|
||||
<prompt phrase="paramount" filename="paramount.wav"/>
|
||||
<prompt phrase="passenger" filename="passenger.wav"/>
|
||||
<prompt phrase="payday" filename="payday.wav"/>
|
||||
<prompt phrase="peachy" filename="peachy.wav"/>
|
||||
<prompt phrase="pedigree" filename="pedigree.wav"/>
|
||||
<prompt phrase="penetrate" filename="penetrate.wav"/>
|
||||
<prompt phrase="perceptive" filename="perceptive.wav"/>
|
||||
<prompt phrase="performance" filename="performance.wav"/>
|
||||
<prompt phrase="pharmacy" filename="pharmacy.wav"/>
|
||||
<prompt phrase="pheasant" filename="pheasant.wav"/>
|
||||
<prompt phrase="phonetic" filename="phonetic.wav"/>
|
||||
<prompt phrase="photograph" filename="photograph.wav"/>
|
||||
<prompt phrase="physique" filename="physique.wav"/>
|
||||
<prompt phrase="pioneer" filename="pioneer.wav"/>
|
||||
<prompt phrase="playhouse" filename="playhouse.wav"/>
|
||||
<prompt phrase="pocketful" filename="pocketful.wav"/>
|
||||
<prompt phrase="politeness" filename="politeness.wav"/>
|
||||
<prompt phrase="positive" filename="positive.wav"/>
|
||||
<prompt phrase="potato" filename="potato.wav"/>
|
||||
<prompt phrase="preclude" filename="preclude.wav"/>
|
||||
<prompt phrase="prefer" filename="prefer.wav"/>
|
||||
<prompt phrase="preshrunk" filename="preshrunk.wav"/>
|
||||
<prompt phrase="printer" filename="printer.wav"/>
|
||||
<prompt phrase="processor" filename="processor.wav"/>
|
||||
<prompt phrase="provincial" filename="provincial.wav"/>
|
||||
<prompt phrase="prowler" filename="prowler.wav"/>
|
||||
<prompt phrase="proximate" filename="proximate.wav"/>
|
||||
<prompt phrase="puberty" filename="puberty.wav"/>
|
||||
<prompt phrase="publisher" filename="publisher.wav"/>
|
||||
<prompt phrase="pupil" filename="pupil.wav"/>
|
||||
<prompt phrase="puppy" filename="puppy.wav"/>
|
||||
<prompt phrase="pyramid" filename="pyramid.wav"/>
|
||||
<prompt phrase="python" filename="python.wav"/>
|
||||
<prompt phrase="quadrant" filename="quadrant.wav"/>
|
||||
<prompt phrase="quantity" filename="quantity.wav"/>
|
||||
<prompt phrase="quiver" filename="quiver.wav"/>
|
||||
<prompt phrase="quota" filename="quota.wav"/>
|
||||
<prompt phrase="racketeer" filename="racketeer.wav"/>
|
||||
<prompt phrase="ragtime" filename="ragtime.wav"/>
|
||||
<prompt phrase="ratchet" filename="ratchet.wav"/>
|
||||
<prompt phrase="rebellion" filename="rebellion.wav"/>
|
||||
<prompt phrase="rebirth" filename="rebirth.wav"/>
|
||||
<prompt phrase="recipe" filename="recipe.wav"/>
|
||||
<prompt phrase="recover" filename="recover.wav"/>
|
||||
<prompt phrase="reform" filename="reform.wav"/>
|
||||
<prompt phrase="regain" filename="regain.wav"/>
|
||||
<prompt phrase="reindeer" filename="reindeer.wav"/>
|
||||
<prompt phrase="rematch" filename="rematch.wav"/>
|
||||
<prompt phrase="repay" filename="repay.wav"/>
|
||||
<prompt phrase="repellent" filename="repellent.wav"/>
|
||||
<prompt phrase="replica" filename="replica.wav"/>
|
||||
<prompt phrase="reproduce" filename="reproduce.wav"/>
|
||||
<prompt phrase="resistor" filename="resistor.wav"/>
|
||||
<prompt phrase="responsive" filename="responsive.wav"/>
|
||||
<prompt phrase="retouch" filename="retouch.wav"/>
|
||||
<prompt phrase="retraction" filename="retraction.wav"/>
|
||||
<prompt phrase="retrieval" filename="retrieval.wav"/>
|
||||
<prompt phrase="retrospect" filename="retrospect.wav"/>
|
||||
<prompt phrase="revenge" filename="revenge.wav"/>
|
||||
<prompt phrase="revenue" filename="revenue.wav"/>
|
||||
<prompt phrase="revival" filename="revival.wav"/>
|
||||
<prompt phrase="revolver" filename="revolver.wav"/>
|
||||
<prompt phrase="reward" filename="reward.wav"/>
|
||||
<prompt phrase="rhythm" filename="rhythm.wav"/>
|
||||
<prompt phrase="ribcage" filename="ribcage.wav"/>
|
||||
<prompt phrase="ringbolt" filename="ringbolt.wav"/>
|
||||
<prompt phrase="robust" filename="robust.wav"/>
|
||||
<prompt phrase="rocker" filename="rocker.wav"/>
|
||||
<prompt phrase="ruffled" filename="ruffled.wav"/>
|
||||
<prompt phrase="sailboat" filename="sailboat.wav"/>
|
||||
<prompt phrase="sandalwood" filename="sandalwood.wav"/>
|
||||
<prompt phrase="sardonic" filename="sardonic.wav"/>
|
||||
<prompt phrase="savagery" filename="savagery.wav"/>
|
||||
<prompt phrase="sawdust" filename="sawdust.wav"/>
|
||||
<prompt phrase="scallion" filename="scallion.wav"/>
|
||||
<prompt phrase="scavenger" filename="scavenger.wav"/>
|
||||
<prompt phrase="scenic" filename="scenic.wav"/>
|
||||
<prompt phrase="scorecard" filename="scorecard.wav"/>
|
||||
<prompt phrase="seabird" filename="seabird.wav"/>
|
||||
<prompt phrase="select" filename="select.wav"/>
|
||||
<prompt phrase="sensation" filename="sensation.wav"/>
|
||||
<prompt phrase="sentence" filename="sentence.wav"/>
|
||||
<prompt phrase="shadow" filename="shadow.wav"/>
|
||||
<prompt phrase="shamrock" filename="shamrock.wav"/>
|
||||
<prompt phrase="showgirl" filename="showgirl.wav"/>
|
||||
<prompt phrase="skullcap" filename="skullcap.wav"/>
|
||||
<prompt phrase="skydive" filename="skydive.wav"/>
|
||||
<prompt phrase="slingshot" filename="slingshot.wav"/>
|
||||
<prompt phrase="slowdown" filename="slowdown.wav"/>
|
||||
<prompt phrase="snapline" filename="snapline.wav"/>
|
||||
<prompt phrase="snapshot" filename="snapshot.wav"/>
|
||||
<prompt phrase="snowcap" filename="snowcap.wav"/>
|
||||
<prompt phrase="snowslide" filename="snowslide.wav"/>
|
||||
<prompt phrase="sociable" filename="sociable.wav"/>
|
||||
<prompt phrase="solo" filename="solo.wav"/>
|
||||
<prompt phrase="southward" filename="southward.wav"/>
|
||||
<prompt phrase="souvenir" filename="souvenir.wav"/>
|
||||
<prompt phrase="soybean" filename="soybean.wav"/>
|
||||
<prompt phrase="spaniel" filename="spaniel.wav"/>
|
||||
<prompt phrase="spearhead" filename="spearhead.wav"/>
|
||||
<prompt phrase="specialist" filename="specialist.wav"/>
|
||||
<prompt phrase="speculate" filename="speculate.wav"/>
|
||||
<prompt phrase="spellbind" filename="spellbind.wav"/>
|
||||
<prompt phrase="spheroid" filename="spheroid.wav"/>
|
||||
<prompt phrase="spigot" filename="spigot.wav"/>
|
||||
<prompt phrase="spindle" filename="spindle.wav"/>
|
||||
<prompt phrase="spyglass" filename="spyglass.wav"/>
|
||||
<prompt phrase="stagehand" filename="stagehand.wav"/>
|
||||
<prompt phrase="stagnate" filename="stagnate.wav"/>
|
||||
<prompt phrase="stairway" filename="stairway.wav"/>
|
||||
<prompt phrase="standard" filename="standard.wav"/>
|
||||
<prompt phrase="stapler" filename="stapler.wav"/>
|
||||
<prompt phrase="steamship" filename="steamship.wav"/>
|
||||
<prompt phrase="sterling" filename="sterling.wav"/>
|
||||
<prompt phrase="stethoscope" filename="stethoscope.wav"/>
|
||||
<prompt phrase="stockman" filename="stockman.wav"/>
|
||||
<prompt phrase="stopwatch" filename="stopwatch.wav"/>
|
||||
<prompt phrase="stormy" filename="stormy.wav"/>
|
||||
<prompt phrase="stupendous" filename="stupendous.wav"/>
|
||||
<prompt phrase="sugar" filename="sugar.wav"/>
|
||||
<prompt phrase="supportive" filename="supportive.wav"/>
|
||||
<prompt phrase="surmount" filename="surmount.wav"/>
|
||||
<prompt phrase="surrender" filename="surrender.wav"/>
|
||||
<prompt phrase="suspense" filename="suspense.wav"/>
|
||||
<prompt phrase="suspicious" filename="suspicious.wav"/>
|
||||
<prompt phrase="sweatband" filename="sweatband.wav"/>
|
||||
<prompt phrase="swelter" filename="swelter.wav"/>
|
||||
<prompt phrase="sympathy" filename="sympathy.wav"/>
|
||||
<prompt phrase="tactics" filename="tactics.wav"/>
|
||||
<prompt phrase="talon" filename="talon.wav"/>
|
||||
<prompt phrase="tambourine" filename="tambourine.wav"/>
|
||||
<prompt phrase="tapeworm" filename="tapeworm.wav"/>
|
||||
<prompt phrase="telephone" filename="telephone.wav"/>
|
||||
<prompt phrase="tempest" filename="tempest.wav"/>
|
||||
<prompt phrase="therapist" filename="therapist.wav"/>
|
||||
<prompt phrase="tiger" filename="tiger.wav"/>
|
||||
<prompt phrase="tissue" filename="tissue.wav"/>
|
||||
<prompt phrase="tobacco" filename="tobacco.wav"/>
|
||||
<prompt phrase="tolerance" filename="tolerance.wav"/>
|
||||
<prompt phrase="tomorrow" filename="tomorrow.wav"/>
|
||||
<prompt phrase="tonic" filename="tonic.wav"/>
|
||||
<prompt phrase="topmost" filename="topmost.wav"/>
|
||||
<prompt phrase="torpedo" filename="torpedo.wav"/>
|
||||
<prompt phrase="tracker" filename="tracker.wav"/>
|
||||
<prompt phrase="tradition" filename="tradition.wav"/>
|
||||
<prompt phrase="transit" filename="transit.wav"/>
|
||||
<prompt phrase="trauma" filename="trauma.wav"/>
|
||||
<prompt phrase="travesty" filename="travesty.wav"/>
|
||||
<prompt phrase="treadmill" filename="treadmill.wav"/>
|
||||
<prompt phrase="trombonist" filename="trombonist.wav"/>
|
||||
<prompt phrase="trouble" filename="trouble.wav"/>
|
||||
<prompt phrase="truncated" filename="truncated.wav"/>
|
||||
<prompt phrase="tumor" filename="tumor.wav"/>
|
||||
<prompt phrase="tunnel" filename="tunnel.wav"/>
|
||||
<prompt phrase="tycoon" filename="tycoon.wav"/>
|
||||
<prompt phrase="typewriter" filename="typewriter.wav"/>
|
||||
<prompt phrase="ultimate" filename="ultimate.wav"/>
|
||||
<prompt phrase="uncut" filename="uncut.wav"/>
|
||||
<prompt phrase="undaunted" filename="undaunted.wav"/>
|
||||
<prompt phrase="underfoot" filename="underfoot.wav"/>
|
||||
<prompt phrase="unearth" filename="unearth.wav"/>
|
||||
<prompt phrase="unicorn" filename="unicorn.wav"/>
|
||||
<prompt phrase="unify" filename="unify.wav"/>
|
||||
<prompt phrase="universe" filename="universe.wav"/>
|
||||
<prompt phrase="unravel" filename="unravel.wav"/>
|
||||
<prompt phrase="unwind" filename="unwind.wav"/>
|
||||
<prompt phrase="upcoming" filename="upcoming.wav"/>
|
||||
<prompt phrase="uproot" filename="uproot.wav"/>
|
||||
<prompt phrase="upset" filename="upset.wav"/>
|
||||
<prompt phrase="upshot" filename="upshot.wav"/>
|
||||
<prompt phrase="vacancy" filename="vacancy.wav"/>
|
||||
<prompt phrase="vagabond" filename="vagabond.wav"/>
|
||||
<prompt phrase="vapor" filename="vapor.wav"/>
|
||||
<prompt phrase="vertigo" filename="vertigo.wav"/>
|
||||
<prompt phrase="village" filename="village.wav"/>
|
||||
<prompt phrase="virus" filename="virus.wav"/>
|
||||
<prompt phrase="visitor" filename="visitor.wav"/>
|
||||
<prompt phrase="vocalist" filename="vocalist.wav"/>
|
||||
<prompt phrase="voyager" filename="voyager.wav"/>
|
||||
<prompt phrase="waffle" filename="waffle.wav"/>
|
||||
<prompt phrase="wallet" filename="wallet.wav"/>
|
||||
<prompt phrase="warranty" filename="warranty.wav"/>
|
||||
<prompt phrase="watchword" filename="watchword.wav"/>
|
||||
<prompt phrase="wayside" filename="wayside.wav"/>
|
||||
<prompt phrase="whimsical" filename="whimsical.wav"/>
|
||||
<prompt phrase="willow" filename="willow.wav"/>
|
||||
<prompt phrase="woodlark" filename="woodlark.wav"/>
|
||||
<prompt phrase="yesteryear" filename="yesteryear.wav"/>
|
||||
<!-- Event prompts -->
|
||||
<prompt phrase="Bem-vindo ao agente de registro de segurança ZRTP." filename="zrtp-enroll_welcome.wav"/>
|
||||
<prompt phrase="Vocę deve verificar a autentificaçăo com o seu destinatário. Se năo coincidir, isso indica presença de um dispositivo de escuta telefonica." filename="zrtp-check_sas.wav"/>
|
||||
<prompt phrase="Somente aqueles telefones que estem autentificados podem ser configurados de maneira segura neste sistema para retransmitir as ligaçőes em ZRTP. O seu telefone nao esta autentificado com este sistema, esta ligaçăo năo sera realizada." filename="zrtp-enroll_not_sip_registered.wav"/>
|
||||
<prompt phrase="O seu telefone indica que é seguro este sistema para realizar ligaçőes seguras em ZRTP, vocę năo precisa fazer nada mais." filename="zrtp-enroll_already_enrolled.wav"/>
|
||||
<prompt phrase="Somente os telefones equipados com protocolo ZRTP podem usar este ramal.O seu telefone năo esta configurado para ZRTP, esta ligaçăo năo sera completada." filename="zrtp-enroll_notzrtp.wav"/>
|
||||
<prompt phrase="Este sistema está configurado para realizar ligaçőes telefonicas encriptadas em ZRTP. Vocę deve decidir se permitira que este sistema possa interceptar e monitorizar as suas ligaçőes telefonicas seguras. Pode finalizar a ligaçăo depois disso." filename="zrtp-enroll_confirmed.wav"/>
|
||||
<prompt phrase="Compare verbalmente este código de autentificaçăo com o seu destinatário." filename="zrtp-is_secure.wav"/>
|
||||
<prompt phrase="O código de autentificaçăo năo foi verificado." filename="zrtp-is_unverified.wav"/>
|
||||
<prompt phrase="O código de autentificaçăo foi verificado." filename="zrtp-is_verified.wav"/>
|
||||
<prompt phrase="Obrigado pela sua ligaçăo. Até logo." filename="zrtp-thankyou_goodbye.wav"/>
|
||||
<prompt phrase="Algo falha." filename="zrtp-somethings_wrong.wav"/>
|
||||
<prompt phrase="Erro." filename="zrtp-status_error.wav"/>
|
||||
<prompt phrase="A ligaçăo năo e segura." filename="zrtp-status_notsecure.wav"/>
|
||||
<prompt phrase="A ligaçăo e segura." filename="zrtp-status_secure.wav"/>
|
||||
<prompt phrase="Securizando a ligaçăo." filename="zrtp-status_securing.wav"/>
|
||||
</zrtp>
|
||||
</pt_BR>
|
||||
</language>
|
|
@ -0,0 +1,987 @@
|
|||
<language>
|
||||
<pt_PT>
|
||||
<ascii>
|
||||
<prompt phrase="Espaço" filename="32.wav"/>
|
||||
<prompt phrase="Cardinal" filename="35.wav"/>
|
||||
<prompt phrase="Asterisco" filename="42.wav"/>
|
||||
<prompt phrase="Ponto" filename="46.wav"/>
|
||||
<prompt phrase="A" filename="97.wav"/>
|
||||
<prompt phrase="B" filename="98.wav"/>
|
||||
<prompt phrase="C" filename="99.wav"/>
|
||||
<prompt phrase="D" filename="100.wav"/>
|
||||
<prompt phrase="E" filename="101.wav"/>
|
||||
<prompt phrase="F" filename="102.wav"/>
|
||||
<prompt phrase="G" filename="103.wav"/>
|
||||
<prompt phrase="H" filename="104.wav"/>
|
||||
<prompt phrase="I" filename="105.wav"/>
|
||||
<prompt phrase="J" filename="106.wav"/>
|
||||
<prompt phrase="K" filename="107.wav"/>
|
||||
<prompt phrase="L" filename="108.wav"/>
|
||||
<prompt phrase="M" filename="109.wav"/>
|
||||
<prompt phrase="N" filename="110.wav"/>
|
||||
<prompt phrase="O" filename="111.wav"/>
|
||||
<prompt phrase="P" filename="112.wav"/>
|
||||
<prompt phrase="Q" filename="113.wav"/>
|
||||
<prompt phrase="R" filename="114.wav"/>
|
||||
<prompt phrase="S" filename="115.wav"/>
|
||||
<prompt phrase="T" filename="116.wav"/>
|
||||
<prompt phrase="U" filename="117.wav"/>
|
||||
<prompt phrase="V" filename="118.wav"/>
|
||||
<prompt phrase="W" filename="119.wav"/>
|
||||
<prompt phrase="X" filename="120.wav"/>
|
||||
<prompt phrase="Y" filename="121.wav"/>
|
||||
<prompt phrase="Z" filename="122.wav"/>
|
||||
</ascii>
|
||||
<phonetic-ascii>
|
||||
<prompt phrase="Espaço" filename="32.wav"/>
|
||||
<prompt phrase="Ponto" filename="46.wav"/>
|
||||
<prompt phrase="Alpha" filename="97.wav"/>
|
||||
<prompt phrase="Bravo" filename="98.wav"/>
|
||||
<prompt phrase="Charlie" filename="99.wav"/>
|
||||
<prompt phrase="Delta" filename="100.wav"/>
|
||||
<prompt phrase="Echo" filename="101.wav"/>
|
||||
<prompt phrase="Foxtrot" filename="102.wav"/>
|
||||
<prompt phrase="Golf" filename="103.wav"/>
|
||||
<prompt phrase="Hotel" filename="104.wav"/>
|
||||
<prompt phrase="India" filename="105.wav"/>
|
||||
<prompt phrase="Juliet" filename="106.wav"/>
|
||||
<prompt phrase="Kilo" filename="107.wav"/>
|
||||
<prompt phrase="Lima" filename="108.wav"/>
|
||||
<prompt phrase="Mike" filename="109.wav"/>
|
||||
<prompt phrase="November" filename="110.wav"/>
|
||||
<prompt phrase="Oscar" filename="111.wav"/>
|
||||
<prompt phrase="Papa" filename="112.wav"/>
|
||||
<prompt phrase="Quebec" filename="113.wav"/>
|
||||
<prompt phrase="Romeo" filename="114.wav"/>
|
||||
<prompt phrase="Sierra" filename="115.wav"/>
|
||||
<prompt phrase="Tango" filename="116.wav"/>
|
||||
<prompt phrase="Unifor" filename="117.wav"/>
|
||||
<prompt phrase="Victor" filename="118.wav"/>
|
||||
<prompt phrase="Whiskey" filename="119.wav"/>
|
||||
<prompt phrase="Xray" filename="120.wav"/>
|
||||
<prompt phrase="Yankee" filename="121.wav"/>
|
||||
<prompt phrase="Zulu" filename="122.wav"/>
|
||||
</phonetic-ascii>
|
||||
<digits>
|
||||
<prompt phrase="Zero" filename="0.wav"/>
|
||||
<prompt phrase="Um" filename="1.wav"/>
|
||||
<prompt phrase="Dois" filename="2.wav"/>
|
||||
<prompt phrase="Três" filename="3.wav"/>
|
||||
<prompt phrase="Quatro" filename="4.wav"/>
|
||||
<prompt phrase="Cinco" filename="5.wav"/>
|
||||
<prompt phrase="Seis" filename="6.wav"/>
|
||||
<prompt phrase="Sete" filename="7.wav"/>
|
||||
<prompt phrase="Oito" filename="8.wav"/>
|
||||
<prompt phrase="Nove" filename="9.wav"/>
|
||||
<prompt phrase="Dez" filename="10.wav"/>
|
||||
<prompt phrase="Onze" filename="11.wav"/>
|
||||
<prompt phrase="Doze" filename="12.wav"/>
|
||||
<prompt phrase="Treze" filename="13.wav"/>
|
||||
<prompt phrase="Catorze" filename="14.wav"/>
|
||||
<prompt phrase="Quinze" filename="15.wav"/>
|
||||
<prompt phrase="Dezasseis" filename="16.wav"/>
|
||||
<prompt phrase="Dezassete" filename="17.wav"/>
|
||||
<prompt phrase="Dezoito" filename="18.wav"/>
|
||||
<prompt phrase="Dezanove" filename="19.wav"/>
|
||||
<prompt phrase="Vinte" filename="20.wav"/>
|
||||
<prompt phrase="Trinta" filename="30.wav"/>
|
||||
<prompt phrase="Quarenta" filename="40.wav"/>
|
||||
<prompt phrase="Cinquenta" filename="50.wav"/>
|
||||
<prompt phrase="Sessenta" filename="60.wav"/>
|
||||
<prompt phrase="Setenta" filename="70.wav"/>
|
||||
<prompt phrase="Oitenta" filename="80.wav"/>
|
||||
<prompt phrase="Noventa" filename="90.wav"/>
|
||||
<prompt phrase="Cem" filename="100.wav"/>
|
||||
<prompt phrase="Duzentos" filename="200.wav"/>
|
||||
<prompt phrase="Trezentos" filename="300.wav"/>
|
||||
<prompt phrase="Quinhentos" filename="500.wav"/>
|
||||
<prompt phrase="Ponto" filename="dot.wav"/>
|
||||
<prompt phrase="Primeiro" filename="h-1.wav"/>
|
||||
<prompt phrase="Segundo" filename="h-2.wav"/>
|
||||
<prompt phrase="Terceiro" filename="h-3.wav"/>
|
||||
<prompt phrase="Quarto" filename="h-4.wav"/>
|
||||
<prompt phrase="Quinto" filename="h-5.wav"/>
|
||||
<prompt phrase="Sexto" filename="h-6.wav"/>
|
||||
<prompt phrase="Sétimo" filename="h-7.wav"/>
|
||||
<prompt phrase="Oitavo" filename="h-8.wav"/>
|
||||
<prompt phrase="Nono" filename="h-9.wav"/>
|
||||
<prompt phrase="Décimo" filename="h-10.wav"/>
|
||||
<prompt phrase="Vigésimo" filename="h-20.wav"/>
|
||||
<prompt phrase="Trigésimo" filename="h-30.wav"/>
|
||||
<prompt phrase="Quadragésimo" filename="h-40.wav"/>
|
||||
<prompt phrase="Quinquagésimo" filename="h-50.wav"/>
|
||||
<prompt phrase="Sexagésimo" filename="h-60.wav"/>
|
||||
<prompt phrase="Septuagésimo" filename="h-70.wav"/>
|
||||
<prompt phrase="Octogésimo" filename="h-80.wav"/>
|
||||
<prompt phrase="Nonagésimo" filename="h-90.wav"/>
|
||||
<prompt phrase="Cento" filename="hundred.wav"/>
|
||||
<prompt phrase="Centos" filename="hundreds.wav"/>
|
||||
<prompt phrase="Mil" filename="thousand.wav"/>
|
||||
<prompt phrase="Milhão" filename="million.wav"/>
|
||||
<prompt phrase="Milhões" filename="millions.wav"/>
|
||||
<prompt phrase="Período" filename="period.wav"/>
|
||||
<prompt phrase="Ponto" filename="point.wav"/>
|
||||
<prompt phrase="Cardinal" filename="pound.wav"/>
|
||||
<prompt phrase="Asterisco" filename="star.wav"/>
|
||||
</digits>
|
||||
<currency>
|
||||
<prompt phrase="E" filename="and.wav"/>
|
||||
<prompt phrase="Cêntimo" filename="cent.wav"/>
|
||||
<prompt phrase="Central" filename="central.wav"/>
|
||||
<prompt phrase="Cêntimos por minuto" filename="cents-per-minute.wav"/>
|
||||
<prompt phrase="Cêntimos" filename="cents.wav"/>
|
||||
<prompt phrase="Dólar" filename="dollar.wav"/>
|
||||
<prompt phrase="Dólares" filename="dollars.wav"/>
|
||||
<prompt phrase="Menos" filename="minus.wav"/>
|
||||
<prompt phrase="Negativo" filename="negative.wav"/>
|
||||
</currency>
|
||||
<time>
|
||||
<prompt phrase="A.M." filename="a-m.wav"/>
|
||||
<prompt phrase="a" filename="at.wav"/>
|
||||
<prompt phrase="às" filename="ats.wav"/>
|
||||
<prompt phrase="Domingo" filename="day-0.wav"/>
|
||||
<prompt phrase="Segunda-feira" filename="day-1.wav"/>
|
||||
<prompt phrase="Terça-feira" filename="day-2.wav"/>
|
||||
<prompt phrase="Quarta-feira" filename="day-3.wav"/>
|
||||
<prompt phrase="Quinta-feira" filename="day-4.wav"/>
|
||||
<prompt phrase="Sexta-feira" filename="day-5.wav"/>
|
||||
<prompt phrase="Sábado" filename="day-6.wav"/>
|
||||
<prompt phrase="Hora" filename="hour.wav"/>
|
||||
<prompt phrase="Horas" filename="hours.wav"/>
|
||||
<prompt phrase="Minuto" filename="minute.wav"/>
|
||||
<prompt phrase="Minutos" filename="minutes.wav"/>
|
||||
<prompt phrase="Janeiro" filename="mon-0.wav"/>
|
||||
<prompt phrase="Fevereiro" filename="mon-1.wav"/>
|
||||
<prompt phrase="Março" filename="mon-2.wav"/>
|
||||
<prompt phrase="Abril" filename="mon-3.wav"/>
|
||||
<prompt phrase="Maio" filename="mon-4.wav"/>
|
||||
<prompt phrase="Junho" filename="mon-5.wav"/>
|
||||
<prompt phrase="Julho" filename="mon-6.wav"/>
|
||||
<prompt phrase="Agosto" filename="mon-7.wav"/>
|
||||
<prompt phrase="Setembro" filename="mon-8.wav"/>
|
||||
<prompt phrase="Outubro" filename="mon-9.wav"/>
|
||||
<prompt phrase="Novembro" filename="mon-10.wav"/>
|
||||
<prompt phrase="Dezembro" filename="mon-11.wav"/>
|
||||
<prompt phrase="Em ponto" filename="oclock.wav"/>
|
||||
<prompt phrase="P.M." filename="p-m.wav"/>
|
||||
<prompt phrase="Segundo" filename="second.wav"/>
|
||||
<prompt phrase="Segundos" filename="seconds.wav"/>
|
||||
<prompt phrase="Hoje" filename="today.wav"/>
|
||||
<prompt phrase="Amanhã" filename="tomorrow.wav"/>
|
||||
<prompt phrase="Ontem" filename="yesterday.wav"/>
|
||||
</time>
|
||||
<voicemail>
|
||||
<prompt phrase="A pessoa na extensão..." filename="vm-person.wav"/>
|
||||
<prompt phrase="marcada como urgente" filename="vm-marked-urgent.wav"/>
|
||||
<prompt phrase="email enviado" filename="vm-emailed.wav"/>
|
||||
<prompt phrase="Você tem..." filename="vm-you_have.wav"/>
|
||||
<prompt phrase="Por favor introduza o seu número de utilizador, seguido de..." filename="vm-enter_id.wav"/>
|
||||
<prompt phrase="Por favor introduza a sua palavra passe, seguida de..." filename="vm-enter_pass.wav"/>
|
||||
<prompt phrase="Falha na autenticação." filename="vm-fail_auth.wav"/>
|
||||
<prompt phrase="Bem-vindo ao seu correio de voz." filename="vm-hello.wav"/>
|
||||
<prompt phrase="Até breve." filename="vm-goodbye.wav"/>
|
||||
<prompt phrase="Após o sinal por favor diga o seu nome, pressione qualquer tecla ou deixe de falar para parar a gravação." filename="vm-record_name1.wav"/>
|
||||
<prompt phrase="Seleccione uma saudação entre 1 e 9" filename="vm-choose_greeting_choose.wav"/>
|
||||
<prompt phrase="Valor inválido." filename="vm-choose_greeting_fail.wav"/>
|
||||
<prompt phrase="Demasiadas tentativas falhadas." filename="vm-abort.wav"/>
|
||||
<prompt phrase="Para alterar a sua palavra passe..." filename="vm-change_password.wav"/>
|
||||
<prompt phrase="após o sinal grave a sua saudação, pressione qualquer tecla ou deixe de falar para parar a gravação." filename="vm-record_greeting.wav"/>
|
||||
<prompt phrase="após o sinal grave a sua mensagem, pressione qualquer tecla ou deixe de falar para parar a gravação." filename="vm-record_message.wav"/>
|
||||
<prompt phrase="Não está disponível." filename="vm-play_greeting.wav"/>
|
||||
<prompt phrase="nova e urgente" filename="vm-urgent-new.wav"/>
|
||||
<prompt phrase="nova" filename="vm-new.wav"/>
|
||||
<prompt phrase="guardada e urgente" filename="vm-urgent-saved.wav"/>
|
||||
<prompt phrase="guardada" filename="vm-saved.wav"/>
|
||||
<prompt phrase="mensagem" filename="vm-message.wav"/>
|
||||
<prompt phrase="mensagens" filename="vm-messages.wav"/>
|
||||
<prompt phrase="marque" filename="vm-press.wav"/>
|
||||
<prompt phrase="Para ouvir as mensagens novas..." filename="vm-listen_new.wav"/>
|
||||
<prompt phrase="Para ouvir as mensagens guardadas..." filename="vm-listen_saved.wav"/>
|
||||
<prompt phrase="Para opções avançadas..." filename="vm-advanced.wav"/>
|
||||
<prompt phrase="Para sair..." filename="vm-to_exit.wav"/>
|
||||
<prompt phrase="Para gravar a sua saudação..." filename="vm-record_greeting.wav"/>
|
||||
<prompt phrase="Para escolher a sua saudação..." filename="vm-choose_greeting.wav"/>
|
||||
<prompt phrase="Para gravar o seu nome..." filename="vm-record_name2.wav"/>
|
||||
<prompt phrase="Para o menu principal..." filename="vm-main_menu.wav"/>
|
||||
<prompt phrase="Para ouvir a gravação..." filename="vm-listen_to_recording.wav"/>
|
||||
<prompt phrase="Para guardar a gravação..." filename="vm-save_recording.wav"/>
|
||||
<prompt phrase="Para gravar novamente..." filename="vm-rerecord.wav"/>
|
||||
<prompt phrase="Para marcar esta mensagem como urgente..." filename="vm-mark_urgent.wav"/>
|
||||
<prompt phrase="Para continuar..." filename="vm-continue.wav"/>
|
||||
<prompt phrase="Para ouvir a gravação novamente..." filename="vm-listen_to_recording_again.wav"/>
|
||||
<prompt phrase="Para apagar a gravação..." filename="vm-delete_recording.wav"/>
|
||||
<prompt phrase="Para encaminhar a gravação para o seu email..." filename="vm-forward_to_email.wav"/>
|
||||
<prompt phrase="saudação" filename="vm-greeting.wav"/>
|
||||
<prompt phrase="seleccionada" filename="vm-selected.wav"/>
|
||||
<prompt phrase="Não está disponível." filename="vm-not_available.wav"/>
|
||||
<prompt phrase="Mensagem número..." filename="vm-message_number.wav"/>
|
||||
<prompt phrase="apagada" filename="vm-deleted.wav"/>
|
||||
<prompt phrase="O tamanho da sua gravação é menor que o mínimo aceite, por favor tente novamente." filename="vm-too-small.wav"/>
|
||||
<prompt phrase="na caixa de entrada" filename="vm-in_folder.wav"/>
|
||||
<prompt phrase="Para devolver a chamada agora..." filename="vm-return_call.wav"/>
|
||||
<prompt phrase="urgente" filename="vm-urgent.wav"/>
|
||||
<prompt phrase="Esta caixa de correio está cheia, por favor tente mais tarde." filename="vm-mailbox_full.wav"/>
|
||||
<prompt phrase="Bem-Vindo ao seu voicemail. Para ouvir o tutorial e configurar o seu voicemail, pressione um. Para saltar-lo pressione dois." filename="vm-tutorial_yes_no.wav"/>
|
||||
<prompt phrase="Necessita gravar o seu nome e sobrenome. Esta gravação é usada entre outros, no serviço de directório." filename="vm-tutorial_record_name.wav"/>
|
||||
<prompt phrase="O número de identificação pessoal ou PIN serve para impedir o acesso de terceiros às suas mensagens. Deseja alterar o seu PIN agora?" filename="vm-tutorial_change_pin.wav"/>
|
||||
</voicemail>
|
||||
<directory>
|
||||
<prompt phrase="Por favor introduza as primeiras letras do nome da pessoa." filename="dir-enter-person.wav"/>
|
||||
<prompt phrase="...último nome..." filename="dir-last_name.wav"/>
|
||||
<prompt phrase="Para pesquisar por..." filename="dir-to_search_by.wav"/>
|
||||
<prompt phrase="...primeiro nome..." filename="dir-first_name.wav"/>
|
||||
<prompt phrase="Não foram encontrados resultados, tente novamente." filename="dir-no_match_entry.wav"/>
|
||||
<prompt phrase="...resultados encontrados para a sua pesquisa." filename="dir-result_match.wav"/>
|
||||
<prompt phrase="A sua pesquisa devolveu demasiados resultados, por favor tente novamente." filename="dir-too_many_result.wav"/>
|
||||
<prompt phrase="Não há mais resultados." filename="dir-no_more_results.wav"/>
|
||||
<prompt phrase="Resultado número" filename="dir-result_number.wav"/>
|
||||
<prompt phrase="...na extensão..." filename="dir-at_extension.wav"/>
|
||||
<prompt phrase="Para seleccionar este resultado..." filename="dir-to_select_entry.wav"/>
|
||||
<prompt phrase="Para o resultado seguinte..." filename="dir-for_next.wav"/>
|
||||
<prompt phrase="Para o resultado anterior..." filename="dir-for_prev.wav"/>
|
||||
<prompt phrase="Para iniciar uma nova pesquisa..." filename="dir-start_new_search.wav"/>
|
||||
<prompt phrase="Você necessita de especificar um mínimo de..." filename="dir-specify_mininum_first.wav"/>
|
||||
<prompt phrase="...letras do nome da pessoa, tente novamente." filename="dir-letters_of_person_name.wav"/>
|
||||
<prompt phrase="marque" filename="dir-press.wav"/>
|
||||
</directory>
|
||||
<conference>
|
||||
<prompt phrase="NULL" filename="conf-ack.wav" type="tone"/>
|
||||
<prompt phrase="NULL" filename="conf-nack.wav" type="tone"/>
|
||||
<prompt phrase="Você agora está em silêncio." filename="conf-muted.wav"/>
|
||||
<prompt phrase="Você já não está em silêncio." filename="conf-unmuted.wav"/>
|
||||
<prompt phrase="Neste momento você é a única pessoa na conferência." filename="conf-alone.wav"/>
|
||||
<prompt phrase="NULL" filename="conf-perpetual.wav" type="music"/>
|
||||
<prompt phrase="NULL" filename="conf-enter.wav" type="tone"/>
|
||||
<prompt phrase="NULL" filename="conf-exit.wav" type="tone"/>
|
||||
<prompt phrase="Você foi excluído desta conferência." filename="conf-kicked.wav"/>
|
||||
<prompt phrase="Esta conferência está bloqueada." filename="conf-locked.wav"/>
|
||||
<prompt phrase="A conferência está agora bloqueada." filename="conf-is-locked.wav"/>
|
||||
<prompt phrase="A conferência está agora desbloqueada." filename="conf-is-unlocked.wav"/>
|
||||
<prompt phrase="Por favor introduza o PIN da conferência." filename="conf-pin.wav"/>
|
||||
<prompt phrase="PIN inválido, tente novamente." filename="conf-bad-pin.wav"/>
|
||||
<prompt phrase="Até breve." filename="conf-goodbye.wav"/>
|
||||
<prompt phrase="Bem-vindo à conferência." filename="conf-welcome.wav"/>
|
||||
</conference>
|
||||
<ivr>
|
||||
<prompt phrase="Número da conta" filename="ivr-account_number.wav"/>
|
||||
<prompt phrase="Estabelecer contacto com a pessoa que telefona" filename="ivr-connect_to_caller.wav"/>
|
||||
<prompt phrase="Se conhece a extensão do destinatário, por favor marque-a agora." filename="ivr-enter_ext_pound.wav"/>
|
||||
<prompt phrase="Por favor introduza uma extensão seguida de cardinal." filename="ivr-enter_ext.wav"/>
|
||||
<prompt phrase="Para esta pessoa..." filename="ivr-for_this_person.wav"/>
|
||||
<prompt phrase="Por favor aguarde enquanto a sua chamada é estabelecida." filename="ivr-hold_connect_call.wav"/>
|
||||
<prompt phrase="Desculpe" filename="ivr-im_sorry.wav"/>
|
||||
<prompt phrase="Por favor" filename="ivr-please.wav"/>
|
||||
<prompt phrase="Por favor devolva a nossa chamada às..." filename="ivr-please_return_our_call_at.wav"/>
|
||||
<prompt phrase="De acordo com o número de referência" filename="ivr-regarding_reference_number.wav"/>
|
||||
<prompt phrase="Este é um exemplo de um submenu IVR..." filename="ivr-sample_submenu.wav"/>
|
||||
<prompt phrase="Por favor diga o seu nome depois do sinal." filename="ivr-say_name.wav"/>
|
||||
<prompt phrase="Enviar esta chamada para o correio de voz." filename="ivr-send_to_voicemail.wav"/>
|
||||
<prompt phrase="Para falar com um responsável do apoio a clientes..." filename="ivr-speak_to_a_customer_service_representative.wav"/>
|
||||
<prompt phrase="Deixe uma mensagem" filename="ivr-take_a_message.wav"/>
|
||||
<prompt phrase="Obrigado" filename="ivr-thank_you.wav"/>
|
||||
<prompt phrase="Essa era uma entrada inválida." filename="ivr-that_was_an_invalid_entry.wav"/>
|
||||
<prompt phrase="Esta é uma chamada de..." filename="ivr-this_is_a_call_from.wav"/>
|
||||
<prompt phrase="Este IVR permite-lhe testar algumas das funções..." filename="ivr-this_ivr_will_let_you_test_features.wav"/>
|
||||
<prompt phrase="Para ligar à conferência FreeSWITCH..." filename="ivr-to_call_the_freeswitch_conference.wav"/>
|
||||
<prompt phrase="Para realizar um teste FreeSWITCH eco..." filename="ivr-to_do_a_freeswitch_echo_test.wav"/>
|
||||
<prompt phrase="Para realizar um teste FWD eco..." filename="ivr-to_do_a_fwd_echo_test.wav"/>
|
||||
<prompt phrase="Para ouvir o exemplo de um submenu IVR..." filename="ivr-to_hear_sample_submenu.wav"/>
|
||||
<prompt phrase="Para ouvir gritaria de macacos..." filename="ivr-to_hear_screaming_monkeys.wav"/>
|
||||
<prompt phrase="Para ouvir música em espera..." filename="ivr-to_listen_to_moh.wav"/>
|
||||
<prompt phrase="Para ouvir novamente estas opções..." filename="ivr-to_repeat_these_options.wav"/>
|
||||
<prompt phrase="Para voltar ao menu anterior..." filename="ivr-to_return_to_previous_menu.wav"/>
|
||||
<prompt phrase="Para falar com um operador..." filename="ivr-to_speak_with_an_operator.wav"/>
|
||||
<prompt phrase="Bem-vindo a FreeSWITCH, o futuro da telefonia." filename="ivr-welcome_to_freeswitch.wav"/>
|
||||
<prompt phrase="Você pode sair a qualquer altura, simplesmente terminando a chamada." filename="ivr-you_may_exit_by_hanging_up.wav"/>
|
||||
<prompt phrase="ou" filename ="ivr-or.wav"/>
|
||||
<prompt phrase="não" filename ="ivr-not.wav"/>
|
||||
<prompt phrase="chamada" filename ="ivr-call.wav"/>
|
||||
<prompt phrase="Você pode" filename ="ivr-you_may.wav"/>
|
||||
<prompt phrase="Olá" filename="ivr-hello.wav"/>
|
||||
<prompt phrase="Usando as teclas do seu telefone..." filename="ivr-use_telephone_keypad.wav"/>
|
||||
<prompt phrase="Por favor soletre o nome da pessoa que você pretente contactar." filename="ivr-spell_name.wav"/>
|
||||
<prompt phrase="Último nome primeiro" filename="ivr-last_name_first.wav"/>
|
||||
<prompt phrase="Primeiro nome primeiro" filename="ivr-first_name_first.wav"/>
|
||||
<prompt phrase="Marque 1 para Q ou Z." filename="ivr-press_one_q_or_z.wav"/>
|
||||
<prompt phrase="Vendas" filename="ivr-sales.wav"/>
|
||||
<prompt phrase="Apoio a clientes" filename="ivr-customer_service.wav"/>
|
||||
<prompt phrase="Suporte técnico" filename="ivr-technical_support.wav"/>
|
||||
<prompt phrase="Operador" filename="ivr-operator.wav"/>
|
||||
<prompt phrase="Você marcou uma extensão inválida." filename="ivr-you_have_dialed_an_invalid_extension.wav"/>
|
||||
<prompt phrase="Por favor marque a sua extensão, seguida de cardinal." filename="ivr-please_enter_extension_followed_by_pound.wav"/>
|
||||
<prompt phrase="Por favor marque o seu número PIN, seguido de cardinal." filename="ivr-please_enter_pin_followed_by_pound.wav"/>
|
||||
<prompt phrase="O seu número PIN ou extensão é inválido." filename="ivr-pin_or_extension_is-invalid.wav"/>
|
||||
<prompt phrase="Você está a ponto de associar este telefone à sua conta..." filename="ivr-you_are_about_to_provision_this_phone.wav"/>
|
||||
<prompt phrase="Por favor marque novamente o seu número PIN para confirmar." filename="ivr-please_reenter_your_pin.wav"/>
|
||||
<prompt phrase="Para registar em ClueCon, por favor marque..." filename="ivr-register_for_cluecon.wav"/>
|
||||
<prompt phrase="Para conectar..." filename="ivr-to_log_in.wav"/>
|
||||
<prompt phrase="Para desconectar..." filename="ivr-to_log_out.wav"/>
|
||||
<prompt phrase="Você está agora conectado." filename="ivr-you_are_now_logged_in.wav"/>
|
||||
<prompt phrase="Você está agora desconectado." filename="ivr-you_are_now_logged_out.wav"/>
|
||||
<prompt phrase="Por favor tente novamente." filename="ivr-please_try_again.wav"/>
|
||||
<prompt phrase="Você está a ponto de associar permanentemente este telefone à sua extensão." filename="ivr-provision_phone_permanently_to_extension.wav"/>
|
||||
<prompt phrase="Por favor marque o número da extensão à qual pretende associar este telefone, seguido de cardinal." filename="ivr-extension_to_provision_this_phone.wav"/>
|
||||
<prompt phrase="Obrigado, este telefone irá agora ser reiniciado." filename="ivr-this_phone_will_now_reboot.wav"/>
|
||||
<prompt phrase="Obrigado. A sua gravação foi guardada." filename="ivr-recording_saved.wav"/>
|
||||
<prompt phrase="Marque 1 para guardar a sua gravação. Marque 2 para ouvir a sua gravação. Marque 3 para gravar novamente." filename="ivr-save_review_record.wav"/>
|
||||
<prompt phrase="Neste momento o sistema é incapaz de guardar o seu ficheiro de som. Por favor tente novamente mais tarde." filename="ivr-unable_save.wav"/>
|
||||
<prompt phrase="Você é o número" filename="ivr-you_are_number.wav"/>
|
||||
<prompt phrase="...em linha" filename="ivr-in_line.wav"/>
|
||||
<prompt phrase="Obrigado por aguardar." filename="ivr-thank_you_for_holding.wav"/>
|
||||
<prompt phrase="O seu tempo estimado de espera é..." filename="ivr-estimated_hold_time.wav"/>
|
||||
<prompt phrase="Mais de..." filename="ivr-more_than.wav"/>
|
||||
<prompt phrase="Menos de..." filename="ivr-less_than.wav"/>
|
||||
<prompt phrase="Iniciar gravação." filename="ivr-begin_recording.wav "/>
|
||||
<prompt phrase="O encaminhamento da chamada foi cancelado." filename="ivr-call_forwarding_has_been_cancelled.wav"/>
|
||||
<prompt phrase="O encaminhamento da chamada foi activado." filename="ivr-call_forwarding_has_been_set.wav"/>
|
||||
<prompt phrase="Por favor, introduza o número de telefone." filename="ivr-please_enter_the_phone_number.wav"/>
|
||||
<prompt phrase="Por favor, deixe o seu nome e o motivo da sua chamada." filename="ivr-please_state_your_name_and_reason_for_calling.wav"/>
|
||||
<prompt phrase="Para aceitar, marque 1. Para rejeitar, marque 2. Para enviar para o correio de voz, marque 3." filename="ivr-accept_reject_voicemail.wav"/>
|
||||
<prompt phrase="Entrada de chamada." filename="ivr-incoming_call.wav"/>
|
||||
<prompt phrase="Obrigado pela sua chamada." filename="ivr-thank_you_for_calling.wav"/>
|
||||
<prompt phrase="Por favor permaneça em linha. A sua chamada será atendida brevemente." filename="ivr-stay_on_line_call_answered_momentarily.wav"/>
|
||||
<prompt phrase="A sua chamada está a ser transferida." filename="ivr-call_being_transferred.wav"/>
|
||||
<prompt phrase="Por favor, desfrute da música enquanto a sua chamada é transferida." filename="ivr-enjoy_music_while_transfer.wav"/>
|
||||
<prompt phrase="Você tem uma chamada de..." filename="ivr-call_from.wav"/>
|
||||
<prompt phrase="Este menú não tem opções. Por favor entre em contacto com o administrador." filename="ivr-no_menu_items.wav"/>
|
||||
<prompt phrase="Para directório, marque..." filename="ivr-for_directory_press.wav"/>
|
||||
<prompt phrase="Usando o teclado do seu telefone..." filename="ivr-using_telephone_keypad.wav"/>
|
||||
<prompt phrase="Introduza as primeiras letras do último nome da pessoa." filename="ivr-enter_letters_last_name.wav"/>
|
||||
<prompt phrase="Introduza as primeiras letras do primeiro nome da pessoa." filename="ivr-enter_letters_first_name.wav"/>
|
||||
<prompt phrase="Introduza as primeiras letras do primeiro ou último nome da pessoa." filename="ivr-enter_letters_first_or_last_name.wav"/>
|
||||
<prompt phrase="Se isto é correcto, marque..." filename="ivr-if_correct_press.wav"/>
|
||||
<prompt phrase="Se não, marque..." filename="ivr-if_not_press.wav"/>
|
||||
<prompt phrase="Quando terminar, marque cardinal." filename="ivr-finished_pound_hash_key.wav"/>
|
||||
<prompt phrase="O modo Não Incomodar está agora activado." filename="ivr-dnd_activated.wav"/>
|
||||
<prompt phrase="O modo Não Incomodar foi desactivado." filename="ivr-dnd_cancelled.wav"/>
|
||||
<prompt phrase="Marque qualquer outro dígito..." filename="ivr-any_other_digit.wav"/>
|
||||
<prompt phrase="Marque um para sim. Marque dois para não." filename="ivr-one_yes_two_no.wav"/>
|
||||
<prompt phrase="Por favor marque o número da fila, seguido de cardinal." filename="ivr-enter_queue_number.wav"/>
|
||||
<prompt phrase="Por favor marque o..." filename="ivr-please_enter_the.wav"/>
|
||||
<prompt phrase="Número." filename="ivr-number.wav"/>
|
||||
<prompt phrase="...seguido de cardinal." filename="ivr-followed_by_pound.wav"/>
|
||||
<prompt phrase="O saldo da conta é..." filename="ivr-account_balance_is.wav"/>
|
||||
<prompt phrase="Obrigado por telefonar. Se conhece a extensão do destinatário, por favor marque-a agora. Para ir para o directório, marque..." filename="ivr-generic_greeting.wav"/>
|
||||
<prompt phrase="...ficheiro..." filename="ivr-file.wav"/>
|
||||
<prompt phrase="...ficheiros..." filename="ivr-files-.wav"/>
|
||||
<prompt phrase="Para uma chamada de despertar..." filename="ivr-for_a_wakeup_call.wav"/>
|
||||
<prompt phrase="Esta é a sua chamada de despertar." filename="ivr-this_is_your_wakeup_call.wav"/>
|
||||
<prompt phrase="Para solicitar uma chamada de despertar..." filename="ivr-request_wakeup_call.wav"/>
|
||||
<prompt phrase="Para confirmar uma chamada de despertar..." filename="ivr-confirm_wakeup_call.wav"/>
|
||||
<prompt phrase="Para cancelar uma chamada de despertar..." filename="ivr-cancel_wakeup_call.wav"/>
|
||||
<prompt phrase="Você solicitou uma chamada de despertar..." filename="ivr-requested_wakeup_call_for.wav"/>
|
||||
<prompt phrase="Você não solicitou uma chamada de despertar." filename="ivr-not_requested_wakeup_call.wav"/>
|
||||
<prompt phrase="A sua chamada de despertar foi cancelada." filename="ivr-wakeup_call_cancelled.wav"/>
|
||||
<prompt phrase="Para uma chamada de despertar por dia..." filename="ivr-for_daily_wakeup_call.wav"/>
|
||||
<prompt phrase="Chamada de despertar diária..." filename="ivr-daily_wakeup_call.wav"/>
|
||||
<prompt phrase="Para chamadas de despertar diárias..." filename="ivr-for_daily_wakeup_calls.wav"/>
|
||||
<prompt phrase="Para apenas uma chamada de despertar..." filename="ivr-for_one_time_wakeup_call.wav"/>
|
||||
<prompt phrase="Apenas uma chamada de despertar..." filename="ivr-one_time_wakeup_call.wav"/>
|
||||
<prompt phrase="...chamada de despertar..." filename="ivr-wakeup_call.wav"/>
|
||||
<prompt phrase="Acorda! Acorda raio de sol!!" filename="ivr-wakey_wakey_sunshine.wav"/>
|
||||
<prompt phrase="Bem-vindo." filename="ivr-welcome.wav"/>
|
||||
<prompt phrase="Bem-vindo a..." filename="ivr-welcome_to.wav"/>
|
||||
<prompt phrase="Bom dia." filename="ivr-good_morning.wav"/>
|
||||
<prompt phrase="Boa tarde." filename="ivr-good_afternoon.wav"/>
|
||||
<prompt phrase="Boa noite." filename="ivr-good_evening.wav"/>
|
||||
<prompt phrase="Obrigado." filename="ivr-Thank_you.wav"/>
|
||||
<prompt phrase="Para..." filename="ivr-for.wav"/>
|
||||
<prompt phrase="Estamos a observar tempos de espera superiores ao normal." filename="ivr-longer_than_usual_hold_times.wav"/>
|
||||
<prompt phrase="Você é o..." filename="ivr-you_are_the.wav"/>
|
||||
<prompt phrase="Um momento por favor." filename="ivr-one_moment_please.wav"/>
|
||||
<prompt phrase="A sua chamada será atendida pela ordem que foi recebida." filename="ivr-call_answered_order_received.wav"/>
|
||||
<prompt phrase="Por favor marque o número da conferência, seguido de cardinal" filename="conf-enter_conf_number.wav"/>
|
||||
<prompt phrase="Introduza o número PIN da conferência, seguido de cardinal." filename="conf-enter_conf_pin.wav"/>
|
||||
<prompt phrase="...entrou na conferência." filename="conf-has_joined.wav"/>
|
||||
<prompt phrase="...abandonou a conferência." filename="conf-has_left.wav"/>
|
||||
<prompt phrase="Você entrou..." filename="ivr-you_entered.wav"/>
|
||||
<prompt phrase="Número da extensão..." filename="ivr-extension_number.wav"/>
|
||||
<prompt phrase="Por favor aguarde enquanto contactamos com o destinatário." filename="ivr-please_hold_while_party_contacted.wav"/>
|
||||
<prompt phrase="Por favor desfrute da música enquanto contactamos com o destinatário." filename="ivr-please_enjoy_music_while_party_reached.wav"/>
|
||||
<prompt phrase="Obrigado por telefonar. Se conhece a extensão do destinatário, marque-a agora, ou marque nove para ir para o directório." filename="ivr-generic_greeting.wav"/>
|
||||
<prompt phrase="Se isto é correcto, marque 1. Se não é correcto, marque 2." filename="ivr-if_correct_one_if_not_two.wav"/>
|
||||
<prompt phrase="Para ouvir novamente esta informação.." filename="ivr-repeat_this_information.wav"/>
|
||||
<prompt phrase="Não não não!" filename="ivr-no_no_no.wav"/>
|
||||
<prompt phrase="Você pretendia marcar esta tecla?" filename="ivr-did_you_mean_to_press_key.wav"/>
|
||||
<prompt phrase="A sério? Pretendia MESMO marcar esta tecla?" filename="ivr-seriously_mean_to_press_key.wav"/>
|
||||
<prompt phrase="Oh, tanto faz." filename="ivr-oh_whatever.wav"/>
|
||||
<prompt phrase="Já chega! Um erro mais e desligo a chamada." filename="ivr-one_more_mistake.wav"/>
|
||||
<prompt phrase="Felicidades, você pressionou estrela. Isto não significa que você é uma estrela. Apenas significa que pode pressionar teclas e que provavelmente tem dedos." filename="ivr-congratulations_you_pressed_star.wav"/>
|
||||
<prompt phrase="Todos os nossos engenheiros estão ocupados demonstrando como é impressionante CudaTel." filename="ivr-engineers_busy_assisting_other_sales.wav"/>
|
||||
<prompt phrase="O destino que deseja contactar não está disponível e não tem correio de voz." filename="vm-not_available_no_voicemail.wav"/>
|
||||
<prompt phrase="Esta mensagem vai autodestruir-se em 5, 4, 3, 2, 1..." filename="ivr-message_self_destruct.wav"/>
|
||||
<prompt phrase="Você já está em silêncio." filename="conf-you_are_already_muted.wav"/>
|
||||
<prompt phrase="Você está agora em silêncio em ambos sentidos." filename="conf-you_are_now_bidirectionally_muted.wav"/>
|
||||
<prompt phrase="Todas as suas chamadas pertencem-nos." filename="ivr-all_your_call_are_belong_to_us.wav"/>
|
||||
<prompt phrase="Adoro a forma como você pressiona as teclas!" filename="ivr-love_those_touch_tones.wav"/>
|
||||
<prompt phrase="Sim, nós não temos bananas." filename="ivr-yes_we_have_no_bananas.wav"/>
|
||||
<prompt phrase="Homem, você está a ser ridículo!" filename="ivr-dude_you_suck.wav"/>
|
||||
<prompt phrase="A sua chamada é muito importante para nós, mas a sua saúde mental não, então estamos felizes por mantê-lo em espera, torturando-o com a irritante música em espera." filename="ivr-on_hold_indefinitely.wav"/>
|
||||
<prompt phrase="...deixou o edifício." filename="ivr-has_left_the_building.wav"/>
|
||||
<prompt phrase="Este telefone não está associado e não pode realizar chamadas externas." filename="ivr-phone_is_unassigned.wav"/>
|
||||
<prompt phrase="Este telefone não está configurado correctamente." filename="ivr-phone_not_configured.wav"/>
|
||||
<prompt phrase="Parabéns! Este telefone está configurado correctamente e pode agora ser associado a um utilizador." filename="ivr-phone_is_configured_properly.wav"/>
|
||||
<prompt phrase="Por favor contacte o administrador do sistema para assistência." filename="ivr-contact_system_administrator.wav"/>
|
||||
<prompt phrase="Barracuda Networks" filename="ivr-barracuda_networks.wav"/>
|
||||
<prompt phrase="CudaTel Communication Server" filename="ivr-cudatel_communication_server.wav"/>
|
||||
<prompt phrase="Por favor, introduza as primeiras letras do primeiro ou último nome da pessoa" filename="dir-enter_person_first_or_last.wav"/>
|
||||
<prompt phrase="Não há mais chamadas á espera nesta fila." filename="ivr-no_calls_waiting_in_queue.wav"/>
|
||||
<prompt phrase="Brian West" filename="misc-Brian_West.wav"/>
|
||||
<prompt phrase="Anthony Minessale" filename="misc-Anthony_Minessale.wav"/>
|
||||
<prompt phrase="Michael Jerris" filename="misc-Michael_Jerris.wav"/>
|
||||
<prompt phrase="Raymond Chandler" filename="misc-Raymond_Chandler.wav"/>
|
||||
<prompt phrase="Michael Collins" filename="misc-Michael_Collins.wav"/>
|
||||
<prompt phrase="Mark Mann" filename="misc-Mark_Mann.wav"/>
|
||||
<prompt phrase="William King" filename="misc-William_King.wav"/>
|
||||
<prompt phrase="Rudy Fleminger" filename="misc-Rudy_Fleminger.wav"/>
|
||||
<prompt phrase="Andrew Thompson" filename="misc-Andrew_Thompson.wav"/>
|
||||
<prompt phrase="Graham Saathoff" filename="misc-Graham_Saathoff.wav"/>
|
||||
<prompt phrase="Nicholaus Belluni" filename="misc-Nicholaus_Belluni.wav"/>
|
||||
<prompt phrase="Sean Heiney" filename="misc-Sean_Heiney.wav"/>
|
||||
</ivr>
|
||||
<misc>
|
||||
<prompt phrase="Foi activada a segurança para esta chamada." filename="call_secured.wav"/>
|
||||
<prompt phrase="...seguido de cardinal." filename="followed.wav"/>
|
||||
<prompt phrase="Se você é esta pessoa..." filename="if_you_are_this_person.wav"/>
|
||||
<prompt phrase="Se você deseja..." filename="if_you_would_like_to.wav"/>
|
||||
<prompt phrase="Forneça o número de referência" filename="provide_reference_number.wav"/>
|
||||
<prompt phrase="Por favor, introduza a extensão para a qual pretende transferir." filename="transfer1.wav"/>
|
||||
<prompt phrase="Transferir" filename="transfer2.wav"/>
|
||||
<prompt phrase="Estamos a tentar contactar..." filename="we_are_trying_to_reach.wav"/>
|
||||
<prompt phrase="Ocorreu um erro, por favor entre em contacto com o administrador." filename="error.wav"/>
|
||||
<prompt phrase="A sua chamada irá terminar em..." filename="misc-your_call_will_be_terminated_in.wav"/>
|
||||
<prompt phrase="A sua chamada foi concluída." filename="misc-your_call_has_been_terminated.wav"/>
|
||||
</misc>
|
||||
<zrtp>
|
||||
<!-- base256 prompts for SAS -->
|
||||
<prompt phrase="Algol" filename="Algol.wav"/>
|
||||
<prompt phrase="Apollo" filename="Apollo.wav"/>
|
||||
<prompt phrase="Athens" filename="Athens.wav"/>
|
||||
<prompt phrase="Atlantic" filename="Atlantic.wav"/>
|
||||
<prompt phrase="Aztec" filename="Aztec.wav"/>
|
||||
<prompt phrase="Babylon" filename="Babylon.wav"/>
|
||||
<prompt phrase="Belfast" filename="Belfast.wav"/>
|
||||
<prompt phrase="Bradbury" filename="Bradbury.wav"/>
|
||||
<prompt phrase="Brazilian" filename="Brazilian.wav"/>
|
||||
<prompt phrase="Burbank" filename="Burbank.wav"/>
|
||||
<prompt phrase="Burlington" filename="Burlington.wav"/>
|
||||
<prompt phrase="Camelot" filename="Camelot.wav"/>
|
||||
<prompt phrase="Capricorn" filename="Capricorn.wav"/>
|
||||
<prompt phrase="Cherokee" filename="Cherokee.wav"/>
|
||||
<prompt phrase="Chicago" filename="Chicago.wav"/>
|
||||
<prompt phrase="Christmas" filename="Christmas.wav"/>
|
||||
<prompt phrase="Dakota" filename="Dakota.wav"/>
|
||||
<prompt phrase="December" filename="December.wav"/>
|
||||
<prompt phrase="Dupont" filename="Dupont.wav"/>
|
||||
<prompt phrase="Eskimo" filename="Eskimo.wav"/>
|
||||
<prompt phrase="Galveston" filename="Galveston.wav"/>
|
||||
<prompt phrase="Geiger" filename="Geiger.wav"/>
|
||||
<prompt phrase="Hamilton" filename="Hamilton.wav"/>
|
||||
<prompt phrase="Istanbul" filename="Istanbul.wav"/>
|
||||
<prompt phrase="Jamaica" filename="Jamaica.wav"/>
|
||||
<prompt phrase="Jupiter" filename="Jupiter.wav"/>
|
||||
<prompt phrase="Medusa" filename="Medusa.wav"/>
|
||||
<prompt phrase="Mohawk" filename="Mohawk.wav"/>
|
||||
<prompt phrase="Montana" filename="Montana.wav"/>
|
||||
<prompt phrase="Neptune" filename="Neptune.wav"/>
|
||||
<prompt phrase="Norwegian" filename="Norwegian.wav"/>
|
||||
<prompt phrase="Oakland" filename="Oakland.wav"/>
|
||||
<prompt phrase="October" filename="October.wav"/>
|
||||
<prompt phrase="Ohio" filename="Ohio.wav"/>
|
||||
<prompt phrase="Orlando" filename="Orlando.wav"/>
|
||||
<prompt phrase="Pacific" filename="Pacific.wav"/>
|
||||
<prompt phrase="Pandora" filename="Pandora.wav"/>
|
||||
<prompt phrase="Pegasus" filename="Pegasus.wav"/>
|
||||
<prompt phrase="Pluto" filename="Pluto.wav"/>
|
||||
<prompt phrase="Saturday" filename="Saturday.wav"/>
|
||||
<prompt phrase="Scotland" filename="Scotland.wav"/>
|
||||
<prompt phrase="Trojan" filename="Trojan.wav"/>
|
||||
<prompt phrase="Virginia" filename="Virginia.wav"/>
|
||||
<prompt phrase="Vulcan" filename="Vulcan.wav"/>
|
||||
<prompt phrase="Waterloo" filename="Waterloo.wav"/>
|
||||
<prompt phrase="Wichita" filename="Wichita.wav"/>
|
||||
<prompt phrase="Wilmington" filename="Wilmington.wav"/>
|
||||
<prompt phrase="Wyoming" filename="Wyoming.wav"/>
|
||||
<prompt phrase="Yucatan" filename="Yucatan.wav"/>
|
||||
<prompt phrase="Zulu" filename="Zulu.wav"/>
|
||||
<prompt phrase="aardvark" filename="aardvark.wav"/>
|
||||
<prompt phrase="absurd" filename="absurd.wav"/>
|
||||
<prompt phrase="accrue" filename="accrue.wav"/>
|
||||
<prompt phrase="acme" filename="acme.wav"/>
|
||||
<prompt phrase="adrift" filename="adrift.wav"/>
|
||||
<prompt phrase="adroitness" filename="adroitness.wav"/>
|
||||
<prompt phrase="adult" filename="adult.wav"/>
|
||||
<prompt phrase="adviser" filename="adviser.wav"/>
|
||||
<prompt phrase="afflict" filename="afflict.wav"/>
|
||||
<prompt phrase="aftermath" filename="aftermath.wav"/>
|
||||
<prompt phrase="aggregate" filename="aggregate.wav"/>
|
||||
<prompt phrase="ahead" filename="ahead.wav"/>
|
||||
<prompt phrase="aimless" filename="aimless.wav"/>
|
||||
<prompt phrase="alkali" filename="alkali.wav"/>
|
||||
<prompt phrase="allow" filename="allow.wav"/>
|
||||
<prompt phrase="almighty" filename="almighty.wav"/>
|
||||
<prompt phrase="alone" filename="alone.wav"/>
|
||||
<prompt phrase="ammo" filename="ammo.wav"/>
|
||||
<prompt phrase="amulet" filename="amulet.wav"/>
|
||||
<prompt phrase="amusement" filename="amusement.wav"/>
|
||||
<prompt phrase="ancient" filename="ancient.wav"/>
|
||||
<prompt phrase="antenna" filename="antenna.wav"/>
|
||||
<prompt phrase="apple" filename="apple.wav"/>
|
||||
<prompt phrase="applicant" filename="applicant.wav"/>
|
||||
<prompt phrase="armistice" filename="armistice.wav"/>
|
||||
<prompt phrase="article" filename="article.wav"/>
|
||||
<prompt phrase="artist" filename="artist.wav"/>
|
||||
<prompt phrase="assume" filename="assume.wav"/>
|
||||
<prompt phrase="asteroid" filename="asteroid.wav"/>
|
||||
<prompt phrase="atlas" filename="atlas.wav"/>
|
||||
<prompt phrase="atmosphere" filename="atmosphere.wav"/>
|
||||
<prompt phrase="autopsy" filename="autopsy.wav"/>
|
||||
<prompt phrase="baboon" filename="baboon.wav"/>
|
||||
<prompt phrase="backfield" filename="backfield.wav"/>
|
||||
<prompt phrase="backward" filename="backward.wav"/>
|
||||
<prompt phrase="backwater" filename="backwater.wav"/>
|
||||
<prompt phrase="banjo" filename="banjo.wav"/>
|
||||
<prompt phrase="barbecue" filename="barbecue.wav"/>
|
||||
<prompt phrase="beaming" filename="beaming.wav"/>
|
||||
<prompt phrase="bedlamp" filename="bedlamp.wav"/>
|
||||
<prompt phrase="beehive" filename="beehive.wav"/>
|
||||
<prompt phrase="beeswax" filename="beeswax.wav"/>
|
||||
<prompt phrase="befriend" filename="befriend.wav"/>
|
||||
<prompt phrase="belowground" filename="belowground.wav"/>
|
||||
<prompt phrase="berserk" filename="berserk.wav"/>
|
||||
<prompt phrase="bifocals" filename="bifocals.wav"/>
|
||||
<prompt phrase="billiard" filename="billiard.wav"/>
|
||||
<prompt phrase="bison" filename="bison.wav"/>
|
||||
<prompt phrase="blackjack" filename="blackjack.wav"/>
|
||||
<prompt phrase="blockade" filename="blockade.wav"/>
|
||||
<prompt phrase="blowtorch" filename="blowtorch.wav"/>
|
||||
<prompt phrase="bluebird" filename="bluebird.wav"/>
|
||||
<prompt phrase="bodyguard" filename="bodyguard.wav"/>
|
||||
<prompt phrase="bombast" filename="bombast.wav"/>
|
||||
<prompt phrase="bookseller" filename="bookseller.wav"/>
|
||||
<prompt phrase="bookshelf" filename="bookshelf.wav"/>
|
||||
<prompt phrase="borderline" filename="borderline.wav"/>
|
||||
<prompt phrase="bottomless" filename="bottomless.wav"/>
|
||||
<prompt phrase="brackish" filename="brackish.wav"/>
|
||||
<prompt phrase="bravado" filename="bravado.wav"/>
|
||||
<prompt phrase="breadline" filename="breadline.wav"/>
|
||||
<prompt phrase="breakaway" filename="breakaway.wav"/>
|
||||
<prompt phrase="breakup" filename="breakup.wav"/>
|
||||
<prompt phrase="brickyard" filename="brickyard.wav"/>
|
||||
<prompt phrase="briefcase" filename="briefcase.wav"/>
|
||||
<prompt phrase="businessman" filename="businessman.wav"/>
|
||||
<prompt phrase="butterfat" filename="butterfat.wav"/>
|
||||
<prompt phrase="button" filename="button.wav"/>
|
||||
<prompt phrase="buzzard" filename="buzzard.wav"/>
|
||||
<prompt phrase="candidate" filename="candidate.wav"/>
|
||||
<prompt phrase="cannonball" filename="cannonball.wav"/>
|
||||
<prompt phrase="caravan" filename="caravan.wav"/>
|
||||
<prompt phrase="caretaker" filename="caretaker.wav"/>
|
||||
<prompt phrase="celebrate" filename="celebrate.wav"/>
|
||||
<prompt phrase="cellulose" filename="cellulose.wav"/>
|
||||
<prompt phrase="cement" filename="cement.wav"/>
|
||||
<prompt phrase="certify" filename="certify.wav"/>
|
||||
<prompt phrase="chairlift" filename="chairlift.wav"/>
|
||||
<prompt phrase="chambermaid" filename="chambermaid.wav"/>
|
||||
<prompt phrase="chatter" filename="chatter.wav"/>
|
||||
<prompt phrase="checkup" filename="checkup.wav"/>
|
||||
<prompt phrase="chisel" filename="chisel.wav"/>
|
||||
<prompt phrase="choking" filename="choking.wav"/>
|
||||
<prompt phrase="chopper" filename="chopper.wav"/>
|
||||
<prompt phrase="clamshell" filename="clamshell.wav"/>
|
||||
<prompt phrase="classic" filename="classic.wav"/>
|
||||
<prompt phrase="classroom" filename="classroom.wav"/>
|
||||
<prompt phrase="cleanup" filename="cleanup.wav"/>
|
||||
<prompt phrase="clergyman" filename="clergyman.wav"/>
|
||||
<prompt phrase="clockwork" filename="clockwork.wav"/>
|
||||
<prompt phrase="cobra" filename="cobra.wav"/>
|
||||
<prompt phrase="coherence" filename="coherence.wav"/>
|
||||
<prompt phrase="combustion" filename="combustion.wav"/>
|
||||
<prompt phrase="commando" filename="commando.wav"/>
|
||||
<prompt phrase="commence" filename="commence.wav"/>
|
||||
<prompt phrase="company" filename="company.wav"/>
|
||||
<prompt phrase="component" filename="component.wav"/>
|
||||
<prompt phrase="concert" filename="concert.wav"/>
|
||||
<prompt phrase="concurrent" filename="concurrent.wav"/>
|
||||
<prompt phrase="confidence" filename="confidence.wav"/>
|
||||
<prompt phrase="conformist" filename="conformist.wav"/>
|
||||
<prompt phrase="congregate" filename="congregate.wav"/>
|
||||
<prompt phrase="consensus" filename="consensus.wav"/>
|
||||
<prompt phrase="consulting" filename="consulting.wav"/>
|
||||
<prompt phrase="corporate" filename="corporate.wav"/>
|
||||
<prompt phrase="corrosion" filename="corrosion.wav"/>
|
||||
<prompt phrase="councilman" filename="councilman.wav"/>
|
||||
<prompt phrase="cowbell" filename="cowbell.wav"/>
|
||||
<prompt phrase="crackdown" filename="crackdown.wav"/>
|
||||
<prompt phrase="cranky" filename="cranky.wav"/>
|
||||
<prompt phrase="crossover" filename="crossover.wav"/>
|
||||
<prompt phrase="crowfoot" filename="crowfoot.wav"/>
|
||||
<prompt phrase="crucial" filename="crucial.wav"/>
|
||||
<prompt phrase="crucifix" filename="crucifix.wav"/>
|
||||
<prompt phrase="crumpled" filename="crumpled.wav"/>
|
||||
<prompt phrase="crusade" filename="crusade.wav"/>
|
||||
<prompt phrase="cubic" filename="cubic.wav"/>
|
||||
<prompt phrase="cumbersome" filename="cumbersome.wav"/>
|
||||
<prompt phrase="customer" filename="customer.wav"/>
|
||||
<prompt phrase="dashboard" filename="dashboard.wav"/>
|
||||
<prompt phrase="deadbolt" filename="deadbolt.wav"/>
|
||||
<prompt phrase="decadence" filename="decadence.wav"/>
|
||||
<prompt phrase="decimal" filename="decimal.wav"/>
|
||||
<prompt phrase="deckhand" filename="deckhand.wav"/>
|
||||
<prompt phrase="designing" filename="designing.wav"/>
|
||||
<prompt phrase="detector" filename="detector.wav"/>
|
||||
<prompt phrase="detergent" filename="detergent.wav"/>
|
||||
<prompt phrase="determine" filename="determine.wav"/>
|
||||
<prompt phrase="dictator" filename="dictator.wav"/>
|
||||
<prompt phrase="dinosaur" filename="dinosaur.wav"/>
|
||||
<prompt phrase="direction" filename="direction.wav"/>
|
||||
<prompt phrase="disable" filename="disable.wav"/>
|
||||
<prompt phrase="disbelief" filename="disbelief.wav"/>
|
||||
<prompt phrase="disruptive" filename="disruptive.wav"/>
|
||||
<prompt phrase="distortion" filename="distortion.wav"/>
|
||||
<prompt phrase="document" filename="document.wav"/>
|
||||
<prompt phrase="dogsled" filename="dogsled.wav"/>
|
||||
<prompt phrase="dragnet" filename="dragnet.wav"/>
|
||||
<prompt phrase="drainage" filename="drainage.wav"/>
|
||||
<prompt phrase="dreadful" filename="dreadful.wav"/>
|
||||
<prompt phrase="drifter" filename="drifter.wav"/>
|
||||
<prompt phrase="dropper" filename="dropper.wav"/>
|
||||
<prompt phrase="drumbeat" filename="drumbeat.wav"/>
|
||||
<prompt phrase="drunken" filename="drunken.wav"/>
|
||||
<prompt phrase="dwelling" filename="dwelling.wav"/>
|
||||
<prompt phrase="eating" filename="eating.wav"/>
|
||||
<prompt phrase="edict" filename="edict.wav"/>
|
||||
<prompt phrase="egghead" filename="egghead.wav"/>
|
||||
<prompt phrase="eightball" filename="eightball.wav"/>
|
||||
<prompt phrase="embezzle" filename="embezzle.wav"/>
|
||||
<prompt phrase="enchanting" filename="enchanting.wav"/>
|
||||
<prompt phrase="endorse" filename="endorse.wav"/>
|
||||
<prompt phrase="endow" filename="endow.wav"/>
|
||||
<prompt phrase="enlist" filename="enlist.wav"/>
|
||||
<prompt phrase="enrollment" filename="enrollment.wav"/>
|
||||
<prompt phrase="enterprise" filename="enterprise.wav"/>
|
||||
<prompt phrase="equation" filename="equation.wav"/>
|
||||
<prompt phrase="equipment" filename="equipment.wav"/>
|
||||
<prompt phrase="erase" filename="erase.wav"/>
|
||||
<prompt phrase="escapade" filename="escapade.wav"/>
|
||||
<prompt phrase="escape" filename="escape.wav"/>
|
||||
<prompt phrase="everyday" filename="everyday.wav"/>
|
||||
<prompt phrase="examine" filename="examine.wav"/>
|
||||
<prompt phrase="exceed" filename="exceed.wav"/>
|
||||
<prompt phrase="existence" filename="existence.wav"/>
|
||||
<prompt phrase="exodus" filename="exodus.wav"/>
|
||||
<prompt phrase="eyeglass" filename="eyeglass.wav"/>
|
||||
<prompt phrase="eyetooth" filename="eyetooth.wav"/>
|
||||
<prompt phrase="facial" filename="facial.wav"/>
|
||||
<prompt phrase="fallout" filename="fallout.wav"/>
|
||||
<prompt phrase="fascinate" filename="fascinate.wav"/>
|
||||
<prompt phrase="filament" filename="filament.wav"/>
|
||||
<prompt phrase="finicky" filename="finicky.wav"/>
|
||||
<prompt phrase="flagpole" filename="flagpole.wav"/>
|
||||
<prompt phrase="flatfoot" filename="flatfoot.wav"/>
|
||||
<prompt phrase="flytrap" filename="flytrap.wav"/>
|
||||
<prompt phrase="forever" filename="forever.wav"/>
|
||||
<prompt phrase="fortitude" filename="fortitude.wav"/>
|
||||
<prompt phrase="fracture" filename="fracture.wav"/>
|
||||
<prompt phrase="framework" filename="framework.wav"/>
|
||||
<prompt phrase="freedom" filename="freedom.wav"/>
|
||||
<prompt phrase="frequency" filename="frequency.wav"/>
|
||||
<prompt phrase="frighten" filename="frighten.wav"/>
|
||||
<prompt phrase="gadgetry" filename="gadgetry.wav"/>
|
||||
<prompt phrase="gazelle" filename="gazelle.wav"/>
|
||||
<prompt phrase="getaway" filename="getaway.wav"/>
|
||||
<prompt phrase="glitter" filename="glitter.wav"/>
|
||||
<prompt phrase="glossary" filename="glossary.wav"/>
|
||||
<prompt phrase="glucose" filename="glucose.wav"/>
|
||||
<prompt phrase="goggles" filename="goggles.wav"/>
|
||||
<prompt phrase="goldfish" filename="goldfish.wav"/>
|
||||
<prompt phrase="gossamer" filename="gossamer.wav"/>
|
||||
<prompt phrase="graduate" filename="graduate.wav"/>
|
||||
<prompt phrase="gravity" filename="gravity.wav"/>
|
||||
<prompt phrase="gremlin" filename="gremlin.wav"/>
|
||||
<prompt phrase="guidance" filename="guidance.wav"/>
|
||||
<prompt phrase="guitarist" filename="guitarist.wav"/>
|
||||
<prompt phrase="hamburger" filename="hamburger.wav"/>
|
||||
<prompt phrase="hamlet" filename="hamlet.wav"/>
|
||||
<prompt phrase="handiwork" filename="handiwork.wav"/>
|
||||
<prompt phrase="hazardous" filename="hazardous.wav"/>
|
||||
<prompt phrase="headwaters" filename="headwaters.wav"/>
|
||||
<prompt phrase="hemisphere" filename="hemisphere.wav"/>
|
||||
<prompt phrase="hesitate" filename="hesitate.wav"/>
|
||||
<prompt phrase="hideaway" filename="hideaway.wav"/>
|
||||
<prompt phrase="highchair" filename="highchair.wav"/>
|
||||
<prompt phrase="hockey" filename="hockey.wav"/>
|
||||
<prompt phrase="holiness" filename="holiness.wav"/>
|
||||
<prompt phrase="hurricane" filename="hurricane.wav"/>
|
||||
<prompt phrase="hydraulic" filename="hydraulic.wav"/>
|
||||
<prompt phrase="impartial" filename="impartial.wav"/>
|
||||
<prompt phrase="impetus" filename="impetus.wav"/>
|
||||
<prompt phrase="inception" filename="inception.wav"/>
|
||||
<prompt phrase="indigo" filename="indigo.wav"/>
|
||||
<prompt phrase="indoors" filename="indoors.wav"/>
|
||||
<prompt phrase="indulge" filename="indulge.wav"/>
|
||||
<prompt phrase="inertia" filename="inertia.wav"/>
|
||||
<prompt phrase="infancy" filename="infancy.wav"/>
|
||||
<prompt phrase="inferno" filename="inferno.wav"/>
|
||||
<prompt phrase="informant" filename="informant.wav"/>
|
||||
<prompt phrase="insincere" filename="insincere.wav"/>
|
||||
<prompt phrase="insurgent" filename="insurgent.wav"/>
|
||||
<prompt phrase="integrate" filename="integrate.wav"/>
|
||||
<prompt phrase="intention" filename="intention.wav"/>
|
||||
<prompt phrase="inventive" filename="inventive.wav"/>
|
||||
<prompt phrase="inverse" filename="inverse.wav"/>
|
||||
<prompt phrase="involve" filename="involve.wav"/>
|
||||
<prompt phrase="island" filename="island.wav"/>
|
||||
<prompt phrase="jawbone" filename="jawbone.wav"/>
|
||||
<prompt phrase="keyboard" filename="keyboard.wav"/>
|
||||
<prompt phrase="kickoff" filename="kickoff.wav"/>
|
||||
<prompt phrase="kiwi" filename="kiwi.wav"/>
|
||||
<prompt phrase="klaxon" filename="klaxon.wav"/>
|
||||
<prompt phrase="leprosy" filename="leprosy.wav"/>
|
||||
<prompt phrase="letterhead" filename="letterhead.wav"/>
|
||||
<prompt phrase="liberty" filename="liberty.wav"/>
|
||||
<prompt phrase="locale" filename="locale.wav"/>
|
||||
<prompt phrase="lockup" filename="lockup.wav"/>
|
||||
<prompt phrase="maritime" filename="maritime.wav"/>
|
||||
<prompt phrase="matchmaker" filename="matchmaker.wav"/>
|
||||
<prompt phrase="maverick" filename="maverick.wav"/>
|
||||
<prompt phrase="megaton" filename="megaton.wav"/>
|
||||
<prompt phrase="merit" filename="merit.wav"/>
|
||||
<prompt phrase="microscope" filename="microscope.wav"/>
|
||||
<prompt phrase="microwave" filename="microwave.wav"/>
|
||||
<prompt phrase="midsummer" filename="midsummer.wav"/>
|
||||
<prompt phrase="millionaire" filename="millionaire.wav"/>
|
||||
<prompt phrase="minnow" filename="minnow.wav"/>
|
||||
<prompt phrase="miracle" filename="miracle.wav"/>
|
||||
<prompt phrase="miser" filename="miser.wav"/>
|
||||
<prompt phrase="misnomer" filename="misnomer.wav"/>
|
||||
<prompt phrase="molasses" filename="molasses.wav"/>
|
||||
<prompt phrase="molecule" filename="molecule.wav"/>
|
||||
<prompt phrase="monument" filename="monument.wav"/>
|
||||
<prompt phrase="mosquito" filename="mosquito.wav"/>
|
||||
<prompt phrase="mural" filename="mural.wav"/>
|
||||
<prompt phrase="music" filename="music.wav"/>
|
||||
<prompt phrase="narrative" filename="narrative.wav"/>
|
||||
<prompt phrase="nebula" filename="nebula.wav"/>
|
||||
<prompt phrase="necklace" filename="necklace.wav"/>
|
||||
<prompt phrase="newborn" filename="newborn.wav"/>
|
||||
<prompt phrase="newsletter" filename="newsletter.wav"/>
|
||||
<prompt phrase="nightbird" filename="nightbird.wav"/>
|
||||
<prompt phrase="obtuse" filename="obtuse.wav"/>
|
||||
<prompt phrase="offload" filename="offload.wav"/>
|
||||
<prompt phrase="onlooker" filename="onlooker.wav"/>
|
||||
<prompt phrase="optic" filename="optic.wav"/>
|
||||
<prompt phrase="opulent" filename="opulent.wav"/>
|
||||
<prompt phrase="orca" filename="orca.wav"/>
|
||||
<prompt phrase="outfielder" filename="outfielder.wav"/>
|
||||
<prompt phrase="pandemic" filename="pandemic.wav"/>
|
||||
<prompt phrase="paperweight" filename="paperweight.wav"/>
|
||||
<prompt phrase="paragon" filename="paragon.wav"/>
|
||||
<prompt phrase="paragraph" filename="paragraph.wav"/>
|
||||
<prompt phrase="paramount" filename="paramount.wav"/>
|
||||
<prompt phrase="passenger" filename="passenger.wav"/>
|
||||
<prompt phrase="payday" filename="payday.wav"/>
|
||||
<prompt phrase="peachy" filename="peachy.wav"/>
|
||||
<prompt phrase="pedigree" filename="pedigree.wav"/>
|
||||
<prompt phrase="penetrate" filename="penetrate.wav"/>
|
||||
<prompt phrase="perceptive" filename="perceptive.wav"/>
|
||||
<prompt phrase="performance" filename="performance.wav"/>
|
||||
<prompt phrase="pharmacy" filename="pharmacy.wav"/>
|
||||
<prompt phrase="pheasant" filename="pheasant.wav"/>
|
||||
<prompt phrase="phonetic" filename="phonetic.wav"/>
|
||||
<prompt phrase="photograph" filename="photograph.wav"/>
|
||||
<prompt phrase="physique" filename="physique.wav"/>
|
||||
<prompt phrase="pioneer" filename="pioneer.wav"/>
|
||||
<prompt phrase="playhouse" filename="playhouse.wav"/>
|
||||
<prompt phrase="pocketful" filename="pocketful.wav"/>
|
||||
<prompt phrase="politeness" filename="politeness.wav"/>
|
||||
<prompt phrase="positive" filename="positive.wav"/>
|
||||
<prompt phrase="potato" filename="potato.wav"/>
|
||||
<prompt phrase="preclude" filename="preclude.wav"/>
|
||||
<prompt phrase="prefer" filename="prefer.wav"/>
|
||||
<prompt phrase="preshrunk" filename="preshrunk.wav"/>
|
||||
<prompt phrase="printer" filename="printer.wav"/>
|
||||
<prompt phrase="processor" filename="processor.wav"/>
|
||||
<prompt phrase="provincial" filename="provincial.wav"/>
|
||||
<prompt phrase="prowler" filename="prowler.wav"/>
|
||||
<prompt phrase="proximate" filename="proximate.wav"/>
|
||||
<prompt phrase="puberty" filename="puberty.wav"/>
|
||||
<prompt phrase="publisher" filename="publisher.wav"/>
|
||||
<prompt phrase="pupil" filename="pupil.wav"/>
|
||||
<prompt phrase="puppy" filename="puppy.wav"/>
|
||||
<prompt phrase="pyramid" filename="pyramid.wav"/>
|
||||
<prompt phrase="python" filename="python.wav"/>
|
||||
<prompt phrase="quadrant" filename="quadrant.wav"/>
|
||||
<prompt phrase="quantity" filename="quantity.wav"/>
|
||||
<prompt phrase="quiver" filename="quiver.wav"/>
|
||||
<prompt phrase="quota" filename="quota.wav"/>
|
||||
<prompt phrase="racketeer" filename="racketeer.wav"/>
|
||||
<prompt phrase="ragtime" filename="ragtime.wav"/>
|
||||
<prompt phrase="ratchet" filename="ratchet.wav"/>
|
||||
<prompt phrase="rebellion" filename="rebellion.wav"/>
|
||||
<prompt phrase="rebirth" filename="rebirth.wav"/>
|
||||
<prompt phrase="recipe" filename="recipe.wav"/>
|
||||
<prompt phrase="recover" filename="recover.wav"/>
|
||||
<prompt phrase="reform" filename="reform.wav"/>
|
||||
<prompt phrase="regain" filename="regain.wav"/>
|
||||
<prompt phrase="reindeer" filename="reindeer.wav"/>
|
||||
<prompt phrase="rematch" filename="rematch.wav"/>
|
||||
<prompt phrase="repay" filename="repay.wav"/>
|
||||
<prompt phrase="repellent" filename="repellent.wav"/>
|
||||
<prompt phrase="replica" filename="replica.wav"/>
|
||||
<prompt phrase="reproduce" filename="reproduce.wav"/>
|
||||
<prompt phrase="resistor" filename="resistor.wav"/>
|
||||
<prompt phrase="responsive" filename="responsive.wav"/>
|
||||
<prompt phrase="retouch" filename="retouch.wav"/>
|
||||
<prompt phrase="retraction" filename="retraction.wav"/>
|
||||
<prompt phrase="retrieval" filename="retrieval.wav"/>
|
||||
<prompt phrase="retrospect" filename="retrospect.wav"/>
|
||||
<prompt phrase="revenge" filename="revenge.wav"/>
|
||||
<prompt phrase="revenue" filename="revenue.wav"/>
|
||||
<prompt phrase="revival" filename="revival.wav"/>
|
||||
<prompt phrase="revolver" filename="revolver.wav"/>
|
||||
<prompt phrase="reward" filename="reward.wav"/>
|
||||
<prompt phrase="rhythm" filename="rhythm.wav"/>
|
||||
<prompt phrase="ribcage" filename="ribcage.wav"/>
|
||||
<prompt phrase="ringbolt" filename="ringbolt.wav"/>
|
||||
<prompt phrase="robust" filename="robust.wav"/>
|
||||
<prompt phrase="rocker" filename="rocker.wav"/>
|
||||
<prompt phrase="ruffled" filename="ruffled.wav"/>
|
||||
<prompt phrase="sailboat" filename="sailboat.wav"/>
|
||||
<prompt phrase="sandalwood" filename="sandalwood.wav"/>
|
||||
<prompt phrase="sardonic" filename="sardonic.wav"/>
|
||||
<prompt phrase="savagery" filename="savagery.wav"/>
|
||||
<prompt phrase="sawdust" filename="sawdust.wav"/>
|
||||
<prompt phrase="scallion" filename="scallion.wav"/>
|
||||
<prompt phrase="scavenger" filename="scavenger.wav"/>
|
||||
<prompt phrase="scenic" filename="scenic.wav"/>
|
||||
<prompt phrase="scorecard" filename="scorecard.wav"/>
|
||||
<prompt phrase="seabird" filename="seabird.wav"/>
|
||||
<prompt phrase="select" filename="select.wav"/>
|
||||
<prompt phrase="sensation" filename="sensation.wav"/>
|
||||
<prompt phrase="sentence" filename="sentence.wav"/>
|
||||
<prompt phrase="shadow" filename="shadow.wav"/>
|
||||
<prompt phrase="shamrock" filename="shamrock.wav"/>
|
||||
<prompt phrase="showgirl" filename="showgirl.wav"/>
|
||||
<prompt phrase="skullcap" filename="skullcap.wav"/>
|
||||
<prompt phrase="skydive" filename="skydive.wav"/>
|
||||
<prompt phrase="slingshot" filename="slingshot.wav"/>
|
||||
<prompt phrase="slowdown" filename="slowdown.wav"/>
|
||||
<prompt phrase="snapline" filename="snapline.wav"/>
|
||||
<prompt phrase="snapshot" filename="snapshot.wav"/>
|
||||
<prompt phrase="snowcap" filename="snowcap.wav"/>
|
||||
<prompt phrase="snowslide" filename="snowslide.wav"/>
|
||||
<prompt phrase="sociable" filename="sociable.wav"/>
|
||||
<prompt phrase="solo" filename="solo.wav"/>
|
||||
<prompt phrase="southward" filename="southward.wav"/>
|
||||
<prompt phrase="souvenir" filename="souvenir.wav"/>
|
||||
<prompt phrase="soybean" filename="soybean.wav"/>
|
||||
<prompt phrase="spaniel" filename="spaniel.wav"/>
|
||||
<prompt phrase="spearhead" filename="spearhead.wav"/>
|
||||
<prompt phrase="specialist" filename="specialist.wav"/>
|
||||
<prompt phrase="speculate" filename="speculate.wav"/>
|
||||
<prompt phrase="spellbind" filename="spellbind.wav"/>
|
||||
<prompt phrase="spheroid" filename="spheroid.wav"/>
|
||||
<prompt phrase="spigot" filename="spigot.wav"/>
|
||||
<prompt phrase="spindle" filename="spindle.wav"/>
|
||||
<prompt phrase="spyglass" filename="spyglass.wav"/>
|
||||
<prompt phrase="stagehand" filename="stagehand.wav"/>
|
||||
<prompt phrase="stagnate" filename="stagnate.wav"/>
|
||||
<prompt phrase="stairway" filename="stairway.wav"/>
|
||||
<prompt phrase="standard" filename="standard.wav"/>
|
||||
<prompt phrase="stapler" filename="stapler.wav"/>
|
||||
<prompt phrase="steamship" filename="steamship.wav"/>
|
||||
<prompt phrase="sterling" filename="sterling.wav"/>
|
||||
<prompt phrase="stethoscope" filename="stethoscope.wav"/>
|
||||
<prompt phrase="stockman" filename="stockman.wav"/>
|
||||
<prompt phrase="stopwatch" filename="stopwatch.wav"/>
|
||||
<prompt phrase="stormy" filename="stormy.wav"/>
|
||||
<prompt phrase="stupendous" filename="stupendous.wav"/>
|
||||
<prompt phrase="sugar" filename="sugar.wav"/>
|
||||
<prompt phrase="supportive" filename="supportive.wav"/>
|
||||
<prompt phrase="surmount" filename="surmount.wav"/>
|
||||
<prompt phrase="surrender" filename="surrender.wav"/>
|
||||
<prompt phrase="suspense" filename="suspense.wav"/>
|
||||
<prompt phrase="suspicious" filename="suspicious.wav"/>
|
||||
<prompt phrase="sweatband" filename="sweatband.wav"/>
|
||||
<prompt phrase="swelter" filename="swelter.wav"/>
|
||||
<prompt phrase="sympathy" filename="sympathy.wav"/>
|
||||
<prompt phrase="tactics" filename="tactics.wav"/>
|
||||
<prompt phrase="talon" filename="talon.wav"/>
|
||||
<prompt phrase="tambourine" filename="tambourine.wav"/>
|
||||
<prompt phrase="tapeworm" filename="tapeworm.wav"/>
|
||||
<prompt phrase="telephone" filename="telephone.wav"/>
|
||||
<prompt phrase="tempest" filename="tempest.wav"/>
|
||||
<prompt phrase="therapist" filename="therapist.wav"/>
|
||||
<prompt phrase="tiger" filename="tiger.wav"/>
|
||||
<prompt phrase="tissue" filename="tissue.wav"/>
|
||||
<prompt phrase="tobacco" filename="tobacco.wav"/>
|
||||
<prompt phrase="tolerance" filename="tolerance.wav"/>
|
||||
<prompt phrase="tomorrow" filename="tomorrow.wav"/>
|
||||
<prompt phrase="tonic" filename="tonic.wav"/>
|
||||
<prompt phrase="topmost" filename="topmost.wav"/>
|
||||
<prompt phrase="torpedo" filename="torpedo.wav"/>
|
||||
<prompt phrase="tracker" filename="tracker.wav"/>
|
||||
<prompt phrase="tradition" filename="tradition.wav"/>
|
||||
<prompt phrase="transit" filename="transit.wav"/>
|
||||
<prompt phrase="trauma" filename="trauma.wav"/>
|
||||
<prompt phrase="travesty" filename="travesty.wav"/>
|
||||
<prompt phrase="treadmill" filename="treadmill.wav"/>
|
||||
<prompt phrase="trombonist" filename="trombonist.wav"/>
|
||||
<prompt phrase="trouble" filename="trouble.wav"/>
|
||||
<prompt phrase="truncated" filename="truncated.wav"/>
|
||||
<prompt phrase="tumor" filename="tumor.wav"/>
|
||||
<prompt phrase="tunnel" filename="tunnel.wav"/>
|
||||
<prompt phrase="tycoon" filename="tycoon.wav"/>
|
||||
<prompt phrase="typewriter" filename="typewriter.wav"/>
|
||||
<prompt phrase="ultimate" filename="ultimate.wav"/>
|
||||
<prompt phrase="uncut" filename="uncut.wav"/>
|
||||
<prompt phrase="undaunted" filename="undaunted.wav"/>
|
||||
<prompt phrase="underfoot" filename="underfoot.wav"/>
|
||||
<prompt phrase="unearth" filename="unearth.wav"/>
|
||||
<prompt phrase="unicorn" filename="unicorn.wav"/>
|
||||
<prompt phrase="unify" filename="unify.wav"/>
|
||||
<prompt phrase="universe" filename="universe.wav"/>
|
||||
<prompt phrase="unravel" filename="unravel.wav"/>
|
||||
<prompt phrase="unwind" filename="unwind.wav"/>
|
||||
<prompt phrase="upcoming" filename="upcoming.wav"/>
|
||||
<prompt phrase="uproot" filename="uproot.wav"/>
|
||||
<prompt phrase="upset" filename="upset.wav"/>
|
||||
<prompt phrase="upshot" filename="upshot.wav"/>
|
||||
<prompt phrase="vacancy" filename="vacancy.wav"/>
|
||||
<prompt phrase="vagabond" filename="vagabond.wav"/>
|
||||
<prompt phrase="vapor" filename="vapor.wav"/>
|
||||
<prompt phrase="vertigo" filename="vertigo.wav"/>
|
||||
<prompt phrase="village" filename="village.wav"/>
|
||||
<prompt phrase="virus" filename="virus.wav"/>
|
||||
<prompt phrase="visitor" filename="visitor.wav"/>
|
||||
<prompt phrase="vocalist" filename="vocalist.wav"/>
|
||||
<prompt phrase="voyager" filename="voyager.wav"/>
|
||||
<prompt phrase="waffle" filename="waffle.wav"/>
|
||||
<prompt phrase="wallet" filename="wallet.wav"/>
|
||||
<prompt phrase="warranty" filename="warranty.wav"/>
|
||||
<prompt phrase="watchword" filename="watchword.wav"/>
|
||||
<prompt phrase="wayside" filename="wayside.wav"/>
|
||||
<prompt phrase="whimsical" filename="whimsical.wav"/>
|
||||
<prompt phrase="willow" filename="willow.wav"/>
|
||||
<prompt phrase="woodlark" filename="woodlark.wav"/>
|
||||
<prompt phrase="yesteryear" filename="yesteryear.wav"/>
|
||||
<!-- Event prompts -->
|
||||
<prompt phrase="Bem-vindo ao agente de registo ZRTP." filename="zrtp-enroll_welcome.wav"/>
|
||||
<prompt phrase="Deve verificar a chave de autenticação com destinatário. Se não for igual, indica a presença de uma escuta." filename="zrtp-check_sas.wav"/>
|
||||
<prompt phrase="Apenas telefones que estão autenticados podem ser configurados para usarem este sistema de retransmissão ZRTP para chamadas com modo de segurança activo. Se o seu telefone não está autenticado com o sistema, esta chamada não terá qualquer efeito." filename="zrtp-enroll_not_sip_registered.wav"/>
|
||||
<prompt phrase="O seu telefone indica que já confia neste sistema de retransmissão ZRTP para chamadas com o modo de segurança activo, portanto você já não precisa de fazer mais nada." filename="zrtp-enroll_already_enrolled.wav"/>
|
||||
<prompt phrase="Apenas telefones equipados com o protocolo ZRTP podem usar esta extensão. O seu telefone não suporta ZRTP, portanto esta chamada não terá qualquer efeito." filename="zrtp-enroll_notzrtp.wav"/>
|
||||
<prompt phrase="Este sistema está preparado para suportar chamadas encriptadas ZRTP. Você deve determinar se deseja permitir que o sistema possa interceptar ou gravar as suas chamadas telefónicas com o modo de segurança activado. Você pode desligar após confirmar este comportamento." filename="zrtp-enroll_confirmed.wav"/>
|
||||
<prompt phrase="Comparando verbalmente o código desta autenticação com o destinatário." filename="zrtp-is_secure.wav"/>
|
||||
<prompt phrase="O código de autenticação não foi verificado." filename="zrtp-is_unverified.wav"/>
|
||||
<prompt phrase="O código de autenticação foi verificado." filename="zrtp-is_verified.wav"/>
|
||||
<prompt phrase="Obrigado por telefonar. Até breve." filename="zrtp-thankyou_goodbye.wav"/>
|
||||
<prompt phrase="Algo está errado" filename="zrtp-somethings_wrong.wav"/>
|
||||
<prompt phrase="Erro." filename="zrtp-status_error.wav"/>
|
||||
<prompt phrase="O modo de segurança não está activo na chamada." filename="zrtp-status_notsecure.wav"/>
|
||||
<prompt phrase="O modo de segurança está activo na chamada." filename="zrtp-status_secure.wav"/>
|
||||
<prompt phrase="Activando o modo de segurança na chamada." filename="zrtp-status_securing.wav"/>
|
||||
</zrtp>
|
||||
</pt_PT>
|
||||
</language>
|
|
@ -9,9 +9,9 @@ CXXFLAGS=$(BASE_FLAGS) -Wall -Werror -Wno-unused-variable
|
|||
MYLIB=libesl.a
|
||||
LIBS=-lncurses -lpthread -lesl -lm
|
||||
LDFLAGS=-L.
|
||||
OBJS=src/esl.o src/esl_event.o src/esl_threadmutex.o src/esl_config.o src/esl_json.o
|
||||
SRC=src/esl.c src/esl_json.c src/esl_event.c src/esl_threadmutex.c src/esl_config.c src/esl_oop.cpp src/esl_json.c
|
||||
HEADERS=src/include/esl_config.h src/include/esl_event.h src/include/esl.h src/include/esl_threadmutex.h src/include/esl_oop.h src/include/esl_json.h
|
||||
OBJS=src/esl.o src/esl_event.o src/esl_threadmutex.o src/esl_config.o src/esl_json.o src/esl_buffer.o
|
||||
SRC=src/esl.c src/esl_json.c src/esl_event.c src/esl_threadmutex.c src/esl_config.c src/esl_oop.cpp src/esl_json.c src/esl_buffer.c
|
||||
HEADERS=src/include/esl_config.h src/include/esl_event.h src/include/esl.h src/include/esl_threadmutex.h src/include/esl_oop.h src/include/esl_json.h src/include/esl_buffer.h
|
||||
SOLINK=-shared -Xlinker -x
|
||||
# comment the next line to disable c++ (no swig mods for you then)
|
||||
OBJS += src/esl_oop.o
|
||||
|
|
|
@ -290,6 +290,10 @@
|
|||
RelativePath=".\esl.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\esl_buffer.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\esl_config.c"
|
||||
>
|
||||
|
@ -316,6 +320,10 @@
|
|||
RelativePath=".\include\esl.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\esl_buffer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\esl_config.h"
|
||||
>
|
||||
|
|
|
@ -128,6 +128,7 @@
|
|||
<ClCompile Include="esl_event.c" />
|
||||
<ClCompile Include="esl_json.c" />
|
||||
<ClCompile Include="esl_threadmutex.c" />
|
||||
<ClCompile Include="esl_buffer.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\esl.h" />
|
||||
|
@ -135,6 +136,7 @@
|
|||
<ClInclude Include="include\esl_event.h" />
|
||||
<ClInclude Include="include\esl_json.h" />
|
||||
<ClInclude Include="include\esl_threadmutex.h" />
|
||||
<ClInclude Include="include\esl_buffer.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
@ -428,6 +428,10 @@ ESL_DECLARE(esl_status_t) esl_attach_handle(esl_handle_t *handle, esl_socket_t s
|
|||
esl_mutex_create(&handle->mutex);
|
||||
}
|
||||
|
||||
if (!handle->packet_buf) {
|
||||
esl_buffer_create(&handle->packet_buf, BUF_CHUNK, BUF_START, 0);
|
||||
}
|
||||
|
||||
handle->connected = 1;
|
||||
|
||||
esl_send_recv(handle, "connect\n\n");
|
||||
|
@ -632,6 +636,10 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *
|
|||
if (!handle->mutex) {
|
||||
esl_mutex_create(&handle->mutex);
|
||||
}
|
||||
|
||||
if (!handle->packet_buf) {
|
||||
esl_buffer_create(&handle->packet_buf, BUF_CHUNK, BUF_START, 0);
|
||||
}
|
||||
|
||||
handle->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
|
@ -805,6 +813,11 @@ ESL_DECLARE(esl_status_t) esl_disconnect(esl_handle_t *handle)
|
|||
esl_mutex_destroy(&mutex);
|
||||
}
|
||||
|
||||
if (handle->packet_buf) {
|
||||
esl_buffer_destroy(&handle->packet_buf);
|
||||
}
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -825,7 +838,7 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms
|
|||
|
||||
if (check_q) {
|
||||
esl_mutex_lock(handle->mutex);
|
||||
if (handle->race_event) {
|
||||
if (handle->race_event || esl_buffer_packet_count(handle->packet_buf)) {
|
||||
esl_mutex_unlock(handle->mutex);
|
||||
return esl_recv_event(handle, check_q, save_event);
|
||||
}
|
||||
|
@ -894,12 +907,15 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms
|
|||
|
||||
}
|
||||
|
||||
static esl_ssize_t handle_recv(esl_handle_t *handle, void *data, esl_size_t datalen)
|
||||
{
|
||||
return recv(handle->sock, data, datalen, 0);
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_event_t **save_event)
|
||||
{
|
||||
char *c;
|
||||
esl_ssize_t rrval;
|
||||
int crc = 0;
|
||||
esl_event_t *revent = NULL;
|
||||
char *beg;
|
||||
char *hname, *hval;
|
||||
|
@ -907,7 +923,6 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
|
|||
char *cl;
|
||||
esl_ssize_t len;
|
||||
int zc = 0;
|
||||
int bread = 0;
|
||||
|
||||
if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
|
||||
return ESL_FAIL;
|
||||
|
@ -916,9 +931,7 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
|
|||
esl_mutex_lock(handle->mutex);
|
||||
|
||||
if (!handle->connected || handle->sock == ESL_SOCK_INVALID) {
|
||||
handle->connected = 0;
|
||||
esl_mutex_unlock(handle->mutex);
|
||||
return ESL_FAIL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
esl_event_safe_destroy(&handle->last_event);
|
||||
|
@ -932,76 +945,62 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
|
|||
goto parse_event;
|
||||
}
|
||||
|
||||
memset(handle->header_buf, 0, sizeof(handle->header_buf));
|
||||
|
||||
while(!revent && handle->connected) {
|
||||
esl_size_t len1;
|
||||
|
||||
if ((len1 = esl_buffer_read_packet(handle->packet_buf, handle->socket_buf, sizeof(handle->socket_buf)))) {
|
||||
char *data = (char *) handle->socket_buf;
|
||||
char *p, *e;
|
||||
|
||||
esl_event_create(&revent, ESL_EVENT_CLONE);
|
||||
revent->event_id = ESL_EVENT_SOCKET_DATA;
|
||||
esl_event_add_header_string(revent, ESL_STACK_BOTTOM, "Event-Name", "SOCKET_DATA");
|
||||
|
||||
hname = p = data;
|
||||
while(p) {
|
||||
hname = p;
|
||||
p = NULL;
|
||||
|
||||
c = handle->header_buf;
|
||||
beg = c;
|
||||
if ((hval = strchr(hname, ':'))) {
|
||||
*hval++ = '\0';
|
||||
while(*hval == ' ' || *hval == '\t') hval++;
|
||||
|
||||
while(handle->connected) {
|
||||
if (bread + 2 >= sizeof(handle->header_buf)) {
|
||||
esl_log(ESL_LOG_CRIT, "OUT OF BUFFER SPACE!\n");
|
||||
handle->connected = 0;
|
||||
esl_mutex_unlock(handle->mutex);
|
||||
return ESL_DISCONNECTED;
|
||||
if ((e = strchr(hval, '\n'))) {
|
||||
*e++ = '\0';
|
||||
while(*e == '\n' || *e == '\r') e++;
|
||||
|
||||
if (hname && hval) {
|
||||
esl_url_decode(hval);
|
||||
esl_log(ESL_LOG_DEBUG, "RECV HEADER [%s] = [%s]\n", hname, hval);
|
||||
esl_event_add_header_string(revent, ESL_STACK_BOTTOM, hname, hval);
|
||||
}
|
||||
|
||||
p = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
rrval = recv(handle->sock, c, 1, 0);
|
||||
rrval = handle_recv(handle, handle->socket_buf, sizeof(handle->socket_buf));
|
||||
|
||||
if (rrval == 0) {
|
||||
if (++zc >= 100) {
|
||||
handle->connected = 0;
|
||||
esl_mutex_unlock(handle->mutex);
|
||||
return ESL_DISCONNECTED;
|
||||
goto fail;
|
||||
}
|
||||
continue;
|
||||
} else if (rrval < 0) {
|
||||
strerror_r(handle->errnum, handle->err, sizeof(handle->err));
|
||||
goto fail;
|
||||
} else {
|
||||
zc = 0;
|
||||
|
||||
if (*c == '\n') {
|
||||
|
||||
*(c+1) = '\0';
|
||||
|
||||
if (++crc == 2) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!revent) {
|
||||
esl_event_create(&revent, ESL_EVENT_CLONE);
|
||||
revent->event_id = ESL_EVENT_SOCKET_DATA;
|
||||
esl_event_add_header_string(revent, ESL_STACK_BOTTOM, "Event-Name", "SOCKET_DATA");
|
||||
|
||||
}
|
||||
|
||||
hname = beg;
|
||||
hval = col = NULL;
|
||||
|
||||
if (hname && (col = strchr(hname, ':'))) {
|
||||
hval = col + 1;
|
||||
*col = '\0';
|
||||
while(*hval == ' ') hval++;
|
||||
}
|
||||
|
||||
*c = '\0';
|
||||
|
||||
if (hname && hval) {
|
||||
esl_url_decode(hval);
|
||||
esl_log(ESL_LOG_DEBUG, "RECV HEADER [%s] = [%s]\n", hname, hval);
|
||||
esl_event_add_header_string(revent, ESL_STACK_BOTTOM, hname, hval);
|
||||
}
|
||||
|
||||
c = beg;
|
||||
bread = 0;
|
||||
continue;
|
||||
|
||||
} else {
|
||||
crc = 0;
|
||||
}
|
||||
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
zc = 0;
|
||||
|
||||
esl_buffer_write(handle->packet_buf, handle->socket_buf, rrval);
|
||||
}
|
||||
|
||||
if (!revent) {
|
||||
goto fail;
|
||||
}
|
||||
|
@ -1016,12 +1015,28 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
|
|||
*(body + len) = '\0';
|
||||
|
||||
do {
|
||||
esl_ssize_t r;
|
||||
if ((r = recv(handle->sock, body + sofar, len - sofar, 0)) < 0) {
|
||||
strerror_r(handle->errnum, handle->err, sizeof(handle->err));
|
||||
goto fail;
|
||||
esl_ssize_t r,s = esl_buffer_inuse(handle->packet_buf);
|
||||
|
||||
if (s >= len) {
|
||||
sofar = esl_buffer_read(handle->packet_buf, body, len);
|
||||
} else {
|
||||
r = handle_recv(handle, handle->socket_buf, sizeof(handle->socket_buf));
|
||||
|
||||
if (r < 0) {
|
||||
strerror_r(handle->errnum, handle->err, sizeof(handle->err));
|
||||
goto fail;
|
||||
} else if (r == 0) {
|
||||
if (++zc >= 100) {
|
||||
goto fail;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
zc = 0;
|
||||
|
||||
esl_buffer_write(handle->packet_buf, handle->socket_buf, r);
|
||||
}
|
||||
sofar += r;
|
||||
|
||||
} while (sofar < len);
|
||||
|
||||
revent->body = body;
|
||||
|
@ -1123,6 +1138,8 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
|
|||
|
||||
fail:
|
||||
|
||||
esl_mutex_unlock(handle->mutex);
|
||||
|
||||
handle->connected = 0;
|
||||
|
||||
return ESL_FAIL;
|
||||
|
@ -1177,7 +1194,6 @@ ESL_DECLARE(esl_status_t) esl_send_recv_timed(esl_handle_t *handle, const char *
|
|||
return ESL_FAIL;
|
||||
}
|
||||
|
||||
esl_event_safe_destroy(&handle->last_event);
|
||||
esl_event_safe_destroy(&handle->last_sr_event);
|
||||
|
||||
*handle->last_sr_reply = '\0';
|
||||
|
|
|
@ -0,0 +1,354 @@
|
|||
/*
|
||||
* Copyright (c) 2010, 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "esl_buffer.h"
|
||||
|
||||
static unsigned buffer_id = 0;
|
||||
|
||||
struct esl_buffer {
|
||||
unsigned char *data;
|
||||
unsigned char *head;
|
||||
esl_size_t used;
|
||||
esl_size_t actually_used;
|
||||
esl_size_t datalen;
|
||||
esl_size_t max_len;
|
||||
esl_size_t blocksize;
|
||||
unsigned id;
|
||||
int loops;
|
||||
};
|
||||
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_buffer_create(esl_buffer_t **buffer, esl_size_t blocksize, esl_size_t start_len, esl_size_t max_len)
|
||||
{
|
||||
esl_buffer_t *new_buffer;
|
||||
|
||||
new_buffer = malloc(sizeof(*new_buffer));
|
||||
if (new_buffer) {
|
||||
memset(new_buffer, 0, sizeof(*new_buffer));
|
||||
|
||||
if (start_len) {
|
||||
new_buffer->data = malloc(start_len);
|
||||
if (!new_buffer->data) {
|
||||
free(new_buffer);
|
||||
return ESL_FAIL;
|
||||
}
|
||||
memset(new_buffer->data, 0, start_len);
|
||||
}
|
||||
|
||||
new_buffer->max_len = max_len;
|
||||
new_buffer->datalen = start_len;
|
||||
new_buffer->id = buffer_id++;
|
||||
new_buffer->blocksize = blocksize;
|
||||
new_buffer->head = new_buffer->data;
|
||||
|
||||
*buffer = new_buffer;
|
||||
return ESL_SUCCESS;
|
||||
}
|
||||
|
||||
return ESL_FAIL;
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_len(esl_buffer_t *buffer)
|
||||
{
|
||||
|
||||
assert(buffer != NULL);
|
||||
|
||||
return buffer->datalen;
|
||||
|
||||
}
|
||||
|
||||
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_freespace(esl_buffer_t *buffer)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
|
||||
|
||||
if (buffer->max_len) {
|
||||
return (esl_size_t) (buffer->max_len - buffer->used);
|
||||
}
|
||||
return 1000000;
|
||||
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_inuse(esl_buffer_t *buffer)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
|
||||
return buffer->used;
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_seek(esl_buffer_t *buffer, esl_size_t datalen)
|
||||
{
|
||||
esl_size_t reading = 0;
|
||||
|
||||
assert(buffer != NULL);
|
||||
|
||||
if (buffer->used < 1) {
|
||||
buffer->used = 0;
|
||||
return 0;
|
||||
} else if (buffer->used >= datalen) {
|
||||
reading = datalen;
|
||||
} else {
|
||||
reading = buffer->used;
|
||||
}
|
||||
|
||||
buffer->used = buffer->actually_used - reading;
|
||||
buffer->head = buffer->data + reading;
|
||||
|
||||
return reading;
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_toss(esl_buffer_t *buffer, esl_size_t datalen)
|
||||
{
|
||||
esl_size_t reading = 0;
|
||||
|
||||
assert(buffer != NULL);
|
||||
|
||||
if (buffer->used < 1) {
|
||||
buffer->used = 0;
|
||||
return 0;
|
||||
} else if (buffer->used >= datalen) {
|
||||
reading = datalen;
|
||||
} else {
|
||||
reading = buffer->used;
|
||||
}
|
||||
|
||||
buffer->used -= reading;
|
||||
buffer->head += reading;
|
||||
|
||||
return buffer->used;
|
||||
}
|
||||
|
||||
ESL_DECLARE(void) esl_buffer_set_loops(esl_buffer_t *buffer, int loops)
|
||||
{
|
||||
buffer->loops = loops;
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_read_loop(esl_buffer_t *buffer, void *data, esl_size_t datalen)
|
||||
{
|
||||
esl_size_t len;
|
||||
if ((len = esl_buffer_read(buffer, data, datalen)) < datalen) {
|
||||
if (buffer->loops == 0) {
|
||||
return len;
|
||||
}
|
||||
buffer->head = buffer->data;
|
||||
buffer->used = buffer->actually_used;
|
||||
len = esl_buffer_read(buffer, (char*)data + len, datalen - len);
|
||||
buffer->loops--;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_read(esl_buffer_t *buffer, void *data, esl_size_t datalen)
|
||||
{
|
||||
esl_size_t reading = 0;
|
||||
|
||||
assert(buffer != NULL);
|
||||
assert(data != NULL);
|
||||
|
||||
|
||||
if (buffer->used < 1) {
|
||||
buffer->used = 0;
|
||||
return 0;
|
||||
} else if (buffer->used >= datalen) {
|
||||
reading = datalen;
|
||||
} else {
|
||||
reading = buffer->used;
|
||||
}
|
||||
|
||||
memcpy(data, buffer->head, reading);
|
||||
buffer->used -= reading;
|
||||
buffer->head += reading;
|
||||
|
||||
/* if (buffer->id == 4) printf("%u o %d = %d\n", buffer->id, (unsigned)reading, (unsigned)buffer->used); */
|
||||
return reading;
|
||||
}
|
||||
|
||||
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_packet_count(esl_buffer_t *buffer)
|
||||
{
|
||||
char *pe, *p, *e, *head = (char *) buffer->head;
|
||||
esl_size_t x = 0;
|
||||
|
||||
assert(buffer != NULL);
|
||||
|
||||
e = (head + buffer->used);
|
||||
|
||||
for (p = head; p && *p && p < e; p++) {
|
||||
if (*p == '\n') {
|
||||
pe = p+1;
|
||||
if (*pe == '\r') pe++;
|
||||
if (pe <= e && *pe == '\n') {
|
||||
p = pe++;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_read_packet(esl_buffer_t *buffer, void *data, esl_size_t maxlen)
|
||||
{
|
||||
char *pe, *p, *e, *head = (char *) buffer->head;
|
||||
esl_size_t datalen = 0;
|
||||
|
||||
assert(buffer != NULL);
|
||||
assert(data != NULL);
|
||||
|
||||
e = (head + buffer->used);
|
||||
|
||||
for (p = head; p && *p && p < e; p++) {
|
||||
if (*p == '\n') {
|
||||
pe = p+1;
|
||||
if (*pe == '\r') pe++;
|
||||
if (pe <= e && *pe == '\n') {
|
||||
pe++;
|
||||
datalen = pe - head;
|
||||
if (datalen > maxlen) {
|
||||
datalen = maxlen;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return esl_buffer_read(buffer, data, datalen);
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data, esl_size_t datalen)
|
||||
{
|
||||
esl_size_t freespace, actual_freespace;
|
||||
|
||||
assert(buffer != NULL);
|
||||
assert(data != NULL);
|
||||
assert(buffer->data != NULL);
|
||||
|
||||
if (!datalen) {
|
||||
return buffer->used;
|
||||
}
|
||||
|
||||
actual_freespace = buffer->datalen - buffer->actually_used;
|
||||
if (actual_freespace < datalen && (!buffer->max_len || (buffer->used + datalen <= buffer->max_len))) {
|
||||
memmove(buffer->data, buffer->head, buffer->used);
|
||||
buffer->head = buffer->data;
|
||||
buffer->actually_used = buffer->used;
|
||||
}
|
||||
|
||||
freespace = buffer->datalen - buffer->used;
|
||||
|
||||
/*
|
||||
if (buffer->data != buffer->head) {
|
||||
memmove(buffer->data, buffer->head, buffer->used);
|
||||
buffer->head = buffer->data;
|
||||
}
|
||||
*/
|
||||
|
||||
if (freespace < datalen) {
|
||||
esl_size_t new_size, new_block_size;
|
||||
void *data1;
|
||||
|
||||
new_size = buffer->datalen + datalen;
|
||||
new_block_size = buffer->datalen + buffer->blocksize;
|
||||
|
||||
if (new_block_size > new_size) {
|
||||
new_size = new_block_size;
|
||||
}
|
||||
buffer->head = buffer->data;
|
||||
data1 = realloc(buffer->data, new_size);
|
||||
if (!data1) {
|
||||
return 0;
|
||||
}
|
||||
buffer->data = data1;
|
||||
buffer->head = buffer->data;
|
||||
buffer->datalen = new_size;
|
||||
}
|
||||
|
||||
|
||||
freespace = buffer->datalen - buffer->used;
|
||||
|
||||
if (freespace < datalen) {
|
||||
return 0;
|
||||
} else {
|
||||
memcpy(buffer->head + buffer->used, data, datalen);
|
||||
buffer->used += datalen;
|
||||
buffer->actually_used += datalen;
|
||||
}
|
||||
/* if (buffer->id == 4) printf("%u i %d = %d\n", buffer->id, (unsigned)datalen, (unsigned)buffer->used); */
|
||||
|
||||
return buffer->used;
|
||||
}
|
||||
|
||||
ESL_DECLARE(void) esl_buffer_zero(esl_buffer_t *buffer)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(buffer->data != NULL);
|
||||
|
||||
buffer->used = 0;
|
||||
buffer->actually_used = 0;
|
||||
buffer->head = buffer->data;
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_zwrite(esl_buffer_t *buffer, const void *data, esl_size_t datalen)
|
||||
{
|
||||
esl_size_t w;
|
||||
|
||||
if (!(w = esl_buffer_write(buffer, data, datalen))) {
|
||||
esl_buffer_zero(buffer);
|
||||
return esl_buffer_write(buffer, data, datalen);
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
ESL_DECLARE(void) esl_buffer_destroy(esl_buffer_t **buffer)
|
||||
{
|
||||
if (*buffer) {
|
||||
free((*buffer)->data);
|
||||
free(*buffer);
|
||||
}
|
||||
|
||||
*buffer = NULL;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
|
@ -251,6 +251,7 @@ typedef int esl_filehandle_t;
|
|||
#include "esl_json.h"
|
||||
|
||||
typedef int16_t esl_port_t;
|
||||
typedef size_t esl_size_t;
|
||||
|
||||
typedef enum {
|
||||
ESL_SUCCESS,
|
||||
|
@ -259,7 +260,11 @@ typedef enum {
|
|||
ESL_DISCONNECTED
|
||||
} esl_status_t;
|
||||
|
||||
#define BUF_CHUNK 65536 * 50
|
||||
#define BUF_START 65536 * 100
|
||||
|
||||
#include <esl_threadmutex.h>
|
||||
#include <esl_buffer.h>
|
||||
|
||||
/*! \brief A handle that will hold the socket information and
|
||||
different events received. */
|
||||
|
@ -273,7 +278,8 @@ typedef struct {
|
|||
/*! The error number reported by the OS */
|
||||
int errnum;
|
||||
/*! The inner contents received by the socket. Used only internally. */
|
||||
char header_buf[4196];
|
||||
esl_buffer_t *packet_buf;
|
||||
char socket_buf[65536];
|
||||
/*! Last command reply */
|
||||
char last_reply[1024];
|
||||
/*! Las command reply when called with esl_send_recv */
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (c) 2010, 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.
|
||||
*/
|
||||
#include "esl.h"
|
||||
#ifndef ESL_BUFFER_H
|
||||
#define ESL_BUFFER_H
|
||||
/**
|
||||
* @defgroup esl_buffer Buffer Routines
|
||||
* @ingroup buffer
|
||||
* The purpose of this module is to make a plain buffering interface that can be used for read/write buffers
|
||||
* throughout the application.
|
||||
* @{
|
||||
*/
|
||||
struct esl_buffer;
|
||||
typedef struct esl_buffer esl_buffer_t;
|
||||
|
||||
/*! \brief Allocate a new dynamic esl_buffer
|
||||
* \param buffer returned pointer to the new buffer
|
||||
* \param blocksize length to realloc by as data is added
|
||||
* \param start_len ammount of memory to reserve initially
|
||||
* \param max_len length the buffer is allowed to grow to
|
||||
* \return status
|
||||
*/
|
||||
ESL_DECLARE(esl_status_t) esl_buffer_create(esl_buffer_t **buffer, esl_size_t blocksize, esl_size_t start_len, esl_size_t max_len);
|
||||
|
||||
/*! \brief Get the length of a esl_buffer_t
|
||||
* \param buffer any buffer of type esl_buffer_t
|
||||
* \return int size of the buffer.
|
||||
*/
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_len(esl_buffer_t *buffer);
|
||||
|
||||
/*! \brief Get the freespace of a esl_buffer_t
|
||||
* \param buffer any buffer of type esl_buffer_t
|
||||
* \return int freespace in the buffer.
|
||||
*/
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_freespace(esl_buffer_t *buffer);
|
||||
|
||||
/*! \brief Get the in use amount of a esl_buffer_t
|
||||
* \param buffer any buffer of type esl_buffer_t
|
||||
* \return int ammount of buffer curently in use
|
||||
*/
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_inuse(esl_buffer_t *buffer);
|
||||
|
||||
/*! \brief Read data from a esl_buffer_t up to the ammount of datalen if it is available. Remove read data from buffer.
|
||||
* \param buffer any buffer of type esl_buffer_t
|
||||
* \param data pointer to the read data to be returned
|
||||
* \param datalen amount of data to be returned
|
||||
* \return int ammount of data actually read
|
||||
*/
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_read(esl_buffer_t *buffer, void *data, esl_size_t datalen);
|
||||
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_read_packet(esl_buffer_t *buffer, void *data, esl_size_t maxlen);
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_packet_count(esl_buffer_t *buffer);
|
||||
|
||||
/*! \brief Read data endlessly from a esl_buffer_t
|
||||
* \param buffer any buffer of type esl_buffer_t
|
||||
* \param data pointer to the read data to be returned
|
||||
* \param datalen amount of data to be returned
|
||||
* \return int ammount of data actually read
|
||||
* \note Once you have read all the data from the buffer it will loop around.
|
||||
*/
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_read_loop(esl_buffer_t *buffer, void *data, esl_size_t datalen);
|
||||
|
||||
/*! \brief Assign a number of loops to read
|
||||
* \param buffer any buffer of type esl_buffer_t
|
||||
* \param loops the number of loops (-1 for infinite)
|
||||
*/
|
||||
ESL_DECLARE(void) esl_buffer_set_loops(esl_buffer_t *buffer, int32_t loops);
|
||||
|
||||
/*! \brief Write data into a esl_buffer_t up to the length of datalen
|
||||
* \param buffer any buffer of type esl_buffer_t
|
||||
* \param data pointer to the data to be written
|
||||
* \param datalen amount of data to be written
|
||||
* \return int amount of buffer used after the write, or 0 if no space available
|
||||
*/
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data, esl_size_t datalen);
|
||||
|
||||
/*! \brief Remove data from the buffer
|
||||
* \param buffer any buffer of type esl_buffer_t
|
||||
* \param datalen amount of data to be removed
|
||||
* \return int size of buffer, or 0 if unable to toss that much data
|
||||
*/
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_toss(esl_buffer_t *buffer, esl_size_t datalen);
|
||||
|
||||
/*! \brief Remove all data from the buffer
|
||||
* \param buffer any buffer of type esl_buffer_t
|
||||
*/
|
||||
ESL_DECLARE(void) esl_buffer_zero(esl_buffer_t *buffer);
|
||||
|
||||
/*! \brief Destroy the buffer
|
||||
* \param buffer buffer to destroy
|
||||
* \note only neccessary on dynamic buffers (noop on pooled ones)
|
||||
*/
|
||||
ESL_DECLARE(void) esl_buffer_destroy(esl_buffer_t **buffer);
|
||||
|
||||
/*! \brief Seek to offset from the beginning of the buffer
|
||||
* \param buffer buffer to seek
|
||||
* \param datalen offset in bytes
|
||||
* \return new position
|
||||
*/
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_seek(esl_buffer_t *buffer, esl_size_t datalen);
|
||||
|
||||
/** @} */
|
||||
|
||||
ESL_DECLARE(esl_size_t) esl_buffer_zwrite(esl_buffer_t *buffer, const void *data, esl_size_t datalen);
|
||||
|
||||
#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:
|
||||
*/
|
|
@ -49,6 +49,7 @@ if HAVE_SNG_ISDN
|
|||
INCS += -I/usr/include/sng_isdn
|
||||
endif
|
||||
|
||||
# we needed to separate CFLAGS in FTDM_COMPAT_CFLAGS and FTDM_CFLAGS due to -c99 which causes problems with wanpipe headers
|
||||
FTDM_COMPAT_CFLAGS = $(INCS) -DFTDM_CONFIG_DIR=\"@confdir@\" -DFTDM_MOD_DIR=\"$(moddir)\" @COMP_VENDOR_COMPAT_CFLAGS@ @DEFS@
|
||||
FTDM_CFLAGS = $(INCS) -DFTDM_CONFIG_DIR=\"@confdir@\" -DFTDM_MOD_DIR=\"$(moddir)\" @COMP_VENDOR_CFLAGS@ @DEFS@
|
||||
COMPILE = $(CC) $(FTDM_CFLAGS)
|
||||
|
@ -183,8 +184,8 @@ ftmod_analog_em_la_LIBADD = libfreetdm.la
|
|||
if HAVE_LIBSANGOMA
|
||||
mod_LTLIBRARIES += ftmod_wanpipe.la
|
||||
ftmod_wanpipe_la_SOURCES = $(SRC)/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
|
||||
#some structures within Wanpipe drivers are not c99 compatible, so we need to compile ftmod_wanpipe
|
||||
#without c99 flags
|
||||
# some structures within Wanpipe drivers are not c99 compatible, so we need to compile ftmod_wanpipe
|
||||
# without c99 flags, use FTDM_COMPAT_CFLAGS instead
|
||||
ftmod_wanpipe_la_CFLAGS = $(AM_CFLAGS) $(FTDM_COMPAT_CFLAGS) -D__LINUX__ -I/usr/include/wanpipe
|
||||
ftmod_wanpipe_la_LDFLAGS = -shared -module -avoid-version -lsangoma
|
||||
ftmod_wanpipe_la_LIBADD = libfreetdm.la
|
||||
|
|
|
@ -82,7 +82,7 @@ sun)
|
|||
fi
|
||||
;;
|
||||
*)
|
||||
COMP_VENDOR_COMPAT_CFLAGS="-Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes"
|
||||
COMP_VENDOR_COMPAT_CFLAGS="-Wall -Werror -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes"
|
||||
COMP_VENDOR_CFLAGS="-std=c99 $COMP_VENDOR_COMPAT_CFLAGS"
|
||||
;;
|
||||
esac
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#! /bin/sh
|
||||
./configure "$@" --with-pic
|
||||
|
||||
srcpath=$(dirname $0 2>/dev/null ) || srcpath="."
|
||||
$srcpath/configure "$@" --with-pic
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
FreeTDM can both notify and set signaling status changes in the different protocols thru a unified interface. More
|
||||
specific details on the C data types and function prototypes are found in freetdm.h
|
||||
|
||||
The API provides the following functions and data types to do it:
|
||||
|
||||
The signaling status in any channel/span is represented thru ftdm_signaling_status_t
|
||||
|
||||
/* The signaling link is down (no d-chans up in the span/group, MFC-R2 bit pattern unidentified) */
|
||||
FTDM_SIG_STATE_DOWN,
|
||||
/* The signaling link is suspended (MFC-R2 bit pattern blocked, PRI maintenance, ss7 blocked?) */
|
||||
FTDM_SIG_STATE_SUSPENDED,
|
||||
/* The signaling link is ready and calls can be placed (ie: d-chan up, MFC-R2 both rx and tx in IDLE) */
|
||||
FTDM_SIG_STATE_UP,
|
||||
/* Invalid status */
|
||||
FTDM_SIG_STATE_INVALID
|
||||
|
||||
Changes in the signaling status are notified to the user using the standard callback notification function provided
|
||||
during configuration using the sigevent type FTDM_SIGEVENT_SIGSTATUS_CHANGED which is sent when the line status changes.
|
||||
|
||||
On startup the signalling status default is FTDM_SIG_STATE_DOWN, and no notification is provided until the state change,
|
||||
so applications must assume the status is down unless told otherwise.
|
||||
|
||||
When ftdm_span_start is called, the signaling stack takes care of attempting to bring the status to UP
|
||||
but it will ultimately depend on the other side too.
|
||||
|
||||
== Setting the signaling status ==
|
||||
|
||||
Users can set the signaling status on a given channel/span thru FreeTDM the following API functions:
|
||||
|
||||
ftdm_channel_set_sig_status
|
||||
ftdm_span_set_sig_status
|
||||
|
||||
If the user calls ftdm_channel_set_sig_status(chan, FTDM_SIG_STATE_SUSPENDED), the signaling stack will try to set
|
||||
the status of the line to the one requested, if successful, it will result in a SIGEVENT_SIGSTATUS_CHANGED notification
|
||||
being sent with status FTDM_SIG_STATE_SUSPENDED.
|
||||
|
||||
** MFC-R2 Signaling Notes **
|
||||
For MFC-R2, calling ftdm_span_start() results in setting the tx CAS bits to IDLE. However, if the rx bits are in BLOCKED state
|
||||
the signaling status will be reported as SUSPENDED.
|
||||
|
||||
If the user calls ftdm_channel_set_sig_status(chan, SUSPENDED), the tx CAS bits will be set to BLOCKED and, if, the current rx bits
|
||||
are IDLE then a SIGEVENT_SIGSTATUS_CHANGED with state SUSPENDED will be sent. If the rx bits are already in blocked then no further
|
||||
SIGEVENT_SIGSTATUS_CHANGED notification is needed (because it was already sent when the rx bits were initially detected as BLOCKED).
|
||||
|
||||
If the user calls ftdm_channel_set_sig_status(chan, UP), the tx CAS bits will be set to IDLE and, if, the current rx bits
|
||||
are IDLE, then SIGEVENT_SIGSTATUS_CHANGED with state UP will be sent. If the rx bits are BLOCKED, then no notification is
|
||||
sent at all until the rx bits change.
|
||||
|
||||
Bottom line is, for MFC-R2, SIGEVENT_SIGSTATUS_CHANGED UP is only sent to the user when both the rx and tx bits are in IDLE, and
|
||||
SIGEVENT_SIGSTATUS_CHANGED SUSPENDED is only sent to the user when any of the rx or tx bits are in BLOCKED.
|
||||
|
||||
== Getting the signaling status ==
|
||||
Users can get the signaling status on a given channel/span thru FreeTDM the following API functions:
|
||||
|
||||
ftdm_channel_get_sig_status
|
||||
ftdm_span_get_sig_status
|
||||
|
||||
The line status returned should be the same as the last time a SIGEVENT_SIGSTATUS_CHANGED was reported.
|
||||
|
|
@ -119,10 +119,8 @@ Global
|
|||
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.ActiveCfg = Release|x64
|
||||
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.Build.0 = Release|x64
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.Build.0 = Release|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|x64
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>mod_freetdm</ProjectName>
|
||||
<ProjectGuid>{FE3540C5-3303-46E0-A69E-D92F775687F1}</ProjectGuid>
|
||||
<RootNamespace>mod_freetdm</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(PlatformName)\$(Configuration)\mod\</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)$(PlatformName)\$(Configuration)\mod\</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)$(PlatformName)\$(Configuration)\mod\</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)$(PlatformName)\$(Configuration)\mod\</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>../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>FreeSwitch.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<ImportLibrary>$(OutDir)mod_freetdm.lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>FreeSwitch.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<ImportLibrary>$(OutDir)mod_freetdm.lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>FreeSwitchCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<ImportLibrary>$(OutDir)mod_freetdm.lib</ImportLibrary>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>FreeSwitchCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<ImportLibrary>$(OutDir)mod_freetdm.lib</ImportLibrary>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="mod_freetdm.c" />
|
||||
</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>
|
|
@ -0,0 +1,14 @@
|
|||
<?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;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="mod_freetdm.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -429,7 +429,7 @@ static switch_status_t channel_on_routing(switch_core_session_t *session)
|
|||
assert(tech_pvt->ftdmchan != NULL);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel));
|
||||
|
||||
|
||||
ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROCEED);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -802,7 +802,7 @@ static switch_status_t channel_receive_message_cas(switch_core_session_t *sessio
|
|||
phy_id = ftdm_channel_get_ph_id(tech_pvt->ftdmchan);
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Got Freeswitch message in R2 channel %d [%d]\n", phy_id, msg->message_id);
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -849,7 +849,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -892,7 +892,7 @@ static switch_status_t channel_receive_message_fxo(switch_core_session_t *sessio
|
|||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -924,7 +924,7 @@ static switch_status_t channel_receive_message_fxs(switch_core_session_t *sessio
|
|||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -981,7 +981,7 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
|
|||
switch (msg->message_id) {
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||
if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
if ((var = switch_channel_get_variable(channel, "freetdm_pre_buffer_size"))) {
|
||||
int tmp = atoi(var);
|
||||
if (tmp > -1) {
|
||||
|
@ -1136,6 +1136,10 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
direction = FTDM_BOTTOM_UP;
|
||||
} else if (*argv[1] == 'a') {
|
||||
direction = FTDM_TOP_DOWN;
|
||||
} else if (*argv[1] == 'r') {
|
||||
direction = FTDM_RR_DOWN;
|
||||
} else if (*argv[1] == 'R') {
|
||||
direction = FTDM_RR_UP;
|
||||
} else {
|
||||
chan_id = atoi(argv[1]);
|
||||
}
|
||||
|
@ -1278,6 +1282,10 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
caller_data.dnis.type = outbound_profile->destination_number_ton;
|
||||
}
|
||||
|
||||
if ((var = channel_get_variable(session, var_event, "freetdm_calling_party_category"))) {
|
||||
ftdm_set_calling_party_category(var, (uint8_t *)&caller_data.cpc);
|
||||
}
|
||||
|
||||
if ((var = channel_get_variable(session, var_event, "freetdm_custom_call_data"))) {
|
||||
ftdm_set_string(caller_data.raw_data, var);
|
||||
caller_data.raw_data_len = (uint32_t)strlen(var);
|
||||
|
@ -1329,7 +1337,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
char *v = h->name + FREETDM_VAR_PREFIX_LEN;
|
||||
if (!zstr(v)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s=%s to channel %d:%d\n", v, h->value, span_id, chan_id);
|
||||
ftdm_channel_add_var(ftdmchan, v, h->value);
|
||||
ftdm_call_add_var(&caller_data, v, h->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1363,7 +1371,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
tech_pvt->caller_profile = caller_profile;
|
||||
|
||||
|
||||
switch_channel_set_flag(channel, CF_OUTBOUND);
|
||||
switch_channel_set_state(channel, CS_INIT);
|
||||
if (ftdm_channel_add_token(ftdmchan, switch_core_session_get_uuid(*new_session), ftdm_channel_get_token_count(ftdmchan)) != FTDM_SUCCESS) {
|
||||
switch_core_session_destroy(new_session);
|
||||
|
@ -1528,6 +1535,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
|
|||
switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chanid);
|
||||
switch_channel_set_variable_printf(channel, "freetdm_bearer_capability", "%d", channel_caller_data->bearer_capability);
|
||||
switch_channel_set_variable_printf(channel, "freetdm_bearer_layer1", "%d", channel_caller_data->bearer_layer1);
|
||||
|
||||
if (globals.sip_headers) {
|
||||
switch_channel_set_variable(channel, "sip_h_X-FreeTDM-SpanName", ftdm_channel_get_span_name(sigmsg->channel));
|
||||
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-SpanNumber", "%d", spanid);
|
||||
|
@ -1561,8 +1569,18 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
|
|||
ftdm_channel_get_current_var(curr, &var_name, &var_value);
|
||||
snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name);
|
||||
switch_channel_set_variable_printf(channel, name, "%s", var_value);
|
||||
}
|
||||
|
||||
/* Add any call variable to the dial plan */
|
||||
iter = ftdm_call_get_var_iterator(channel_caller_data, iter);
|
||||
for (curr = iter ; curr; curr = ftdm_iterator_next(curr)) {
|
||||
ftdm_call_get_current_var(curr, &var_name, &var_value);
|
||||
snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name);
|
||||
switch_channel_set_variable_printf(channel, name, "%s", var_value);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s=%s\n", name, var_value);
|
||||
}
|
||||
ftdm_iterator_free(iter);
|
||||
|
||||
|
||||
switch_channel_set_state(channel, CS_INIT);
|
||||
if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
|
||||
|
@ -1661,11 +1679,11 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
|
|||
ftdm_status_t status;
|
||||
uint32_t spanid;
|
||||
uint32_t chanid;
|
||||
ftdm_caller_data_t *callerdata;
|
||||
ftdm_caller_data_t *caller_data;
|
||||
|
||||
spanid = ftdm_channel_get_span_id(sigmsg->channel);
|
||||
chanid = ftdm_channel_get_id(sigmsg->channel);
|
||||
callerdata = ftdm_channel_get_caller_data(sigmsg->channel);
|
||||
caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "got FXO sig %d:%d [%s]\n", spanid, chanid, ftdm_signal_event2str(sigmsg->event_id));
|
||||
|
||||
|
@ -1688,7 +1706,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
|
|||
switch_set_flag_locked(tech_pvt, TFLAG_DEAD);
|
||||
ftdm_channel_clear_token(sigmsg->channel, 0);
|
||||
channel = switch_core_session_get_channel(session);
|
||||
switch_channel_hangup(channel, callerdata->hangup_cause);
|
||||
switch_channel_hangup(channel, caller_data->hangup_cause);
|
||||
ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session));
|
||||
switch_core_session_rwunlock(session);
|
||||
}
|
||||
|
@ -1712,8 +1730,9 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
case FTDM_SIGEVENT_SIGSTATUS_CHANGED: { /* twiddle */ } break;
|
||||
|
||||
default:
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n",
|
||||
|
@ -1767,7 +1786,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
|
||||
case FTDM_SIGEVENT_STOP:
|
||||
{
|
||||
private_t *tech_pvt = NULL;
|
||||
|
@ -1799,7 +1819,9 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
|
|||
switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
|
||||
}
|
||||
|
||||
if (channel_a && channel_b && !switch_channel_test_flag(channel_a, CF_OUTBOUND) && !switch_channel_test_flag(channel_b, CF_OUTBOUND)) {
|
||||
if (channel_a && channel_b && switch_channel_direction(channel_a) == SWITCH_CALL_DIRECTION_INBOUND &&
|
||||
switch_channel_direction(channel_b) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
|
||||
cause = SWITCH_CAUSE_ATTENDED_TRANSFER;
|
||||
if (br_a_uuid && br_b_uuid) {
|
||||
switch_ivr_uuid_bridge(br_a_uuid, br_b_uuid);
|
||||
|
@ -1899,7 +1921,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
|
|||
case FTDM_SIGEVENT_COLLECTED_DIGIT:
|
||||
{
|
||||
int span_id = ftdm_channel_get_span_id(sigmsg->channel);
|
||||
char *dtmf = sigmsg->raw_data;
|
||||
char *dtmf = sigmsg->ev_data.collected.digits;
|
||||
char *regex = SPAN_CONFIG[span_id].dial_regex;
|
||||
char *fail_regex = SPAN_CONFIG[span_id].fail_dial_regex;
|
||||
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
|
||||
|
@ -1991,8 +2013,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
|
|||
}
|
||||
break;
|
||||
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
|
||||
/* on DNIS received from the R2 forward side, return status == FTDM_BREAK to stop requesting DNIS */
|
||||
case FTDM_SIGEVENT_COLLECTED_DIGIT:
|
||||
{
|
||||
|
@ -2065,7 +2087,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
|
|||
|
||||
case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
|
||||
{
|
||||
ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus;
|
||||
ftdm_signaling_status_t sigstatus = sigmsg->ev_data.sigstatus.status;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to: %s\n",
|
||||
spanid, chanid, ftdm_signaling_status2str(sigstatus));
|
||||
}
|
||||
|
@ -2104,14 +2126,14 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
|||
switch(sigmsg->event_id) {
|
||||
case FTDM_SIGEVENT_START:
|
||||
{
|
||||
ftdm_channel_add_var(sigmsg->channel, "screening_ind", ftdm_screening2str(caller_data->screen));
|
||||
ftdm_channel_add_var(sigmsg->channel, "presentation_ind", ftdm_presentation2str(caller_data->pres));
|
||||
ftdm_call_add_var(caller_data, "screening_ind", ftdm_screening2str(caller_data->screen));
|
||||
ftdm_call_add_var(caller_data, "presentation_ind", ftdm_presentation2str(caller_data->pres));
|
||||
return ftdm_channel_from_event(sigmsg, &session);
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
|
||||
case FTDM_SIGEVENT_STOP:
|
||||
case FTDM_SIGEVENT_RESTART:
|
||||
{
|
||||
|
@ -2155,6 +2177,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
|||
}
|
||||
break;
|
||||
case FTDM_SIGEVENT_PROGRESS:
|
||||
case FTDM_SIGEVENT_RINGING:
|
||||
{
|
||||
if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
|
||||
channel = switch_core_session_get_channel(session);
|
||||
|
@ -2170,13 +2193,13 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
|||
break;
|
||||
case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
|
||||
{
|
||||
ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus;
|
||||
ftdm_signaling_status_t sigstatus = sigmsg->ev_data.sigstatus.status;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to :%s\n",
|
||||
spanid, chanid, ftdm_signaling_status2str(sigstatus));
|
||||
}
|
||||
break;
|
||||
case FTDM_SIGEVENT_PROCEED:
|
||||
case FTDM_SIGEVENT_MSG:
|
||||
case FTDM_SIGEVENT_FACILITY:
|
||||
/* FS does not have handlers for these messages, so ignore them for now */
|
||||
break;
|
||||
default:
|
||||
|
@ -3513,7 +3536,19 @@ void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *
|
|||
switch_channel_cause2str(caller_data->hangup_cause));
|
||||
}
|
||||
|
||||
#define FT_SYNTAX "list || dump <span_id> [<chan_id>] || q931_pcap <span_id> on|off [pcapfilename without suffix] || gains <txgain> <rxgain> <span_id> [<chan_id>] || dtmf on|off <span_id> [<chan_id>]"
|
||||
#define FT_SYNTAX "USAGE:\n" \
|
||||
"--------------------------------------------------------------------------------\n" \
|
||||
"ftdm list\n" \
|
||||
"ftdm start|stop <span_name|span_id>\n" \
|
||||
"ftdm restart <span_id|span_name> <chan_id>\n" \
|
||||
"ftdm dump <span_id|span_name> [<chan_id>]\n" \
|
||||
"ftdm sigstatus get|set [<span_id|span_name>] [<channel>] [<sigstatus>]\n" \
|
||||
"ftdm trace <path> <span_id|span_name> [<chan_id>]\n" \
|
||||
"ftdm notrace <span_id|span_name> [<chan_id>]\n" \
|
||||
"ftdm q931_pcap <span_id> on|off [pcapfilename without suffix]\n" \
|
||||
"ftdm gains <txgain> <rxgain> <span_id> [<chan_id>]\n" \
|
||||
"ftdm dtmf on|off <span_id> [<chan_id>]\n" \
|
||||
"--------------------------------------------------------------------------------\n"
|
||||
SWITCH_STANDARD_API(ft_function)
|
||||
{
|
||||
char *mycmd = NULL, *argv[10] = { 0 };
|
||||
|
@ -3530,7 +3565,83 @@ SWITCH_STANDARD_API(ft_function)
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[0], "dump")) {
|
||||
if (!strcasecmp(argv[0], "sigstatus")) {
|
||||
ftdm_span_t *span = NULL;
|
||||
ftdm_signaling_status_t sigstatus;
|
||||
|
||||
if (argc < 3) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm sigstatus get|set [<span_id>] [<channel>] [<sigstatus>]\n");
|
||||
goto end;
|
||||
}
|
||||
if (!strcasecmp(argv[1], "get") && argc < 3) {
|
||||
stream->write_function(stream, "-ERR sigstatus get usage: get <span_id>\n");
|
||||
goto end;
|
||||
}
|
||||
if (!strcasecmp(argv[1], "set") && argc != 5) {
|
||||
stream->write_function(stream, "-ERR sigstatus set usage: set <span_id> <channel>|all <sigstatus>\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ftdm_span_find_by_name(argv[2], &span);
|
||||
if (!span) {
|
||||
stream->write_function(stream, "-ERR invalid span\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[1], "get")) {
|
||||
if (argc == 4) {
|
||||
uint32_t chan_id = atol(argv[3]);
|
||||
ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id);
|
||||
if (!fchan) {
|
||||
stream->write_function(stream, "-ERR failed to get channel id '%d'\n", chan_id);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((FTDM_SUCCESS == ftdm_channel_get_sig_status(fchan, &sigstatus))) {
|
||||
stream->write_function(stream, "channel %d signaling status: %s\n", chan_id, ftdm_signaling_status2str(sigstatus));
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR failed to get channel sigstatus\n");
|
||||
}
|
||||
goto end;
|
||||
} else {
|
||||
if ((FTDM_SUCCESS == ftdm_span_get_sig_status(span, &sigstatus))) {
|
||||
stream->write_function(stream, "signaling_status: %s\n", ftdm_signaling_status2str(sigstatus));
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR failed to read span status: %s\n", ftdm_span_get_last_error(span));
|
||||
}
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
if (!strcasecmp(argv[1], "set")) {
|
||||
sigstatus = ftdm_str2ftdm_signaling_status(argv[4]);
|
||||
|
||||
if (!strcasecmp(argv[3], "all")) {
|
||||
if ((FTDM_SUCCESS == ftdm_span_set_sig_status(span, sigstatus))) {
|
||||
stream->write_function(stream, "Signaling status of all channels from span %s set to %s\n",
|
||||
ftdm_span_get_name(span), ftdm_signaling_status2str(sigstatus));
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR failed to set span sigstatus to '%s'\n", ftdm_signaling_status2str(sigstatus));
|
||||
}
|
||||
goto end;
|
||||
} else {
|
||||
uint32_t chan_id = atol(argv[3]);
|
||||
ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id);
|
||||
if (!fchan) {
|
||||
stream->write_function(stream, "-ERR failed to get channel id '%d'\n", chan_id);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((FTDM_SUCCESS == ftdm_channel_set_sig_status(fchan, sigstatus))) {
|
||||
stream->write_function(stream, "Signaling status of channel %d set to %s\n", chan_id,
|
||||
ftdm_signaling_status2str(sigstatus));
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR failed to set span sigstatus to '%s'\n", ftdm_signaling_status2str(sigstatus));
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (!strcasecmp(argv[0], "dump")) {
|
||||
if (argc < 2) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm dump <span_id> [<chan_id>]\n");
|
||||
goto end;
|
||||
|
@ -3910,6 +4021,28 @@ SWITCH_STANDARD_API(ft_function)
|
|||
}
|
||||
}
|
||||
stream->write_function(stream, "+OK gains set to Rx %f and Tx %f\n", rxgain, txgain);
|
||||
} else if (!strcasecmp(argv[0], "restart")) {
|
||||
uint32_t chan_id = 0;
|
||||
ftdm_channel_t *chan;
|
||||
ftdm_span_t *span = NULL;
|
||||
if (argc < 3) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm restart <span_id> <chan_id>\n");
|
||||
goto end;
|
||||
}
|
||||
ftdm_span_find_by_name(argv[1], &span);
|
||||
if (!span) {
|
||||
stream->write_function(stream, "-ERR invalid span\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
chan_id = atoi(argv[2]);
|
||||
chan = ftdm_span_get_channel(span, chan_id);
|
||||
if (!chan) {
|
||||
stream->write_function(stream, "-ERR Could not find chan\n");
|
||||
goto end;
|
||||
}
|
||||
stream->write_function(stream, "Resetting channel %s:%s\n", argv[2], argv[3]);
|
||||
ftdm_channel_reset(chan);
|
||||
} else {
|
||||
|
||||
char *rply = ftdm_api_execute(cmd);
|
||||
|
|
|
@ -30,6 +30,12 @@
|
|||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
* Moises Silva <moy@sangoma.com>
|
||||
* Ricardo Barroetaveña <rbarroetavena@anura.com.ar>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "private/ftdm_core.h"
|
||||
|
@ -144,3 +150,20 @@ FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_set_calling_party_category(const char *string, uint8_t *target)
|
||||
{
|
||||
uint8_t val;
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
|
||||
val = ftdm_str2ftdm_calling_party_category(string);
|
||||
if (val == FTDM_CPC_INVALID) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid category string (%s)\n", string);
|
||||
val = FTDM_CPC_ORDINARY;
|
||||
status = FTDM_FAIL;
|
||||
}
|
||||
|
||||
*target = val;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -156,7 +156,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||
release_request_id((m3ua_request_id_t)ftdmchan->extra_id);
|
||||
ftdmchan->extra_id = 0;
|
||||
}
|
||||
ftdm_channel_done(ftdmchan);
|
||||
ftdm_channel_close(&ftdmchan);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
|
|
|
@ -96,6 +96,10 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_fxs_outgoing_call)
|
|||
|
||||
static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(analog_get_channel_sig_status)
|
||||
{
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM)) {
|
||||
*status = FTDM_SIG_STATE_DOWN;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
*status = FTDM_SIG_STATE_UP;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
@ -109,7 +113,25 @@ static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(analog_get_channel_sig_status)
|
|||
|
||||
static FIO_SPAN_GET_SIG_STATUS_FUNCTION(analog_get_span_sig_status)
|
||||
{
|
||||
*status = FTDM_SIG_STATE_UP;
|
||||
ftdm_iterator_t *citer = NULL;
|
||||
ftdm_iterator_t *chaniter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
if (!chaniter) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
/* if ALL channels are in alarm, report DOWN, UP otherwise. */
|
||||
*status = FTDM_SIG_STATE_DOWN;
|
||||
for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) {
|
||||
ftdm_channel_t *fchan = ftdm_iterator_current(citer);
|
||||
ftdm_channel_lock(fchan);
|
||||
if (!ftdm_test_flag(fchan, FTDM_CHANNEL_IN_ALARM)) {
|
||||
*status = FTDM_SIG_STATE_UP;
|
||||
ftdm_channel_unlock(fchan);
|
||||
break;
|
||||
}
|
||||
ftdm_channel_unlock(fchan);
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -491,9 +513,12 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_GENERATE_RING_OFF, NULL);
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) &&
|
||||
(ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE
|
||||
|| ftdmchan->last_state >= FTDM_CHANNEL_STATE_RING)) {
|
||||
if (ftdmchan->type == FTDM_CHAN_TYPE_FXS &&
|
||||
ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) &&
|
||||
(ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING
|
||||
|| ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE
|
||||
|| ftdmchan->last_state == FTDM_CHANNEL_STATE_RING
|
||||
|| ftdmchan->last_state == FTDM_CHANNEL_STATE_UP)) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
|
||||
} else {
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING;
|
||||
|
@ -716,7 +741,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||
dtmf_offset = strlen(dtmf);
|
||||
last_digit = elapsed;
|
||||
sig.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT;
|
||||
sig.raw_data = dtmf;
|
||||
ftdm_set_string(sig.ev_data.collected.digits, dtmf);
|
||||
if (ftdm_span_send_signal(ftdmchan->span, &sig) == FTDM_BREAK) {
|
||||
collecting = 0;
|
||||
}
|
||||
|
@ -883,14 +908,14 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
|
|||
{
|
||||
if (event->channel->type != FTDM_CHAN_TYPE_FXO) {
|
||||
ftdm_log_chan_msg(event->channel, FTDM_LOG_ERROR, "Cannot get a RING_START event on a non-fxo channel, please check your config.\n");
|
||||
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN);
|
||||
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN);
|
||||
goto end;
|
||||
}
|
||||
if (!event->channel->ring_count && (event->channel->state == FTDM_CHANNEL_STATE_DOWN && !ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD))) {
|
||||
if (ftdm_test_flag(analog_data, FTDM_ANALOG_CALLERID)) {
|
||||
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID);
|
||||
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID);
|
||||
} else {
|
||||
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_RING);
|
||||
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_RING);
|
||||
}
|
||||
event->channel->ring_count = 1;
|
||||
ftdm_mutex_unlock(event->channel->mutex);
|
||||
|
@ -908,7 +933,12 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
|
|||
}
|
||||
|
||||
if (event->channel->state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN);
|
||||
if (event->channel->state == FTDM_CHANNEL_STATE_HANGUP &&
|
||||
ftdm_test_flag(event->channel, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_clear_flag(event->channel, FTDM_CHANNEL_STATE_CHANGE);
|
||||
/* we do not need to process HANGUP since the device also hangup already */
|
||||
}
|
||||
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -916,16 +946,16 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
|
|||
case FTDM_OOB_FLASH:
|
||||
{
|
||||
if (event->channel->state == FTDM_CHANNEL_STATE_CALLWAITING) {
|
||||
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_UP);
|
||||
ftdm_clear_flag_locked(event->channel, FTDM_CHANNEL_STATE_CHANGE);
|
||||
ftdm_clear_flag_locked(event->channel->span, FTDM_SPAN_STATE_CHANGE);
|
||||
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_UP);
|
||||
ftdm_clear_flag(event->channel, FTDM_CHANNEL_STATE_CHANGE);
|
||||
ftdm_clear_flag(event->channel->span, FTDM_SPAN_STATE_CHANGE);
|
||||
event->channel->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK] = 0;
|
||||
}
|
||||
|
||||
ftdm_channel_rotate_tokens(event->channel);
|
||||
|
||||
if (ftdm_test_flag(event->channel, FTDM_CHANNEL_HOLD) && event->channel->token_count != 1) {
|
||||
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_UP);
|
||||
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_UP);
|
||||
} else {
|
||||
sig.event_id = FTDM_SIGEVENT_FLASH;
|
||||
ftdm_span_send_signal(span, &sig);
|
||||
|
@ -939,12 +969,12 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
|
|||
if (ftdm_test_flag(event->channel, FTDM_CHANNEL_RINGING)) {
|
||||
ftdm_channel_command(event->channel, FTDM_COMMAND_GENERATE_RING_OFF, NULL);
|
||||
}
|
||||
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_UP);
|
||||
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_UP);
|
||||
} else {
|
||||
if(!analog_data->max_dialstr) {
|
||||
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_COLLECT);
|
||||
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_COLLECT);
|
||||
} else {
|
||||
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DIALTONE);
|
||||
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DIALTONE);
|
||||
}
|
||||
ftdm_mutex_unlock(event->channel->mutex);
|
||||
locked = 0;
|
||||
|
@ -956,9 +986,24 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
|
|||
ftdm_channel_command(event->channel, FTDM_COMMAND_ONHOOK, NULL);
|
||||
}
|
||||
}
|
||||
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN);
|
||||
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_OOB_ALARM_TRAP:
|
||||
{
|
||||
sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sig.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal(span, &sig);
|
||||
}
|
||||
break;
|
||||
case FTDM_OOB_ALARM_CLEAR:
|
||||
{
|
||||
sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sig.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal(span, &sig);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ftdm_log_chan(event->channel, FTDM_LOG_DEBUG, "Ignoring event [%s] in state [%s]\n", ftdm_oob_event2str(event->enum_id), ftdm_channel_state2str(event->channel->state));
|
||||
|
|
|
@ -329,8 +329,8 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
|
|||
{
|
||||
if (state_counter > 500) {
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) &&
|
||||
(ftdmchan->last_state == FTDM_CHANNEL_STATE_RING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE
|
||||
|| ftdmchan->last_state >= FTDM_CHANNEL_STATE_IDLE)) {
|
||||
(ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE
|
||||
|| ftdmchan->last_state == FTDM_CHANNEL_STATE_RING)) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
|
||||
} else {
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING;
|
||||
|
@ -340,7 +340,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
|
|||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
case FTDM_CHANNEL_STATE_IDLE:
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
{
|
||||
ftdm_sleep(interval);
|
||||
continue;
|
||||
|
@ -386,7 +386,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
|
|||
ftdm_channel_use(ftdmchan);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_IDLE:
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
{
|
||||
ftdm_channel_use(ftdmchan);
|
||||
|
||||
|
@ -421,7 +421,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
|
|||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_WINK, NULL);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
{
|
||||
ftdm_buffer_zero(dt_buffer);
|
||||
teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]);
|
||||
|
@ -467,7 +467,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
|
|||
dtmf_offset = strlen(dtmf);
|
||||
last_digit = elapsed;
|
||||
sig.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT;
|
||||
sig.raw_data = dtmf;
|
||||
ftdm_set_string(sig.ev_data.collected.digits, dtmf);
|
||||
if (ftdm_span_send_signal(ftdmchan->span, &sig) == FTDM_BREAK) {
|
||||
collecting = 0;
|
||||
}
|
||||
|
@ -477,7 +477,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
|
|||
|
||||
if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) > analog_data->max_dialstr))) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Number obtained [%s]\n", dtmf);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
last_digit = 0;
|
||||
collecting = 0;
|
||||
}
|
||||
|
|
|
@ -1325,7 +1325,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
|
||||
}
|
||||
ftdm_channel_done(ftdmchan);
|
||||
ftdm_channel_close(&ftdmchan);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
|
|
|
@ -515,23 +515,17 @@ static __inline__ void state_advance(ftdm_channel_t *chan)
|
|||
switch (ftdm_channel_get_state(chan)) {
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
{
|
||||
ftdm_channel_t *chtmp = chan;
|
||||
chan->call_data = NULL;
|
||||
ftdm_channel_done(chan);
|
||||
|
||||
/*
|
||||
* Close channel completely, BRI PTMP will thank us
|
||||
*/
|
||||
if (ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
|
||||
ftdm_channel_t *chtmp = chan;
|
||||
if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Closed channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
}
|
||||
if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Closed channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1403,8 +1397,7 @@ static int on_dchan_up(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev
|
|||
sig.chan_id = ftdm_channel_get_id(chan);
|
||||
sig.channel = chan;
|
||||
sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sig.raw_data = &status;
|
||||
|
||||
sig.ev_data.sigstatus.status = status;
|
||||
ftdm_span_send_signal(span, &sig);
|
||||
}
|
||||
}
|
||||
|
@ -1440,7 +1433,7 @@ static int on_dchan_down(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_
|
|||
sig.chan_id = ftdm_channel_get_id(chan);
|
||||
sig.channel = chan;
|
||||
sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sig.raw_data = &status;
|
||||
sig.ev_data.sigstatus.status = status;
|
||||
|
||||
ftdm_span_send_signal(span, &sig);
|
||||
}
|
||||
|
|
|
@ -127,24 +127,24 @@ static int __pri_lpwrap_read(struct pri *pri, void *buf, int buflen)
|
|||
} else {
|
||||
ftdm_log(FTDM_LOG_CRIT, "span %d D-READ TIMEOUT\n", spri->span->span_id);
|
||||
}
|
||||
|
||||
ftdm_clear_flag(spri, LPWRAP_PRI_READY);
|
||||
return -1;
|
||||
/* we cannot return -1, libpri seems to expect values >= 0 */
|
||||
return 0;
|
||||
}
|
||||
spri->errs = 0;
|
||||
res = (int)len;
|
||||
|
||||
memset(&((unsigned char*)buf)[res], 0, 2);
|
||||
res += 2;
|
||||
|
||||
if (res > 0) {
|
||||
memset(&((unsigned char*)buf)[res], 0, 2);
|
||||
res += 2;
|
||||
#ifdef IODEBUG
|
||||
{
|
||||
char bb[2048] = { 0 };
|
||||
{
|
||||
char bb[2048] = { 0 };
|
||||
|
||||
print_hex_bytes(buf, res - 2, bb, sizeof(bb));
|
||||
ftdm_log(FTDM_LOG_DEBUG, "READ %d\n", res - 2);
|
||||
}
|
||||
print_hex_bytes(buf, res - 2, bb, sizeof(bb));
|
||||
ftdm_log(FTDM_LOG_DEBUG, "READ %d\n", res - 2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -155,8 +155,8 @@ static int __pri_lpwrap_write(struct pri *pri, void *buf, int buflen)
|
|||
|
||||
if (ftdm_channel_write(spri->dchan, buf, buflen, &len) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "span %d D-WRITE FAIL! [%s]\n", spri->span->span_id, spri->dchan->last_error);
|
||||
ftdm_clear_flag(spri, LPWRAP_PRI_READY);
|
||||
return -1;
|
||||
/* we cannot return -1, libpri seems to expect values >= 0 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef IODEBUG
|
||||
|
|
|
@ -280,12 +280,12 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
|||
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
{
|
||||
ftdm_channel_done(ftdmchan);
|
||||
{
|
||||
ftdmchan->call_data = NULL;
|
||||
ftdm_channel_close(&ftdmchan);
|
||||
|
||||
ftdm_channel_done(peerchan);
|
||||
peerchan->call_data = NULL;
|
||||
ftdm_channel_close(&peerchan);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -29,6 +29,12 @@
|
|||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
* Arnaldo Pereira <arnaldo@sangoma.com>
|
||||
* Ricardo Barroetaveña <rbarroetavena@anura.com.ar>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __linux__
|
||||
|
@ -44,16 +50,15 @@
|
|||
#include "freetdm.h"
|
||||
#include "private/ftdm_core.h"
|
||||
|
||||
/* debug thread count for r2 legs */
|
||||
static ftdm_mutex_t* g_thread_count_mutex;
|
||||
static int32_t g_thread_count = 0;
|
||||
|
||||
typedef int openr2_call_status_t;
|
||||
|
||||
/* when the users kills a span we clear this flag to kill the signaling thread */
|
||||
/* when the user stops a span, we clear FTDM_R2_SPAN_STARTED, so that the signaling thread
|
||||
* knows it must stop, and we wait for FTDM_R2_RUNNING to be clear, which tells us the
|
||||
* signaling thread is done. */
|
||||
/* FIXME: what about the calls that are already up-and-running? */
|
||||
typedef enum {
|
||||
FTDM_R2_RUNNING = (1 << 0),
|
||||
FTDM_R2_SPAN_STARTED = (1 << 1),
|
||||
} ftdm_r2_flag_t;
|
||||
|
||||
/* private call information stored in ftdmchan->call_data void* ptr,
|
||||
|
@ -250,7 +255,7 @@ static void ftdm_r2_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling
|
|||
sig.span_id = ftdmchan->span_id;
|
||||
sig.channel = ftdmchan;
|
||||
sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sig.sigstatus = status;
|
||||
sig.ev_data.sigstatus.status = status;
|
||||
if (ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to change channel status to %s\n", ftdm_signaling_status2str(status));
|
||||
}
|
||||
|
@ -372,11 +377,72 @@ static void ft_r2_answer_call(ftdm_channel_t *ftdmchan)
|
|||
R2CALL(ftdmchan)->answer_pending = 0;
|
||||
}
|
||||
|
||||
static __inline__ ftdm_calling_party_category_t ftdm_openr2_cpc_to_r2_ftdm_cpc(openr2_calling_party_category_t cpc)
|
||||
{
|
||||
switch (cpc) {
|
||||
case OR2_CALLING_PARTY_CATEGORY_UNKNOWN:
|
||||
return FTDM_CPC_UNKNOWN;
|
||||
|
||||
case OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER:
|
||||
return FTDM_CPC_ORDINARY;
|
||||
|
||||
case OR2_CALLING_PARTY_CATEGORY_NATIONAL_PRIORITY_SUBSCRIBER:
|
||||
return FTDM_CPC_PRIORITY;
|
||||
|
||||
case OR2_CALLING_PARTY_CATEGORY_INTERNATIONAL_SUBSCRIBER:
|
||||
return FTDM_CPC_UNKNOWN;
|
||||
|
||||
case OR2_CALLING_PARTY_CATEGORY_INTERNATIONAL_PRIORITY_SUBSCRIBER:
|
||||
return FTDM_CPC_UNKNOWN;
|
||||
|
||||
case OR2_CALLING_PARTY_CATEGORY_TEST_EQUIPMENT:
|
||||
return FTDM_CPC_TEST;
|
||||
|
||||
case OR2_CALLING_PARTY_CATEGORY_PAY_PHONE:
|
||||
return FTDM_CPC_PAYPHONE;
|
||||
|
||||
case OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL:
|
||||
return FTDM_CPC_OPERATOR;
|
||||
}
|
||||
return FTDM_CPC_INVALID;
|
||||
}
|
||||
|
||||
static __inline openr2_calling_party_category_t ftdm_r2_ftdm_cpc_to_openr2_cpc(ftdm_calling_party_category_t cpc)
|
||||
{
|
||||
switch (cpc) {
|
||||
case FTDM_CPC_UNKNOWN:
|
||||
return OR2_CALLING_PARTY_CATEGORY_UNKNOWN;
|
||||
|
||||
case FTDM_CPC_OPERATOR:
|
||||
return OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL;
|
||||
|
||||
case FTDM_CPC_ORDINARY:
|
||||
return OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
|
||||
|
||||
case FTDM_CPC_PRIORITY:
|
||||
return OR2_CALLING_PARTY_CATEGORY_NATIONAL_PRIORITY_SUBSCRIBER;
|
||||
|
||||
case FTDM_CPC_DATA:
|
||||
return OR2_CALLING_PARTY_CATEGORY_UNKNOWN;
|
||||
|
||||
case FTDM_CPC_TEST:
|
||||
return OR2_CALLING_PARTY_CATEGORY_TEST_EQUIPMENT;
|
||||
|
||||
case FTDM_CPC_PAYPHONE:
|
||||
return OR2_CALLING_PARTY_CATEGORY_PAY_PHONE;
|
||||
|
||||
case FTDM_CPC_INVALID:
|
||||
return OR2_CALLING_PARTY_CATEGORY_UNKNOWN;
|
||||
}
|
||||
return OR2_CALLING_PARTY_CATEGORY_UNKNOWN;
|
||||
}
|
||||
|
||||
/* this function must be called with the chan mutex held! */
|
||||
static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call)
|
||||
{
|
||||
openr2_call_status_t callstatus;
|
||||
ftdm_r2_data_t *r2data;
|
||||
openr2_calling_party_category_t category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
|
||||
|
||||
r2data = ftdmchan->span->signal_data;
|
||||
|
||||
|
@ -389,6 +455,12 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call)
|
|||
|
||||
ft_r2_clean_call(ftdmchan->call_data);
|
||||
|
||||
if (ftdmchan->caller_data.cpc == FTDM_CPC_INVALID || ftdmchan->caller_data.cpc == FTDM_CPC_UNKNOWN) {
|
||||
category = r2data->category;
|
||||
} else {
|
||||
category = ftdm_r2_ftdm_cpc_to_openr2_cpc(ftdmchan->caller_data.cpc);
|
||||
}
|
||||
|
||||
/* start io dump */
|
||||
if (r2data->mf_dump_size) {
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_INPUT_DUMP, &r2data->mf_dump_size);
|
||||
|
@ -396,9 +468,9 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call)
|
|||
}
|
||||
|
||||
callstatus = openr2_chan_make_call(R2CALL(ftdmchan)->r2chan,
|
||||
ftdmchan->caller_data.cid_num.digits,
|
||||
ftdmchan->caller_data.pres == FTDM_PRES_ALLOWED ? ftdmchan->caller_data.cid_num.digits : NULL,
|
||||
ftdmchan->caller_data.dnis.digits,
|
||||
r2data->category);
|
||||
category);
|
||||
|
||||
if (callstatus) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to make call in R2 channel, openr2_chan_make_call failed\n");
|
||||
|
@ -419,13 +491,14 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call)
|
|||
static ftdm_status_t ftdm_r2_start(ftdm_span_t *span)
|
||||
{
|
||||
ftdm_r2_data_t *r2_data = span->signal_data;
|
||||
ftdm_set_flag(r2_data, FTDM_R2_RUNNING);
|
||||
ftdm_set_flag(r2_data, FTDM_R2_SPAN_STARTED);
|
||||
return ftdm_thread_create_detached(ftdm_r2_run, span);
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdm_r2_stop(ftdm_span_t *span)
|
||||
{
|
||||
ftdm_r2_data_t *r2_data = span->signal_data;
|
||||
ftdm_clear_flag(r2_data, FTDM_R2_SPAN_STARTED);
|
||||
while (ftdm_test_flag(r2_data, FTDM_R2_RUNNING)) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Waiting for R2 span %s\n", span->name);
|
||||
ftdm_sleep(100);
|
||||
|
@ -444,6 +517,95 @@ static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_channel_sig_status)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status)
|
||||
{
|
||||
openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan;
|
||||
openr2_cas_signal_t rxcas, txcas;
|
||||
|
||||
/* get the current rx and tx cas bits */
|
||||
openr2_chan_get_cas(r2chan, &rxcas, &txcas);
|
||||
|
||||
/* if we're already in the state the user asks us to be, we have nothing to do */
|
||||
if (status == FTDM_SIG_STATE_SUSPENDED && txcas == OR2_CAS_BLOCK) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Channel signaling status already in BLOCK state\n");
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
if (status == FTDM_SIG_STATE_UP && txcas == OR2_CAS_IDLE) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Channel signaling status already in IDLE state\n");
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/* set the signaling as requested and send SIGEVENT_SIGSTATUS_CHANGED, if applicable.
|
||||
* see docs/sigstatus.txt for details */
|
||||
switch(status) {
|
||||
case FTDM_SIG_STATE_SUSPENDED:
|
||||
openr2_chan_set_blocked(r2chan);
|
||||
if (rxcas == OR2_CAS_IDLE) {
|
||||
ftdm_r2_set_chan_sig_status(ftdmchan, status);
|
||||
}
|
||||
break;
|
||||
case FTDM_SIG_STATE_UP:
|
||||
openr2_chan_set_idle(r2chan);
|
||||
if (rxcas == OR2_CAS_IDLE) {
|
||||
ftdm_r2_set_chan_sig_status(ftdmchan, status);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_span_sig_status)
|
||||
{
|
||||
ftdm_iterator_t *citer = NULL;
|
||||
ftdm_iterator_t *chaniter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
if (!chaniter) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
/* if ALL channels are non-idle, report SUSPENDED. UP otherwise. */
|
||||
*status = FTDM_SIG_STATE_SUSPENDED;
|
||||
for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) {
|
||||
ftdm_channel_t *fchan = ftdm_iterator_current(citer);
|
||||
ftdm_channel_lock(fchan);
|
||||
if (ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
*status = FTDM_SIG_STATE_UP;
|
||||
ftdm_channel_unlock(fchan);
|
||||
break;
|
||||
}
|
||||
ftdm_channel_unlock(fchan);
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status)
|
||||
{
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *citer = NULL;
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
if (!chaniter) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
/* iterate over all channels, setting them to the requested state */
|
||||
for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) {
|
||||
ftdm_channel_t *fchan = ftdm_iterator_current(citer);
|
||||
/* we set channel's state through ftdm_r2_set_channel_sig_status(), since it already takes
|
||||
* care of notifying the user when appropriate */
|
||||
ftdm_channel_lock(fchan);
|
||||
if ((ftdm_r2_set_channel_sig_status(fchan, status)) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan(fchan, FTDM_LOG_ERROR, "Failed to set signaling status to %s\n", ftdm_signaling_status2str(status));
|
||||
}
|
||||
ftdm_channel_unlock(fchan);
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/* always called from the monitor thread */
|
||||
static void ftdm_r2_on_call_init(openr2_chan_t *r2chan)
|
||||
{
|
||||
|
@ -510,13 +672,21 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons
|
|||
ftdm_r2_data_t *r2data = ftdmchan->span->signal_data;
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Call offered with ANI = %s, DNIS = %s, Category = (%d)\n", ani, dnis, category);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
|
||||
/* nothing went wrong during call setup, MF has ended, we can and must disable the MF dump */
|
||||
if (r2data->mf_dump_size) {
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL);
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL);
|
||||
}
|
||||
|
||||
/* check if this is a collect call and if we should accept it */
|
||||
if (!r2data->allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Rejecting collect call\n");
|
||||
openr2_chan_disconnect_call(r2chan, OR2_CAUSE_COLLECT_CALL_REJECTED);
|
||||
} else {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
}
|
||||
ftdmchan->caller_data.cpc = ftdm_openr2_cpc_to_r2_ftdm_cpc(category);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -556,14 +726,14 @@ static void dump_mf(openr2_chan_t *r2chan)
|
|||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO output in prefix %s\n", logname);
|
||||
snprintf(dfile, sizeof(dfile), logname ? "%s.s%dc%d.input.alaw" : "%s/s%dc%d.input.alaw",
|
||||
logname ? logname : r2data->logdir, ftdmchan->span_id, ftdmchan->chan_id);
|
||||
f = fopen(dfile, "w");
|
||||
f = fopen(dfile, "wb");
|
||||
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);
|
||||
|
||||
snprintf(dfile, sizeof(dfile), logname ? "%s.s%dc%d.output.alaw" : "%s/s%dc%d.output.alaw",
|
||||
logname ? logname : r2data->logdir, ftdmchan->span_id, ftdmchan->chan_id);
|
||||
f = fopen(dfile, "w");
|
||||
f = fopen(dfile, "wb");
|
||||
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);
|
||||
|
@ -573,6 +743,8 @@ static void dump_mf(openr2_chan_t *r2chan)
|
|||
static void ftdm_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
|
||||
{
|
||||
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
|
||||
ftdm_r2_data_t *r2data = ftdmchan->span->signal_data;
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Call accepted\n");
|
||||
|
||||
clear_accept_pending(ftdmchan);
|
||||
|
@ -595,6 +767,11 @@ static void ftdm_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t m
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
/* nothing went wrong during call setup, MF has ended, we can and must disable the MF dump */
|
||||
if (r2data->mf_dump_size) {
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL);
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL);
|
||||
}
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
}
|
||||
}
|
||||
|
@ -653,7 +830,7 @@ static void ftdm_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf
|
|||
static void ftdm_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm)
|
||||
{
|
||||
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Alarm notification: %d\n", alarm);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Alarm notification: %d\n", alarm);
|
||||
}
|
||||
|
||||
static void ftdm_r2_on_os_error(openr2_chan_t *r2chan, int errorcode)
|
||||
|
@ -895,7 +1072,7 @@ static int ftdm_r2_io_write(openr2_chan_t *r2chan, const void *buf, int size)
|
|||
if (FTDM_FAIL == status) {
|
||||
return -1;
|
||||
}
|
||||
return outsize;
|
||||
return (int)outsize;
|
||||
}
|
||||
|
||||
static int ftdm_r2_io_read(openr2_chan_t *r2chan, const void *buf, int size)
|
||||
|
@ -906,7 +1083,7 @@ static int ftdm_r2_io_read(openr2_chan_t *r2chan, const void *buf, int size)
|
|||
if (FTDM_FAIL == status) {
|
||||
return -1;
|
||||
}
|
||||
return outsize;
|
||||
return (int)outsize;
|
||||
}
|
||||
|
||||
static int ftdm_r2_io_wait(openr2_chan_t *r2chan, int *flags, int block)
|
||||
|
@ -988,6 +1165,10 @@ static int ftdm_r2_io_get_oob_event(openr2_chan_t *r2chan, openr2_oob_event_t *e
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (fevent->e_type != FTDM_EVENT_OOB) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (fevent->enum_id) {
|
||||
case FTDM_OOB_CAS_BITS_CHANGE:
|
||||
{
|
||||
|
@ -1396,13 +1577,14 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling)
|
|||
span->sig_read = NULL;
|
||||
span->sig_write = NULL;
|
||||
|
||||
/* let the core set the states, we just read them */
|
||||
span->get_channel_sig_status = ftdm_r2_get_channel_sig_status;
|
||||
|
||||
span->signal_cb = sig_cb;
|
||||
span->signal_type = FTDM_SIGTYPE_R2;
|
||||
span->signal_data = r2data;
|
||||
span->outgoing_call = r2_outgoing_call;
|
||||
span->get_span_sig_status = ftdm_r2_get_span_sig_status;
|
||||
span->set_span_sig_status = ftdm_r2_set_span_sig_status;
|
||||
span->get_channel_sig_status = ftdm_r2_get_channel_sig_status;
|
||||
span->set_channel_sig_status = ftdm_r2_set_channel_sig_status;
|
||||
|
||||
span->state_map = &r2_state_map;
|
||||
|
||||
|
@ -1593,6 +1775,13 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
break;
|
||||
|
||||
/* INDICATE_RINGING doesn't apply to MFC/R2. maybe we could generate a tone */
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
{
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "RINGING indicated, ignoring it as it doesn't apply to MFC/R2\n");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Unhandled channel state change: %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
@ -1639,9 +1828,13 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
|||
int index = 0;
|
||||
struct timeval start, end;
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *citer = NULL;
|
||||
uint32_t txqueue_size = 4;
|
||||
short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count);
|
||||
|
||||
/* as long as this thread is running, this flag is set */
|
||||
ftdm_set_flag(r2data, FTDM_R2_RUNNING);
|
||||
|
||||
#ifdef __linux__
|
||||
r2data->monitor_thread_id = syscall(SYS_gettid);
|
||||
#endif
|
||||
|
@ -1649,8 +1842,12 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
|||
ftdm_log(FTDM_LOG_DEBUG, "OpenR2 monitor thread %lu started.\n", r2data->monitor_thread_id);
|
||||
r2chan = NULL;
|
||||
chaniter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
for (i = 1; chaniter; chaniter = ftdm_iterator_next(chaniter), i++) {
|
||||
ftdmchan = ftdm_iterator_current(chaniter);
|
||||
if (!chaniter) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
|
||||
goto done;
|
||||
}
|
||||
for (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) {
|
||||
ftdmchan = ftdm_iterator_current(citer);
|
||||
r2chan = R2CALL(ftdmchan)->r2chan;
|
||||
openr2_chan_set_span_id(r2chan, span->span_id);
|
||||
openr2_chan_set_idle(r2chan);
|
||||
|
@ -1660,7 +1857,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
|||
|
||||
memset(&start, 0, sizeof(start));
|
||||
memset(&end, 0, sizeof(end));
|
||||
while (ftdm_running() && ftdm_test_flag(r2data, FTDM_R2_RUNNING)) {
|
||||
while (ftdm_running() && ftdm_test_flag(r2data, FTDM_R2_SPAN_STARTED)) {
|
||||
res = gettimeofday(&end, NULL);
|
||||
if (res) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failure gettimeofday [%s]\n", strerror(errno));
|
||||
|
@ -1685,24 +1882,24 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
|||
|
||||
/* deliver the actual channel events to the user now without any channel locking */
|
||||
ftdm_span_trigger_signals(span);
|
||||
#ifndef WIN32
|
||||
|
||||
/* figure out what event to poll each channel for. POLLPRI when the channel is down,
|
||||
* POLLPRI|POLLIN|POLLOUT otherwise */
|
||||
memset(poll_events, 0, sizeof(short)*span->chan_count);
|
||||
chaniter = ftdm_span_get_chan_iterator(span, chaniter);
|
||||
for (i = 0; chaniter; chaniter = ftdm_iterator_next(chaniter), i++) {
|
||||
ftdmchan = ftdm_iterator_current(chaniter);
|
||||
citer = ftdm_span_get_chan_iterator(span, chaniter);
|
||||
if (!citer) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name);
|
||||
goto done;
|
||||
}
|
||||
for (i = 0; citer; citer = ftdm_iterator_next(citer), i++) {
|
||||
ftdmchan = ftdm_iterator_current(citer);
|
||||
r2chan = R2CALL(ftdmchan)->r2chan;
|
||||
poll_events[i] = POLLPRI;
|
||||
poll_events[i] = FTDM_EVENTS;
|
||||
if (openr2_chan_get_read_enabled(r2chan)) {
|
||||
poll_events[i] |= POLLIN;
|
||||
poll_events[i] |= FTDM_READ;
|
||||
}
|
||||
}
|
||||
|
||||
status = ftdm_span_poll_event(span, waitms, poll_events);
|
||||
#else
|
||||
status = ftdm_span_poll_event(span, waitms, NULL);
|
||||
#endif
|
||||
|
||||
/* run any span timers */
|
||||
ftdm_sched_run(r2data->sched);
|
||||
|
@ -1732,9 +1929,9 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
|||
|
||||
/* this main loop takes care of MF and CAS signaling during call setup and tear down
|
||||
* for every single channel in the span, do not perform blocking operations here! */
|
||||
chaniter = ftdm_span_get_chan_iterator(span, chaniter);
|
||||
for ( ; chaniter; chaniter = ftdm_iterator_next(chaniter)) {
|
||||
ftdmchan = ftdm_iterator_current(chaniter);
|
||||
citer = ftdm_span_get_chan_iterator(span, chaniter);
|
||||
for ( ; citer; citer = ftdm_iterator_next(citer)) {
|
||||
ftdmchan = ftdm_iterator_current(citer);
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
|
@ -1761,10 +1958,11 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
|||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(span, chaniter);
|
||||
for ( ; chaniter; chaniter = ftdm_iterator_next(chaniter)) {
|
||||
ftdmchan = ftdm_iterator_current(chaniter);
|
||||
|
||||
done:
|
||||
citer = ftdm_span_get_chan_iterator(span, chaniter);
|
||||
for ( ; citer; citer = ftdm_iterator_next(citer)) {
|
||||
ftdmchan = ftdm_iterator_current(citer);
|
||||
r2chan = R2CALL(ftdmchan)->r2chan;
|
||||
openr2_chan_set_blocked(r2chan);
|
||||
}
|
||||
|
@ -1821,6 +2019,14 @@ static void __inline__ unblock_channel(ftdm_channel_t *fchan, ftdm_stream_handle
|
|||
ftdm_mutex_unlock(fchan->mutex);
|
||||
}
|
||||
|
||||
#define FT_SYNTAX "USAGE:\n" \
|
||||
"--------------------------------------------------------------------------------\n" \
|
||||
"ftdm r2 status <span_id|span_name>\n" \
|
||||
"ftdm r2 loopstats <span_id|span_name>\n" \
|
||||
"ftdm r2 block|unblock <span_id|span_name> [<chan_id>]\n" \
|
||||
"ftdm r2 version\n" \
|
||||
"ftdm r2 variants\n" \
|
||||
"--------------------------------------------------------------------------------\n"
|
||||
static FIO_API_FUNCTION(ftdm_r2_api)
|
||||
{
|
||||
ftdm_span_t *span = NULL;
|
||||
|
@ -1922,7 +2128,7 @@ static FIO_API_FUNCTION(ftdm_r2_api)
|
|||
"Max DNIS: %d\n"
|
||||
"ANI First: %s\n"
|
||||
"Immediate Accept: %s\n"
|
||||
"Job Thread: %lu\n"
|
||||
"Job Thread: %u\n"
|
||||
"Job Max ms: %d\n"
|
||||
"Job Loops: %lu\n",
|
||||
openr2_proto_get_variant_string(r2variant),
|
||||
|
@ -2004,14 +2210,6 @@ static FIO_API_FUNCTION(ftdm_r2_api)
|
|||
}
|
||||
|
||||
if (argc == 1) {
|
||||
if (!strcasecmp(argv[0], "threads")) {
|
||||
ftdm_mutex_lock(g_thread_count_mutex);
|
||||
stream->write_function(stream, "%d R2 channel threads up\n", g_thread_count);
|
||||
ftdm_mutex_unlock(g_thread_count_mutex);
|
||||
stream->write_function(stream, "+OK.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[0], "version")) {
|
||||
stream->write_function(stream, "OpenR2 version: %s, revision: %s\n", openr2_get_version(), openr2_get_revision());
|
||||
stream->write_function(stream, "+OK.\n");
|
||||
|
@ -2037,7 +2235,7 @@ static FIO_API_FUNCTION(ftdm_r2_api)
|
|||
}
|
||||
}
|
||||
|
||||
stream->write_function(stream, "-ERR invalid command.\n");
|
||||
stream->write_function(stream, "%s", FT_SYNTAX);
|
||||
|
||||
done:
|
||||
|
||||
|
@ -2066,7 +2264,6 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_r2_init)
|
|||
if (!g_mod_data_hash) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
ftdm_mutex_create(&g_thread_count_mutex);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2086,7 +2283,6 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_r2_destroy)
|
|||
}
|
||||
}
|
||||
hashtable_destroy(g_mod_data_hash);
|
||||
ftdm_mutex_destroy(&g_thread_count_mutex);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -839,7 +839,7 @@ static void handle_call_released(ftdm_span_t *span, sangomabc_connection_t *mcon
|
|||
if ((ftdmchan = find_ftdmchan(span, event, 1))) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Releasing completely chan s%dc%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event),
|
||||
BOOST_EVENT_CHAN(mcon->sigmod, event));
|
||||
ftdm_channel_done(ftdmchan);
|
||||
ftdm_channel_close(&ftdmchan);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Odd, We could not find chan: s%dc%d to release the call completely!!\n",
|
||||
BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event));
|
||||
|
@ -1105,8 +1105,9 @@ static void handle_call_loop_start(ftdm_span_t *span, sangomabc_connection_t *mc
|
|||
|
||||
ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP, res);
|
||||
if (res != FTDM_SUCCESS) {
|
||||
ftdm_channel_t *toclose = ftdmchan;
|
||||
ftdm_log(FTDM_LOG_CRIT, "yay, could not set the state of the channel to IN_LOOP, loop will fail\n");
|
||||
ftdm_channel_done(ftdmchan);
|
||||
ftdm_channel_close(&toclose);
|
||||
return;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%d:%d starting loop\n", ftdmchan->span_id, ftdmchan->chan_id);
|
||||
|
@ -1426,11 +1427,12 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
|
|||
ftdmchan->sflags = 0;
|
||||
memset(ftdmchan->call_data, 0, sizeof(sangoma_boost_call_t));
|
||||
if (sangoma_boost_data->sigmod && call_stopped_ack_sent) {
|
||||
/* we dont want to call ftdm_channel_done just yet until call released is received */
|
||||
/* we dont want to call ftdm_channel_close just yet until call released is received */
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Waiting for call release confirmation before declaring chan %d:%d as available \n",
|
||||
ftdmchan->span_id, ftdmchan->chan_id);
|
||||
} else {
|
||||
ftdm_channel_done(ftdmchan);
|
||||
ftdm_channel_t *toclose = ftdmchan;
|
||||
ftdm_channel_close(&toclose);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2476,7 +2478,7 @@ static BOOST_SIG_STATUS_CB_FUNCTION(ftdm_boost_sig_status_change)
|
|||
sig.span_id = ftdmchan->span_id;
|
||||
sig.channel = ftdmchan;
|
||||
sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sig.raw_data = &status;
|
||||
sig.ev_data.sigstatus.status = status;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sig);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#if HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
|
|
@ -65,7 +65,13 @@ ftdm_state_map_t sangoma_isdn_state_map = {
|
|||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_ANY_STATE, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_SUSPENDED, FTDM_END}
|
||||
{FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_RESTART, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_RESET, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_DOWN, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
|
@ -170,7 +176,13 @@ ftdm_state_map_t sangoma_isdn_state_map = {
|
|||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_ANY_STATE, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
|
||||
{FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_RESET, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_DOWN, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
|
@ -203,7 +215,7 @@ ftdm_state_map_t sangoma_isdn_state_map = {
|
|||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_DIALING, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
|
||||
FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP,
|
||||
FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP,
|
||||
FTDM_CHANNEL_STATE_DOWN, FTDM_END}
|
||||
},
|
||||
{
|
||||
|
@ -211,14 +223,20 @@ ftdm_state_map_t sangoma_isdn_state_map = {
|
|||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_PROCEED, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
|
||||
FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
|
||||
},
|
||||
FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
|
||||
},
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
|
||||
},
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_RINGING, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
|
||||
},
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
|
@ -626,8 +644,11 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
case FTDM_CHANNEL_STATE_GET_CALLERID:
|
||||
{
|
||||
if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) {
|
||||
/* By default, we do not send a progress indicator in the proceed */
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID};
|
||||
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED);
|
||||
sngisdn_snd_proceed(ftdmchan);
|
||||
sngisdn_snd_proceed(ftdmchan, prog_ind);
|
||||
}
|
||||
/* Wait in this state until we get FACILITY msg */
|
||||
}
|
||||
|
@ -666,16 +687,28 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
} else {
|
||||
if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) {
|
||||
/* By default, we do not send a progress indicator in the proceed */
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID};
|
||||
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED);
|
||||
sngisdn_snd_proceed(ftdmchan);
|
||||
sngisdn_snd_proceed(ftdmchan, prog_ind);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
{
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
|
||||
sngisdn_snd_alert(ftdmchan, prog_ind);
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
/* OUTBOUND...so we were told by the line of this so notify the user */
|
||||
sigev.event_id = FTDM_SIGEVENT_RINGING;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
}
|
||||
} else {
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
|
||||
sngisdn_snd_alert(ftdmchan, prog_ind);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
|
@ -686,12 +719,9 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
sigev.event_id = FTDM_SIGEVENT_PROGRESS;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
} else {
|
||||
/* If we already sent a PROCEED before, do not send a PROGRESS as there is nothing to indicate to the remote switch */
|
||||
if (ftdmchan->last_state != FTDM_CHANNEL_STATE_PROCEED) {
|
||||
/* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
|
||||
sngisdn_snd_progress(ftdmchan, prog_ind);
|
||||
}
|
||||
/* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
|
||||
sngisdn_snd_progress(ftdmchan, prog_ind);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -774,7 +804,7 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
sngisdn_snd_release(ftdmchan, 0);
|
||||
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
|
||||
sngisdn_set_span_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
|
||||
}
|
||||
} else {
|
||||
sngisdn_snd_disconnect(ftdmchan);
|
||||
|
@ -832,6 +862,11 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
/* IMPLEMENT ME */
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
{
|
||||
sngisdn_snd_restart(ftdmchan);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "unsupported sngisdn_rcvd state %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
@ -851,6 +886,22 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
return;
|
||||
}
|
||||
|
||||
static FIO_CHANNEL_SEND_MSG_FUNCTION(ftdm_sangoma_isdn_send_msg)
|
||||
{
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
|
||||
switch (sigmsg->event_id) {
|
||||
case FTDM_SIGEVENT_FACILITY:
|
||||
sngisdn_snd_fac_req(ftdmchan);
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Unsupported signalling msg requested\n");
|
||||
status = FTDM_BREAK;
|
||||
}
|
||||
ftdm_call_clear_data(&ftdmchan->caller_data);
|
||||
return status;
|
||||
}
|
||||
|
||||
static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_isdn_outgoing_call)
|
||||
{
|
||||
sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
|
||||
|
@ -925,7 +976,8 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_span_sig_status)
|
|||
}
|
||||
|
||||
static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
|
||||
{
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = span->signal_data;
|
||||
ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id);
|
||||
if (sngisdn_stack_start(span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name);
|
||||
|
@ -935,6 +987,14 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
|
|||
ftdm_clear_flag(span, FTDM_SPAN_STOP_THREAD);
|
||||
ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD);
|
||||
|
||||
if (signal_data->raw_trace_q921 == SNGISDN_OPT_TRUE) {
|
||||
sngisdn_activate_trace(span, SNGISDN_TRACE_Q921);
|
||||
}
|
||||
|
||||
if (signal_data->raw_trace_q931 == SNGISDN_OPT_TRUE) {
|
||||
sngisdn_activate_trace(span, SNGISDN_TRACE_Q931);
|
||||
}
|
||||
|
||||
/*start the span monitor thread*/
|
||||
if (ftdm_thread_create_detached(ftdm_sangoma_isdn_run, span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT,"Failed to start Sangoma ISDN Span Monitor Thread!\n");
|
||||
|
@ -1030,6 +1090,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
|
|||
span->stop = ftdm_sangoma_isdn_stop;
|
||||
span->signal_type = FTDM_SIGTYPE_ISDN;
|
||||
span->outgoing_call = ftdm_sangoma_isdn_outgoing_call;
|
||||
span->send_msg = ftdm_sangoma_isdn_send_msg;
|
||||
span->channel_request = NULL;
|
||||
span->signal_cb = sig_cb;
|
||||
span->get_channel_sig_status = ftdm_sangoma_isdn_get_chan_sig_status;
|
||||
|
@ -1040,11 +1101,12 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
|
|||
ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE);
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE);
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_PROCEED_STATE);
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_SKIP_STATES);
|
||||
|
||||
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP ||
|
||||
span->trunk_type == FTDM_TRUNK_BRI) {
|
||||
|
||||
sngisdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
|
||||
sngisdn_set_span_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
|
||||
}
|
||||
|
||||
/* Initialize scheduling context */
|
||||
|
@ -1139,6 +1201,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* TODO: Move functions to table + function pointers */
|
||||
if (!strcasecmp(argv[0], "trace")) {
|
||||
char *trace_opt;
|
||||
|
||||
|
@ -1156,6 +1219,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
|
|||
stream->write_function(stream, "-ERR failed to find span by name %s\n", argv[2]);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!strcasecmp(trace_opt, "q921")) {
|
||||
sngisdn_activate_trace(span, SNGISDN_TRACE_Q921);
|
||||
} else if (!strcasecmp(trace_opt, "q931")) {
|
||||
|
@ -1164,7 +1228,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
|
|||
sngisdn_activate_trace(span, SNGISDN_TRACE_DISABLE);
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR invalid trace option <q921|q931> <span name>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!strcasecmp(argv[0], "l1_stats")) {
|
||||
ftdm_span_t *span;
|
||||
|
@ -1182,7 +1246,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
|
|||
}
|
||||
sngisdn_print_phy_stats(stream, span);
|
||||
}
|
||||
|
||||
|
||||
if (!strcasecmp(argv[0], "show_spans")) {
|
||||
ftdm_span_t *span = NULL;
|
||||
if (argc == 2) {
|
||||
|
|
|
@ -101,9 +101,11 @@ typedef enum {
|
|||
FLAG_GLARE = (1 << 6),
|
||||
FLAG_DELAYED_REL = (1 << 7),
|
||||
FLAG_SENT_PROCEED = (1 << 8),
|
||||
FLAG_SEND_DISC = (1 << 9),
|
||||
FLAG_SEND_DISC = (1 << 9),
|
||||
/* Used for BRI only, flag is set after we request line CONNECTED */
|
||||
FLAG_ACTIVATING = (1 << 10),
|
||||
FLAG_ACTIVATING = (1 << 10),
|
||||
/* Used when we receive an ALERT msg + inband tones ready */
|
||||
FLAG_MEDIA_READY = (1 << 11),
|
||||
} sngisdn_flag_t;
|
||||
|
||||
|
||||
|
@ -259,6 +261,8 @@ typedef struct sngisdn_span_data {
|
|||
int8_t facility_timeout;
|
||||
uint8_t num_local_numbers;
|
||||
uint8_t ignore_cause_value;
|
||||
uint8_t raw_trace_q931;
|
||||
uint8_t raw_trace_q921;
|
||||
uint8_t timer_t3;
|
||||
uint8_t restart_opt;
|
||||
char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS];
|
||||
|
@ -352,8 +356,11 @@ void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info);
|
|||
ftdm_status_t get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data);
|
||||
ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data);
|
||||
|
||||
ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail);
|
||||
ftdm_status_t sngisdn_set_chan_avail_rate(ftdm_channel_t *chan, sngisdn_avail_t avail);
|
||||
void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status);
|
||||
void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status);
|
||||
|
||||
ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail);
|
||||
ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt);
|
||||
|
||||
|
||||
|
@ -363,7 +370,7 @@ void stack_pst_init(Pst *pst);
|
|||
/* Outbound Call Control functions */
|
||||
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind);
|
||||
void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind);
|
||||
void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind);
|
||||
void sngisdn_snd_connect(ftdm_channel_t *ftdmchan);
|
||||
|
@ -374,6 +381,7 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan);
|
|||
void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_restart(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len);
|
||||
void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event);
|
||||
|
||||
|
@ -421,8 +429,11 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event);
|
|||
void sngisdn_rcv_phy_ind(SuId suId, Reason reason);
|
||||
void sngisdn_rcv_q921_ind(BdMngmt *status);
|
||||
|
||||
void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len);
|
||||
void sngisdn_trace_q931(char* str, uint8_t* data, uint32_t data_len);
|
||||
void sngisdn_trace_interpreted_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len);
|
||||
void sngisdn_trace_interpreted_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len);
|
||||
void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len);
|
||||
void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len);
|
||||
|
||||
void get_memory_info(void);
|
||||
|
||||
ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt);
|
||||
|
@ -436,6 +447,7 @@ void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...);
|
|||
void sngisdn_rcv_sng_assert(char *message);
|
||||
|
||||
ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb);
|
||||
ftdm_status_t get_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb);
|
||||
ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb);
|
||||
ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb);
|
||||
ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *display);
|
||||
|
@ -443,16 +455,20 @@ ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *us
|
|||
ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad);
|
||||
ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd);
|
||||
ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr);
|
||||
ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t data_len);
|
||||
ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t data_len);
|
||||
|
||||
ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb);
|
||||
ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb);
|
||||
ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb);
|
||||
ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb);
|
||||
ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt);
|
||||
ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad);
|
||||
ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind);
|
||||
ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap);
|
||||
ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId);
|
||||
ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd);
|
||||
ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr);
|
||||
ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t *data_len);
|
||||
ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t *data_len);
|
||||
|
||||
|
||||
uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability);
|
||||
|
@ -480,7 +496,6 @@ static __inline__ void sngisdn_set_flag(sngisdn_chan_data_t *sngisdn_info, sngis
|
|||
|
||||
|
||||
void handle_sng_log(uint8_t level, char *fmt,...);
|
||||
void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status);
|
||||
void sngisdn_delayed_setup(void* p_sngisdn_info);
|
||||
void sngisdn_delayed_release(void* p_sngisdn_info);
|
||||
void sngisdn_delayed_connect(void* p_sngisdn_info);
|
||||
|
|
|
@ -296,6 +296,10 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
parse_yesno(var, val, &signal_data->facility_ie_decode);
|
||||
} else if (!strcasecmp(var, "ignore-cause-value")) {
|
||||
parse_yesno(var, val, &signal_data->ignore_cause_value);
|
||||
} else if (!strcasecmp(var, "q931-raw-trace")) {
|
||||
parse_yesno(var, val, &signal_data->raw_trace_q931);
|
||||
} else if (!strcasecmp(var, "q921-raw-trace")) {
|
||||
parse_yesno(var, val, &signal_data->raw_trace_q921);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var);
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status
|
|||
sig.span_id = ftdmchan->span_id;
|
||||
sig.channel = ftdmchan;
|
||||
sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sig.sigstatus = status;
|
||||
sig.ev_data.sigstatus.status = status;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sig);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,8 @@
|
|||
*/
|
||||
|
||||
#include "ftmod_sangoma_isdn.h"
|
||||
ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn);
|
||||
static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn);
|
||||
static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan);
|
||||
|
||||
/* Remote side transmit a SETUP */
|
||||
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
||||
|
@ -123,12 +124,9 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Export ftdmchan variables here if we need to */
|
||||
ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1");
|
||||
#endif
|
||||
/* Fill in call information */
|
||||
get_calling_num(ftdmchan, &conEvnt->cgPtyNmb);
|
||||
get_calling_num2(ftdmchan, &conEvnt->cgPtyNmb2);
|
||||
get_called_num(ftdmchan, &conEvnt->cdPtyNmb);
|
||||
get_redir_num(ftdmchan, &conEvnt->redirNmb);
|
||||
get_calling_subaddr(ftdmchan, &conEvnt->cgPtySad);
|
||||
|
@ -235,6 +233,9 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing SETUP in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
break;
|
||||
|
@ -277,6 +278,7 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
|
@ -288,6 +290,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
case FTDM_CHANNEL_STATE_HANGUP:
|
||||
/* Race condition, we just hung up the call - ignore this message */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
|
@ -304,6 +309,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
/* Race condition, We just hung up an incoming call right after we sent a CONNECT - ignore this message */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
|
@ -357,27 +365,47 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
goto sngisdn_process_cnst_ind_end;
|
||||
}
|
||||
|
||||
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
} else if (evntType == MI_CALLPROC) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED);
|
||||
} else {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY);
|
||||
}
|
||||
switch (evntType) {
|
||||
case MI_CALLPROC:
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED);
|
||||
}
|
||||
break;
|
||||
case MI_ALERTING:
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_PROCEED) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RINGING);
|
||||
}
|
||||
break;
|
||||
case MI_PROGRESS:
|
||||
if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) {
|
||||
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
} else if (ftdmchan->state != FTDM_CHANNEL_STATE_PROGRESS) {
|
||||
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* We should never reach this section !*/
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle this event %d\n", evntType);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
/* We are already in progress media, we can't go to any higher state except up */
|
||||
/* Do nothing */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing ALERT/PROCEED/PROGRESS in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
|
@ -410,12 +438,16 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Receiving more digits %s, but we already proceeded with call\n", cnStEvnt->cdPtyNmb.nmbDigits.val);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "\n", suId, suInstId, spInstId);
|
||||
break;
|
||||
|
@ -450,6 +482,7 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
|
@ -478,6 +511,9 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
/* This is a race condition. We just sent a DISCONNECT, on this channel */
|
||||
/* Do nothing */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received DISCONNECT in an invalid state (%s)\n",
|
||||
ftdm_channel_state2str(ftdmchan->state));
|
||||
|
@ -532,7 +568,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
/* Remote side rejected our SETUP message on outbound call */
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
|
||||
sngisdn_set_span_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
|
||||
}
|
||||
/* fall-through */
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
|
@ -540,6 +576,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
/* If we previously had a glare on this channel,
|
||||
this RELEASE could be for the previous call. Confirm whether call_data has
|
||||
not changed while we were waiting for ftdmchan->mutex by comparing suInstId's */
|
||||
|
@ -581,6 +618,9 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
/* set abort flag so that we do not transmit another release complete on this channel once FS core is done */
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RELEASE in an invalid state (%s)\n",
|
||||
ftdm_channel_state2str(ftdmchan->state));
|
||||
|
@ -757,14 +797,14 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
{
|
||||
ftdm_sigmsg_t sigev;
|
||||
if (facEvnt->facElmt.facStr.pres) {
|
||||
get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len);
|
||||
get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len-2);
|
||||
}
|
||||
memset(&sigev, 0, sizeof(sigev));
|
||||
sigev.chan_id = ftdmchan->chan_id;
|
||||
sigev.span_id = ftdmchan->span_id;
|
||||
sigev.channel = ftdmchan;
|
||||
|
||||
sigev.event_id = FTDM_SIGEVENT_MSG;
|
||||
sigev.event_id = FTDM_SIGEVENT_FACILITY;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
break;
|
||||
|
@ -884,6 +924,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
break;
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Remote switch expecting OVERLAP receive, but we are already PROCEEDING\n");
|
||||
sngisdn_snd_disconnect(ftdmchan);
|
||||
|
@ -902,6 +943,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
/* T310 timer has expired */
|
||||
ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val;
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T310 Timer expired, hanging up call\n");
|
||||
|
@ -938,6 +980,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
break;
|
||||
case 9: /* Remote switch is in "Incoming call proceeding" state */
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_GET_CALLERID:
|
||||
|
@ -1047,18 +1090,91 @@ void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
return;
|
||||
}
|
||||
|
||||
static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
/* Do nothing */
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RESTART CFM in an invalid state (%s)\n",
|
||||
ftdm_channel_state2str(ftdmchan->state));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
|
||||
{
|
||||
int16_t suId = sngisdn_event->suId;
|
||||
int16_t dChan = sngisdn_event->dChan;
|
||||
uint8_t ces = sngisdn_event->ces;
|
||||
uint8_t evntType = sngisdn_event->evntType;
|
||||
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
/* Function does not require any info from ssHlEvnt struct for now */
|
||||
/*Rst *rstEvnt = &sngisdn_event->event.rstEvnt;*/
|
||||
uint8_t chan_no = 0;
|
||||
Rst *rstEvnt = &sngisdn_event->event.rstEvnt;
|
||||
|
||||
sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[dChan].spans[1];
|
||||
if (!signal_data) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Received RESTART on unconfigured span (suId:%d)\n", suId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Receved RESTART, but Restart Indicator IE not present\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch(rstEvnt->rstInd.rstClass.val) {
|
||||
case IN_CL_INDCHAN: /* Indicated b-channel */
|
||||
if (rstEvnt->chanId.eh.pres) {
|
||||
if (rstEvnt->chanId.intType.val == IN_IT_BASIC) {
|
||||
if (rstEvnt->chanId.infoChanSel.pres == PRSNT_NODEF) {
|
||||
chan_no = rstEvnt->chanId.infoChanSel.val;
|
||||
}
|
||||
} else if (rstEvnt->chanId.intType.val == IN_IT_OTHER) {
|
||||
if (rstEvnt->chanId.chanNmbSlotMap.pres == PRSNT_NODEF) {
|
||||
chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!chan_no) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case IN_CL_SNGINT: /* Single interface */
|
||||
case IN_CL_ALLINT: /* All interfaces */
|
||||
/* In case restart class indicates all interfaces, we will duplicate
|
||||
this event on each span associated to this d-channel in sngisdn_rcv_rst_cfm,
|
||||
so treat it as a single interface anyway */
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_CRIT, "Invalid restart indicator class:%d\n", rstEvnt->rstInd.rstClass.val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (chan_no) { /* For a single channel */
|
||||
if (chan_no > ftdm_span_get_chan_count(signal_data->ftdm_span)) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Received RESTART on invalid channel:%d\n", chan_no);
|
||||
} else {
|
||||
ftdm_channel_t *ftdmchan = ftdm_span_get_channel(signal_data->ftdm_span, chan_no);
|
||||
sngisdn_process_restart_confirm(ftdmchan);
|
||||
}
|
||||
} else { /* for all channels */
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
sngisdn_process_restart_confirm((ftdm_channel_t*)ftdm_iterator_current(curr));
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART CFM (suId:%u dChan:%d ces:%d type:%d)\n", suId, dChan, ces, evntType);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
|
@ -1087,7 +1203,7 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
return;
|
||||
}
|
||||
|
||||
ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn)
|
||||
static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
|
|
|
@ -51,72 +51,6 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
|||
ftdm_mutex_unlock(g_sngisdn_data.ccs[signal_data->cc_id].mutex);
|
||||
|
||||
memset(&conEvnt, 0, sizeof(conEvnt));
|
||||
|
||||
conEvnt.bearCap[0].eh.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].infoTranCap.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability);
|
||||
|
||||
conEvnt.bearCap[0].codeStand0.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].codeStand0.val = IN_CSTD_CCITT;
|
||||
conEvnt.bearCap[0].infoTranRate0.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].infoTranRate0.val = IN_ITR_64KBIT;
|
||||
conEvnt.bearCap[0].tranMode.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].tranMode.val = IN_TM_CIRCUIT;
|
||||
|
||||
conEvnt.chanId.eh.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.prefExc.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
|
||||
conEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
|
||||
conEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
|
||||
conEvnt.chanId.intIdent.pres = NOTPRSNT;
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
/* Trillium stack rejests lyr1Ident on BRI, but Netbricks always sends it.
|
||||
Check with Trillium if this ever causes calls to fail in the field */
|
||||
|
||||
/* BRI only params */
|
||||
conEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.intType.val = IN_IT_BASIC;
|
||||
conEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
|
||||
} else {
|
||||
/* PRI only params */
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1);
|
||||
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN &&
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) {
|
||||
|
||||
/* We are bridging a call from T1 */
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ALAW;
|
||||
|
||||
} else if (conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) {
|
||||
|
||||
/* We are bridging a call from E1 */
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ULAW;
|
||||
}
|
||||
|
||||
conEvnt.bearCap[0].lyr1Ident.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].lyr1Ident.val = IN_L1_IDENT;
|
||||
|
||||
conEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.intType.val = IN_IT_OTHER;
|
||||
conEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
|
||||
conEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
|
||||
conEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
|
||||
conEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
|
||||
conEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.chanNmbSlotMap.len = 1;
|
||||
conEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
|
||||
conEvnt.sndCmplt.eh.pres = PRSNT_NODEF;
|
||||
}
|
||||
|
@ -126,8 +60,11 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Outgoing call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
|
||||
|
||||
set_chan_id_ie(ftdmchan, &conEvnt.chanId);
|
||||
set_bear_cap_ie(ftdmchan, &conEvnt.bearCap[0]);
|
||||
set_called_num(ftdmchan, &conEvnt.cdPtyNmb);
|
||||
set_calling_num(ftdmchan, &conEvnt.cgPtyNmb);
|
||||
set_calling_num2(ftdmchan, &conEvnt.cgPtyNmb2);
|
||||
set_calling_subaddr(ftdmchan, &conEvnt.cgPtySad);
|
||||
set_redir_num(ftdmchan, &conEvnt.redirNmb);
|
||||
set_calling_name(ftdmchan, &conEvnt);
|
||||
|
@ -160,38 +97,7 @@ void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan)
|
|||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
|
||||
cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
|
||||
cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
|
||||
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
/* BRI only params */
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_BASIC;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
|
||||
} else {
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_OTHER;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
|
||||
cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
|
||||
cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
|
||||
cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.len = 1;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP ACK (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
|
@ -220,38 +126,7 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan)
|
|||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
|
||||
cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
|
||||
cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
/* BRI only params */
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_BASIC;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
|
||||
} else {
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_OTHER;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
|
||||
cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
|
||||
cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
|
||||
cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.len = 1;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT COMPL (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
|
@ -262,10 +137,9 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
|
||||
|
||||
void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan)
|
||||
void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind)
|
||||
{
|
||||
CnStEvnt cnStEvnt;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
|
@ -277,40 +151,12 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
|
||||
cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
|
||||
cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
/* BRI only params */
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_BASIC;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
|
||||
} else {
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_OTHER;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
|
||||
cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
|
||||
cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
|
||||
cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.len = 1;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
|
||||
set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
|
||||
set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
|
||||
|
||||
ftdm_call_clear_data(&ftdmchan->caller_data);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROCEED (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
|
@ -343,6 +189,7 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_
|
|||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
|
||||
set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
|
||||
ftdm_call_clear_data(&ftdmchan->caller_data);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, signal_data->dchan_id, sngisdn_info->ces)) {
|
||||
|
@ -369,6 +216,7 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind
|
|||
|
||||
set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
|
||||
set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
|
||||
ftdm_call_clear_data(&ftdmchan->caller_data);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending ALERT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
|
@ -393,41 +241,11 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
|
||||
cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
|
||||
cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
/* BRI only params */
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_BASIC;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
|
||||
} else {
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_OTHER;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
|
||||
cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
|
||||
cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
|
||||
cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.len = 1;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
|
||||
set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
|
||||
set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
|
||||
ftdm_call_clear_data(&ftdmchan->caller_data);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) {
|
||||
|
@ -450,10 +268,17 @@ void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan)
|
|||
|
||||
memset(&facEvnt, 0, sizeof(facEvnt));
|
||||
|
||||
set_facility_ie_str(ftdmchan, &facEvnt.facElmt.facStr.val[2], (ftdm_size_t*)&facEvnt.facElmt.facStr.len);
|
||||
if (set_facility_ie_str(ftdmchan, &facEvnt.facElmt.facStr.val[2], (uint8_t*)&facEvnt.facElmt.facStr.len) != FTDM_SUCCESS) {
|
||||
/* No point in sending a FACILITY message if there is no Facility IE to transmit */
|
||||
return;
|
||||
}
|
||||
ftdm_call_clear_data(&ftdmchan->caller_data);
|
||||
|
||||
facEvnt.facElmt.eh.pres = PRSNT_NODEF;
|
||||
facEvnt.facElmt.facStr.pres = PRSNT_NODEF;
|
||||
facEvnt.facElmt.facStr.val[0] = 0x1C;
|
||||
facEvnt.facElmt.facStr.val[1] = facEvnt.facElmt.facStr.len;
|
||||
facEvnt.facElmt.facStr.val[1] = (uint8_t)facEvnt.facElmt.facStr.len;
|
||||
facEvnt.facElmt.facStr.len +=2; /* Need to include the size of identifier + len */
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending FACILITY (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
|
@ -481,6 +306,8 @@ void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan)
|
|||
//ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending INFO REQ\n");
|
||||
|
||||
|
||||
ftdm_call_clear_data(&ftdmchan->caller_data);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending INFO REQ (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
if (sng_isdn_con_status(signal_data->cc_id, 0, 0, &cnStEvnt, MI_INFO, signal_data->dchan_id, sngisdn_info->ces)) {
|
||||
|
@ -501,6 +328,8 @@ void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan)
|
|||
|
||||
memset(&staEvnt, 0, sizeof(StaEvnt));
|
||||
|
||||
ftdm_call_clear_data(&ftdmchan->caller_data);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Status ENQ on suId:%d suInstId:%u spInstId:%d dchan:%d ces:%d\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
if (sng_isdn_status_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &staEvnt, MI_STATENQ)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused Status ENQ request\n");
|
||||
|
@ -539,6 +368,7 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
|
|||
discEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT;
|
||||
|
||||
set_facility_ie(ftdmchan, &discEvnt.facilityStr);
|
||||
ftdm_call_clear_data(&ftdmchan->caller_data);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
if (sng_isdn_disc_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &discEvnt)) {
|
||||
|
@ -546,6 +376,7 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
|
||||
{
|
||||
RelEvnt relEvnt;
|
||||
|
@ -585,6 +416,7 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
|
|||
}
|
||||
|
||||
set_facility_ie(ftdmchan, &relEvnt.facilityStr);
|
||||
ftdm_call_clear_data(&ftdmchan->caller_data);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RELEASE/RELEASE COMPLETE (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, suInstId, spInstId);
|
||||
|
||||
|
@ -600,6 +432,24 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
|
|||
return;
|
||||
}
|
||||
|
||||
void sngisdn_snd_restart(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
Rst rstEvnt;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
memset(&rstEvnt, 0, sizeof(rstEvnt));
|
||||
|
||||
set_chan_id_ie(ftdmchan, &rstEvnt.chanId);
|
||||
set_restart_ind_ie(ftdmchan, &rstEvnt.rstInd);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RESTART (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, signal_data->dchan_id, CES_MNGMNT);
|
||||
|
||||
if (sng_isdn_restart_request(signal_data->cc_id, &rstEvnt, signal_data->dchan_id, CES_MNGMNT, IN_SND_RST)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RESTART request\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* We received an incoming frame on the d-channel, send data to the stack */
|
||||
void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)
|
||||
|
|
|
@ -34,9 +34,6 @@
|
|||
|
||||
#include "ftmod_sangoma_isdn.h"
|
||||
|
||||
#define MAX_DECODE_STR_LEN 2000
|
||||
|
||||
|
||||
void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces)
|
||||
{
|
||||
uint8_t bchan_no = 0;
|
||||
|
@ -630,8 +627,9 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces
|
|||
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
|
||||
ftdm_log(FTDM_LOG_INFO, "Received RESTART CFM (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType);
|
||||
|
||||
|
||||
/* Enqueue the event to each span within the dChan */
|
||||
for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) {
|
||||
signal_data = g_sngisdn_data.dchans[dChan].spans[i];
|
||||
|
@ -725,14 +723,25 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
|
|||
ftdmspan = signal_data->ftdm_span;
|
||||
|
||||
if (status->t.usta.alarm.event == LCM_EVENT_UP) {
|
||||
uint32_t chan_no = status->t.usta.evntParm[2];
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n",
|
||||
status->t.usta.suId,
|
||||
DECODE_LCM_CATEGORY(status->t.usta.alarm.category),
|
||||
DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event,
|
||||
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
|
||||
|
||||
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP);
|
||||
sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
|
||||
|
||||
if (chan_no) {
|
||||
ftdm_channel_t *ftdmchan = ftdm_span_get_channel(ftdmspan, chan_no);
|
||||
if (ftdmchan) {
|
||||
sngisdn_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP);
|
||||
sngisdn_set_chan_avail_rate(ftdmchan, SNGISDN_AVAIL_UP);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_CRIT, "stack alarm event on invalid channel :%d\n", chan_no);
|
||||
}
|
||||
} else {
|
||||
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP);
|
||||
sngisdn_set_span_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
|
||||
}
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n",
|
||||
status->t.usta.suId,
|
||||
|
@ -741,7 +750,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
|
|||
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
|
||||
|
||||
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN);
|
||||
sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
|
||||
sngisdn_set_span_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -765,9 +774,6 @@ void sngisdn_rcv_cc_ind(CcMngmt *status)
|
|||
return;
|
||||
}
|
||||
|
||||
#define Q931_TRC_EVENT(event) (event == TL3PKTTX)?"TX": \
|
||||
(event == TL3PKTRX)?"RX":"UNKNOWN"
|
||||
|
||||
void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf)
|
||||
{
|
||||
MsgLen mlen;
|
||||
|
@ -776,13 +782,20 @@ void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf)
|
|||
Buffer *tmp;
|
||||
Data *cptr;
|
||||
uint8_t data;
|
||||
ftdm_trace_dir_t dir;
|
||||
uint8_t tdata[1000];
|
||||
char *data_str = ftdm_calloc(1,MAX_DECODE_STR_LEN); /* TODO Find a proper size */
|
||||
|
||||
sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[trc->t.trc.suId];
|
||||
|
||||
ftdm_assert(mBuf != NULLP, "Received a Q931 trace with no buffer");
|
||||
mlen = ((SsMsgInfo*)(mBuf->b_rptr))->len;
|
||||
|
||||
if (mlen != 0) {
|
||||
|
||||
if (trc->t.trc.evnt == TL3PKTTX) {
|
||||
dir = FTDM_TRACE_OUTGOING;
|
||||
} else {
|
||||
dir = FTDM_TRACE_INCOMING;
|
||||
}
|
||||
|
||||
if (mlen) {
|
||||
tmp = mBuf->b_cont;
|
||||
cptr = tmp->b_rptr;
|
||||
data = *cptr++;
|
||||
|
@ -797,41 +810,40 @@ void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf)
|
|||
}
|
||||
data = *cptr++;
|
||||
}
|
||||
|
||||
sngisdn_trace_q931(data_str, tdata, mlen);
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d FRAME %s:%s\n", trc->t.trc.suId, Q931_TRC_EVENT(trc->t.trc.evnt), data_str);
|
||||
if (signal_data->raw_trace_q931 == SNGISDN_OPT_TRUE) {
|
||||
sngisdn_trace_raw_q931(signal_data, dir, tdata, mlen);
|
||||
} else {
|
||||
sngisdn_trace_interpreted_q931(signal_data, dir, tdata, mlen);
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_safe_free(data_str);
|
||||
/* We do not need to free mBuf in this case because stack does it */
|
||||
/* SPutMsg(mBuf); */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#define Q921_TRC_EVENT(event) (event == TL2FRMRX)?"RX": \
|
||||
(event == TL2FRMTX)?"TX": \
|
||||
(event == TL2TMR)?"TMR EXPIRED":"UNKNOWN"
|
||||
|
||||
void sngisdn_rcv_q921_trace(BdMngmt *trc, Buffer *mBuf)
|
||||
{
|
||||
MsgLen mlen;
|
||||
Buffer *tmp;
|
||||
MsgLen i;
|
||||
int16_t j;
|
||||
Buffer *tmp;
|
||||
Data *cptr;
|
||||
uint8_t data;
|
||||
uint8_t tdata[16];
|
||||
char *data_str = ftdm_calloc(1,200); /* TODO Find a proper size */
|
||||
|
||||
ftdm_trace_dir_t dir;
|
||||
uint8_t tdata[1000];
|
||||
sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[trc->t.trc.lnkNmb];
|
||||
|
||||
if (trc->t.trc.evnt == TL2TMR) {
|
||||
goto end_of_trace;
|
||||
return;
|
||||
}
|
||||
|
||||
if (trc->t.trc.evnt == TL2FRMTX) {
|
||||
dir = FTDM_TRACE_OUTGOING;
|
||||
} else {
|
||||
dir = FTDM_TRACE_INCOMING;
|
||||
}
|
||||
|
||||
ftdm_assert(mBuf != NULLP, "Received a Q921 trace with no buffer");
|
||||
mlen = ((SsMsgInfo*)(mBuf->b_rptr))->len;
|
||||
|
||||
if (mlen != 0) {
|
||||
tmp = mBuf->b_cont;
|
||||
cptr = tmp->b_rptr;
|
||||
|
@ -853,12 +865,12 @@ void sngisdn_rcv_q921_trace(BdMngmt *trc, Buffer *mBuf)
|
|||
}
|
||||
|
||||
}
|
||||
sngisdn_trace_q921(data_str, tdata, mlen);
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] s%d FRAME %s:%s\n", trc->t.trc.lnkNmb, Q921_TRC_EVENT(trc->t.trc.evnt), data_str);
|
||||
if (signal_data->raw_trace_q921 == SNGISDN_OPT_TRUE) {
|
||||
sngisdn_trace_raw_q921(signal_data, dir, tdata, mlen);
|
||||
} else {
|
||||
sngisdn_trace_interpreted_q921(signal_data, dir, tdata, mlen);
|
||||
}
|
||||
}
|
||||
end_of_trace:
|
||||
ftdm_safe_free(data_str);
|
||||
SPutMsg(mBuf);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -136,19 +136,25 @@ ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
|
||||
ftdm_status_t sngisdn_set_chan_avail_rate(ftdm_channel_t *chan, sngisdn_avail_t avail)
|
||||
{
|
||||
if (span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
if (FTDM_SPAN_IS_BRI(chan->span)) {
|
||||
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail);
|
||||
chan->availability_rate = avail;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
|
||||
{
|
||||
if (FTDM_SPAN_IS_BRI(span)) {
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
ftdm_log_chan(((ftdm_channel_t*)ftdm_iterator_current(curr)), FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail);
|
||||
((ftdm_channel_t*)ftdm_iterator_current(curr))->availability_rate = avail;
|
||||
sngisdn_set_chan_avail_rate(((ftdm_channel_t*)ftdm_iterator_current(curr)), avail);
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
}
|
||||
|
@ -185,6 +191,39 @@ ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t get_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
|
||||
{
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
if (cgPtyNmb->eh.pres != PRSNT_NODEF) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (cgPtyNmb->screenInd.pres == PRSNT_NODEF) {
|
||||
ftdm_call_add_var(caller_data, "isdn.cg_pty2.screen_ind", ftdm_screening2str(cgPtyNmb->screenInd.val));
|
||||
}
|
||||
|
||||
if (cgPtyNmb->presInd0.pres == PRSNT_NODEF) {
|
||||
ftdm_call_add_var(caller_data, "isdn.cg_pty2.presentation_ind", ftdm_presentation2str(cgPtyNmb->presInd0.val));
|
||||
}
|
||||
|
||||
if (cgPtyNmb->nmbPlanId.pres == PRSNT_NODEF) {
|
||||
ftdm_call_add_var(caller_data, "isdn.cg_pty2.npi", ftdm_npi2str(cgPtyNmb->nmbPlanId.val));
|
||||
}
|
||||
|
||||
if (cgPtyNmb->typeNmb1.pres == PRSNT_NODEF) {
|
||||
ftdm_call_add_var(caller_data, "isdn.cg_pty2.ton", ftdm_ton2str(cgPtyNmb->typeNmb1.val));
|
||||
}
|
||||
|
||||
if (cgPtyNmb->nmbDigits.pres == PRSNT_NODEF) {
|
||||
char digits_string [32];
|
||||
memcpy(digits_string, (const char*)cgPtyNmb->nmbDigits.val, cgPtyNmb->nmbDigits.len);
|
||||
digits_string[cgPtyNmb->nmbDigits.len] = '\0';
|
||||
ftdm_call_add_var(caller_data, "isdn.cg_pty2.digits", digits_string);
|
||||
}
|
||||
memcpy(&caller_data->ani, &caller_data->cid_num, sizeof(caller_data->ani));
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb)
|
||||
{
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
|
@ -278,7 +317,7 @@ ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
|
|||
|
||||
memcpy(subaddress, (char*)cgPtySad->sadInfo.val, cgPtySad->sadInfo.len);
|
||||
subaddress[cgPtySad->sadInfo.len] = '\0';
|
||||
ftdm_channel_add_var(ftdmchan, "isdn.calling_subaddr", subaddress);
|
||||
ftdm_call_add_var(&ftdmchan->caller_data, "isdn.calling_subaddr", subaddress);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -291,17 +330,16 @@ ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr
|
|||
return get_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, facilityStr->facilityStr.len);
|
||||
}
|
||||
|
||||
ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t data_len)
|
||||
ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t data_len)
|
||||
{
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) {
|
||||
if (data_len > sizeof(caller_data->raw_data)-2) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Length of Facility IE exceeds maximum length\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* size of facilityStr->facilityStr.len is a uint8_t so no need to check
|
||||
for overflow here as facilityStr->facilityStr.len will always be smaller
|
||||
than sizeof(caller_data->raw_data) */
|
||||
|
||||
memset(caller_data->raw_data, 0, sizeof(caller_data->raw_data));
|
||||
/* Always include Facility IE identifier + len so this can be used as a sanity check by the user */
|
||||
caller_data->raw_data[0] = SNGISDN_Q931_FACILITY_IE_ID;
|
||||
|
@ -348,7 +386,7 @@ ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd)
|
|||
val = SNGISDN_PROGIND_DESCR_INVALID;
|
||||
break;
|
||||
}
|
||||
ftdm_channel_add_var(ftdmchan, "isdn.prog_ind.descr", ftdm_sngisdn_progind_descr2str(val));
|
||||
ftdm_call_add_var(&ftdmchan->caller_data, "isdn.prog_ind.descr", ftdm_sngisdn_progind_descr2str(val));
|
||||
}
|
||||
|
||||
if (progInd->location.pres) {
|
||||
|
@ -379,7 +417,7 @@ ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd)
|
|||
val = SNGISDN_PROGIND_LOC_INVALID;
|
||||
break;
|
||||
}
|
||||
ftdm_channel_add_var(ftdmchan, "isdn.prog_ind.loc", ftdm_sngisdn_progind_loc2str(val));
|
||||
ftdm_call_add_var(&ftdmchan->caller_data, "isdn.prog_ind.loc", ftdm_sngisdn_progind_loc2str(val));
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
@ -423,6 +461,89 @@ ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
|
||||
{
|
||||
const char* string = NULL;
|
||||
uint8_t len,val;
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
|
||||
string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.digits");
|
||||
if ((string == NULL) || !(*string)) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
cgPtyNmb->eh.pres = PRSNT_NODEF;
|
||||
|
||||
len = strlen(string);
|
||||
cgPtyNmb->nmbDigits.len = len;
|
||||
|
||||
cgPtyNmb->nmbDigits.pres = PRSNT_NODEF;
|
||||
memcpy(cgPtyNmb->nmbDigits.val, string, len);
|
||||
|
||||
/* Screening Indicator */
|
||||
cgPtyNmb->screenInd.pres = PRSNT_NODEF;
|
||||
|
||||
val = FTDM_SCREENING_INVALID;
|
||||
string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.screening_ind");
|
||||
if ((string != NULL) && (*string)) {
|
||||
val = ftdm_str2ftdm_screening(string);
|
||||
}
|
||||
|
||||
/* isdn.cg_pty2.screen_ind does not exist or we could not parse its value */
|
||||
if (val == FTDM_SCREENING_INVALID) {
|
||||
/* default to caller data screening ind */
|
||||
cgPtyNmb->screenInd.val = caller_data->screen;
|
||||
} else {
|
||||
cgPtyNmb->screenInd.val = val;
|
||||
}
|
||||
|
||||
/* Presentation Indicator */
|
||||
cgPtyNmb->presInd0.pres = PRSNT_NODEF;
|
||||
|
||||
val = FTDM_PRES_INVALID;
|
||||
string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.presentation_ind");
|
||||
if ((string != NULL) && (*string)) {
|
||||
val = ftdm_str2ftdm_presentation(string);
|
||||
}
|
||||
|
||||
if (val == FTDM_PRES_INVALID) {
|
||||
cgPtyNmb->presInd0.val = caller_data->pres;
|
||||
} else {
|
||||
cgPtyNmb->presInd0.val = val;
|
||||
}
|
||||
|
||||
/* Numbering Plan Indicator */
|
||||
cgPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
|
||||
|
||||
val = FTDM_NPI_INVALID;
|
||||
string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.npi");
|
||||
if ((string != NULL) && (*string)) {
|
||||
val = ftdm_str2ftdm_npi(string);
|
||||
}
|
||||
|
||||
if (val == FTDM_NPI_INVALID) {
|
||||
cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan;
|
||||
} else {
|
||||
cgPtyNmb->nmbPlanId.val = val;
|
||||
}
|
||||
|
||||
cgPtyNmb->typeNmb1.pres = PRSNT_NODEF;
|
||||
|
||||
/* Type of Number */
|
||||
val = FTDM_TON_INVALID;
|
||||
string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.ton");
|
||||
if ((string != NULL) && (*string)) {
|
||||
val = ftdm_str2ftdm_ton(string);
|
||||
}
|
||||
|
||||
if (val == FTDM_TON_INVALID) {
|
||||
cgPtyNmb->typeNmb1.val = caller_data->cid_num.type;
|
||||
} else {
|
||||
cgPtyNmb->typeNmb1.val = val;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb)
|
||||
{
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
|
@ -544,7 +665,7 @@ ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt)
|
|||
ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
|
||||
{
|
||||
const char* clg_subaddr = NULL;
|
||||
clg_subaddr = ftdm_channel_get_var(ftdmchan, "isdn.calling_subaddr");
|
||||
clg_subaddr = ftdm_call_get_var(&ftdmchan->caller_data, "isdn.calling_subaddr");
|
||||
if ((clg_subaddr != NULL) && (*clg_subaddr)) {
|
||||
unsigned len = strlen (clg_subaddr);
|
||||
cgPtySad->eh.pres = PRSNT_NODEF;
|
||||
|
@ -561,11 +682,10 @@ ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr)
|
||||
{
|
||||
ftdm_status_t status;
|
||||
status = set_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, (ftdm_size_t*)&facilityStr->facilityStr.len);
|
||||
status = set_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, (uint8_t*)&(facilityStr->facilityStr.len));
|
||||
if (status == FTDM_SUCCESS) {
|
||||
facilityStr->eh.pres = PRSNT_NODEF;
|
||||
facilityStr->facilityStr.pres = PRSNT_NODEF;
|
||||
|
@ -573,13 +693,15 @@ ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr
|
|||
return status;
|
||||
}
|
||||
|
||||
ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t *data_len)
|
||||
ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t *data_len)
|
||||
{
|
||||
int len;
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
|
||||
if (caller_data->raw_data_len > 0 && caller_data->raw_data[0] == SNGISDN_Q931_FACILITY_IE_ID) {
|
||||
*data_len = caller_data->raw_data[1];
|
||||
memcpy(data, &caller_data->raw_data[2], *data_len);
|
||||
len = caller_data->raw_data[1];
|
||||
memcpy(data, &caller_data->raw_data[2], len);
|
||||
*data_len = len;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
return FTDM_FAIL;
|
||||
|
@ -591,7 +713,7 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s
|
|||
int descr = prog_ind.descr;
|
||||
int loc = prog_ind.loc;
|
||||
|
||||
str = ftdm_channel_get_var(ftdmchan, "isdn.prog_ind.descr");
|
||||
str = ftdm_call_get_var(&ftdmchan->caller_data, "isdn.prog_ind.descr");
|
||||
if (str && *str) {
|
||||
/* User wants to override progress indicator */
|
||||
descr = ftdm_str2ftdm_sngisdn_progind_descr(str);
|
||||
|
@ -602,8 +724,8 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
str = ftdm_channel_get_var(ftdmchan, "isdn.prog_ind.loc");
|
||||
if (str && *str) {
|
||||
str = ftdm_call_get_var(&ftdmchan->caller_data, "isdn.prog_ind.loc");
|
||||
if (str && *str) {
|
||||
loc = ftdm_str2ftdm_sngisdn_progind_loc(str);
|
||||
}
|
||||
if (loc == SNGISDN_PROGIND_LOC_INVALID) {
|
||||
|
@ -672,6 +794,93 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId)
|
||||
{
|
||||
if (!ftdmchan) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
chanId->eh.pres = PRSNT_NODEF;
|
||||
chanId->prefExc.pres = PRSNT_NODEF;
|
||||
chanId->prefExc.val = IN_PE_EXCLSVE;
|
||||
chanId->dChanInd.pres = PRSNT_NODEF;
|
||||
chanId->dChanInd.val = IN_DSI_NOTDCHAN;
|
||||
chanId->intIdentPres.pres = PRSNT_NODEF;
|
||||
chanId->intIdentPres.val = IN_IIP_IMPLICIT;
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
/* BRI only params */
|
||||
chanId->intType.pres = PRSNT_NODEF;
|
||||
chanId->intType.val = IN_IT_BASIC;
|
||||
chanId->infoChanSel.pres = PRSNT_NODEF;
|
||||
chanId->infoChanSel.val = ftdmchan->physical_chan_id;
|
||||
} else {
|
||||
chanId->intType.pres = PRSNT_NODEF;
|
||||
chanId->intType.val = IN_IT_OTHER;
|
||||
chanId->infoChanSel.pres = PRSNT_NODEF;
|
||||
chanId->infoChanSel.val = IN_ICS_B1CHAN;
|
||||
chanId->chanMapType.pres = PRSNT_NODEF;
|
||||
chanId->chanMapType.val = IN_CMT_BCHAN;
|
||||
chanId->nmbMap.pres = PRSNT_NODEF;
|
||||
chanId->nmbMap.val = IN_NM_CHNNMB;
|
||||
chanId->codeStand1.pres = PRSNT_NODEF;
|
||||
chanId->codeStand1.val = IN_CSTD_CCITT;
|
||||
chanId->chanNmbSlotMap.pres = PRSNT_NODEF;
|
||||
chanId->chanNmbSlotMap.len = 1;
|
||||
chanId->chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
bearCap->eh.pres = PRSNT_NODEF;
|
||||
bearCap->infoTranCap.pres = PRSNT_NODEF;
|
||||
bearCap->infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability);
|
||||
|
||||
bearCap->codeStand0.pres = PRSNT_NODEF;
|
||||
bearCap->codeStand0.val = IN_CSTD_CCITT;
|
||||
bearCap->infoTranRate0.pres = PRSNT_NODEF;
|
||||
bearCap->infoTranRate0.val = IN_ITR_64KBIT;
|
||||
bearCap->tranMode.pres = PRSNT_NODEF;
|
||||
bearCap->tranMode.val = IN_TM_CIRCUIT;
|
||||
|
||||
if (!FTDM_SPAN_IS_BRI(ftdmchan->span)) {
|
||||
/* Trillium stack rejests lyr1Ident on BRI, but Netbricks always sends it.
|
||||
Check with Trillium if this ever causes calls to fail in the field */
|
||||
|
||||
/* PRI only params */
|
||||
bearCap->usrInfoLyr1Prot.pres = PRSNT_NODEF;
|
||||
bearCap->usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1);
|
||||
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN &&
|
||||
bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) {
|
||||
|
||||
/* We are bridging a call from T1 */
|
||||
bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW;
|
||||
|
||||
} else if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) {
|
||||
|
||||
/* We are bridging a call from E1 */
|
||||
bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW;
|
||||
}
|
||||
|
||||
bearCap->lyr1Ident.pres = PRSNT_NODEF;
|
||||
bearCap->lyr1Ident.val = IN_L1_IDENT;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd)
|
||||
{
|
||||
rstInd->eh.pres = PRSNT_NODEF;
|
||||
rstInd->rstClass.pres = PRSNT_NODEF;
|
||||
rstInd->rstClass.val = IN_CL_INDCHAN;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
void sngisdn_t3_timeout(void* p_sngisdn_info)
|
||||
{
|
||||
|
|
|
@ -36,14 +36,15 @@
|
|||
#include "ftmod_sangoma_isdn_trace.h"
|
||||
|
||||
#define OCTET(x) (ieData[x-1] & 0xFF)
|
||||
#define MAX_DECODE_STR_LEN 2000
|
||||
|
||||
void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_start, uint32_t index_end);
|
||||
void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len);
|
||||
void sngisdn_trace_q931(char* str, uint8_t* data, uint32_t data_len);
|
||||
uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset, uint8_t *data, uint16_t index_start);
|
||||
|
||||
uint8_t get_bits(uint8_t octet, uint8_t bitLo, uint8_t bitHi);
|
||||
char* get_code_2_str(int code, struct code2str *pCodeTable);
|
||||
void sngisdn_decode_q921(char* str, uint8_t* data, uint32_t data_len);
|
||||
void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len);
|
||||
|
||||
char* get_code_2_str(int code, struct code2str *pCodeTable)
|
||||
{
|
||||
|
@ -97,7 +98,43 @@ uint8_t get_bits(uint8_t octet, uint8_t bitLo, uint8_t bitHi)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len)
|
||||
void sngisdn_trace_interpreted_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
char *data_str = ftdm_calloc(1,200); /* TODO Find a proper size */
|
||||
sngisdn_decode_q921(data_str, data, data_len);
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] s%d FRAME %s:%s\n", signal_data->ftdm_span->name, ftdm_trace_dir2str(dir), data_str);
|
||||
ftdm_safe_free(data_str);
|
||||
}
|
||||
|
||||
void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
uint8_t *raw_data;
|
||||
ftdm_sigmsg_t sigev;
|
||||
|
||||
memset(&sigev, 0, sizeof(sigev));
|
||||
|
||||
sigev.span_id = signal_data->ftdm_span->span_id;
|
||||
sigev.chan_id = signal_data->dchan->chan_id;
|
||||
sigev.channel = signal_data->dchan;
|
||||
sigev.event_id = FTDM_SIGEVENT_TRACE_RAW;
|
||||
|
||||
sigev.ev_data.logevent.dir = dir;
|
||||
sigev.ev_data.logevent.level = 2;
|
||||
|
||||
/* TODO: Map trace to call ID here */
|
||||
sigev.call_id = 0;
|
||||
|
||||
raw_data = ftdm_malloc(data_len);
|
||||
ftdm_assert(raw_data, "Failed to malloc");
|
||||
|
||||
memcpy(raw_data, data, data_len);
|
||||
sigev.raw.data = raw_data;
|
||||
sigev.raw.len = data_len;
|
||||
sigev.raw.autofree = 1;
|
||||
ftdm_span_send_signal(signal_data->ftdm_span, &sigev);
|
||||
}
|
||||
|
||||
void sngisdn_decode_q921(char* str, uint8_t* data, uint32_t data_len)
|
||||
{
|
||||
int str_len;
|
||||
uint32_t i;
|
||||
|
@ -169,7 +206,43 @@ void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len)
|
|||
return;
|
||||
}
|
||||
|
||||
void sngisdn_trace_q931(char* str, uint8_t* data, uint32_t data_len)
|
||||
|
||||
void sngisdn_trace_interpreted_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
char *data_str = ftdm_calloc(1,MAX_DECODE_STR_LEN); /* TODO Find a proper size */
|
||||
sngisdn_decode_q931(data_str, data, data_len);
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] %s FRAME %s:%s\n", signal_data->ftdm_span->name, ftdm_trace_dir2str(dir), data_str);
|
||||
ftdm_safe_free(data_str);
|
||||
}
|
||||
|
||||
void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
uint8_t *raw_data;
|
||||
ftdm_sigmsg_t sigev;
|
||||
|
||||
memset(&sigev, 0, sizeof(sigev));
|
||||
|
||||
sigev.span_id = signal_data->ftdm_span->span_id;
|
||||
sigev.chan_id = signal_data->dchan->chan_id;
|
||||
sigev.channel = signal_data->dchan;
|
||||
sigev.event_id = FTDM_SIGEVENT_TRACE_RAW;
|
||||
|
||||
sigev.ev_data.logevent.dir = dir;
|
||||
sigev.ev_data.logevent.level = 3;
|
||||
|
||||
/* TODO: Map trace to call ID here */
|
||||
|
||||
raw_data = ftdm_malloc(data_len);
|
||||
ftdm_assert(raw_data, "Failed to malloc");
|
||||
|
||||
memcpy(raw_data, data, data_len);
|
||||
sigev.raw.data = raw_data;
|
||||
sigev.raw.len = data_len;
|
||||
sigev.raw.autofree = 1;
|
||||
ftdm_span_send_signal(signal_data->ftdm_span, &sigev);
|
||||
}
|
||||
|
||||
void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len)
|
||||
{
|
||||
uint32_t str_len;
|
||||
uint8_t prot_disc, callRefFlag;
|
||||
|
|
|
@ -1589,7 +1589,7 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c
|
|||
sigev.span_id = ftdmchan->span_id;
|
||||
sigev.channel = ftdmchan;
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* if this is the first channel in the range */
|
||||
|
@ -1689,7 +1689,7 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c
|
|||
sigev.span_id = ftdmchan->span_id;
|
||||
sigev.channel = ftdmchan;
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* if this is the first channel in the range */
|
||||
|
|
|
@ -211,10 +211,10 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
|
||||
/* add any special variables for the dialplan */
|
||||
sprintf(nadi, "%d", siConEvnt->cgPtyNum.natAddrInd.val);
|
||||
ftdm_channel_add_var(ftdmchan, "ss7_clg_nadi", nadi);
|
||||
ftdm_call_add_var(&ftdmchan->caller_data, "ss7_clg_nadi", nadi);
|
||||
|
||||
sprintf(nadi, "%d", siConEvnt->cdPtyNum.natAddrInd.val);
|
||||
ftdm_channel_add_var(ftdmchan, "ss7_cld_nadi", nadi);
|
||||
ftdm_call_add_var(&ftdmchan->caller_data, "ss7_cld_nadi", nadi);
|
||||
|
||||
|
||||
/* check if a COT test is requested */
|
||||
|
@ -2004,7 +2004,7 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
|
||||
/* bring the sig status down */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* unlock the channel again before we exit */
|
||||
|
@ -2135,7 +2135,7 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
|
||||
/* bring the sig status down */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* unlock the channel again before we exit */
|
||||
|
|
|
@ -502,6 +502,8 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
/**************************************************************************/
|
||||
case FTDM_CHANNEL_STATE_COLLECT: /* IAM received but wating on digits */
|
||||
|
||||
isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
|
||||
|
||||
if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
|
||||
SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
|
||||
break;
|
||||
|
@ -521,8 +523,8 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
/*now go to the RING state */
|
||||
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
|
||||
} else if (i >= g_ftdm_sngss7_data.min_digits) {
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, g_ftdm_sngss7_data.min_digits);
|
||||
} else if (i >= isup_intf->min_digits) {
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, isup_intf->min_digits);
|
||||
|
||||
/*now go to the RING state */
|
||||
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
|
@ -532,7 +534,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) {
|
||||
SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n",
|
||||
i,
|
||||
g_ftdm_sngss7_data.min_digits,
|
||||
isup_intf->min_digits,
|
||||
ftdmchan->caller_data.dnis.digits);
|
||||
|
||||
/* start ISUP t35 */
|
||||
|
@ -839,7 +841,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
SS7_DEBUG_CHAN(ftdmchan,"All reset flags cleared %s\n", "");
|
||||
/* all flags are down so we can bring up the sig status */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal (ftdmchan->span, &sigev);
|
||||
} /* if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) */
|
||||
} /* if !blocked */
|
||||
|
@ -947,7 +949,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
/* if the sig_status is up...bring it down */
|
||||
if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal (ftdmchan->span, &sigev);
|
||||
}
|
||||
|
||||
|
@ -1031,7 +1033,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* bring the sig status back up */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
|
||||
|
@ -1044,7 +1046,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* bring the sig status down */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* go back to the last state */
|
||||
|
@ -1056,7 +1058,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* bring the sig status down */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* send a BLA */
|
||||
|
@ -1074,7 +1076,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* bring the sig status up */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* send a uba */
|
||||
|
@ -1090,7 +1092,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* bring the sig status down */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* send a blo */
|
||||
|
@ -1108,7 +1110,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* bring the sig status up */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_UP;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
/* send a ubl */
|
||||
|
@ -1147,7 +1149,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* bring the channel signaling status to down */
|
||||
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sigev.sigstatus = FTDM_SIG_STATE_DOWN;
|
||||
sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
|
||||
ftdm_span_send_signal (ftdmchan->span, &sigev);
|
||||
|
||||
/* remove any reset flags */
|
||||
|
@ -1520,9 +1522,6 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init)
|
|||
/* initalize the global gen_config flag */
|
||||
g_ftdm_sngss7_data.gen_config = 0;
|
||||
|
||||
/* min. number of digitis to wait for */
|
||||
g_ftdm_sngss7_data.min_digits = 7;
|
||||
|
||||
/* function trace initizalation */
|
||||
g_ftdm_sngss7_data.function_trace = 1;
|
||||
g_ftdm_sngss7_data.function_trace_level = 7;
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
/******************************************************************************/
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
#define MAX_NAME_LEN 10
|
||||
#define MAX_NAME_LEN 25
|
||||
#define MAX_PATH 255
|
||||
|
||||
#define MAX_CIC_LENGTH 5
|
||||
|
@ -224,6 +224,7 @@ typedef struct sng_isup_intf {
|
|||
uint32_t isap;
|
||||
uint32_t clg_nadi;
|
||||
uint32_t cld_nadi;
|
||||
uint32_t min_digits;
|
||||
uint16_t t4;
|
||||
uint32_t t10;
|
||||
uint32_t t11;
|
||||
|
@ -326,7 +327,6 @@ typedef struct sng_ss7_cfg {
|
|||
typedef struct ftdm_sngss7_data {
|
||||
sng_ss7_cfg_t cfg;
|
||||
int gen_config;
|
||||
int min_digits;
|
||||
int function_trace;
|
||||
int function_trace_level;
|
||||
int message_trace;
|
||||
|
|
|
@ -187,7 +187,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
|||
copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum);
|
||||
|
||||
/* check if the user would like a custom NADI value for the calling Pty Num */
|
||||
clg_nadi = ftdm_channel_get_var(ftdmchan, "ss7_clg_nadi");
|
||||
clg_nadi = ftdm_call_get_var(&ftdmchan->caller_data, "ss7_clg_nadi");
|
||||
if ((clg_nadi != NULL) && (*clg_nadi)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling NADI value \"%s\"\n", clg_nadi);
|
||||
iam.cgPtyNum.natAddrInd.val = atoi(clg_nadi);
|
||||
|
@ -196,7 +196,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
|||
SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLG, using \"%d\"\n", iam.cgPtyNum.natAddrInd.val);
|
||||
}
|
||||
|
||||
cld_nadi = ftdm_channel_get_var(ftdmchan, "ss7_cld_nadi");
|
||||
cld_nadi = ftdm_call_get_var(&ftdmchan->caller_data, "ss7_cld_nadi");
|
||||
if ((cld_nadi != NULL) && (*cld_nadi)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called NADI value \"%s\"\n", cld_nadi);
|
||||
iam.cdPtyNum.natAddrInd.val = atoi(cld_nadi);
|
||||
|
@ -206,7 +206,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
|||
}
|
||||
|
||||
/* check if the user would like us to send a clg_sub-address */
|
||||
clg_subAddr = ftdm_channel_get_var(ftdmchan, "ss7_clg_subaddr");
|
||||
clg_subAddr = ftdm_call_get_var(&ftdmchan->caller_data, "ss7_clg_subaddr");
|
||||
if ((clg_subAddr != NULL) && (*clg_subAddr)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling Sub-Address value \"%s\"\n", clg_subAddr);
|
||||
|
||||
|
@ -245,7 +245,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
|||
}
|
||||
|
||||
/* check if the user would like us to send a cld_sub-address */
|
||||
cld_subAddr = ftdm_channel_get_var(ftdmchan, "ss7_cld_subaddr");
|
||||
cld_subAddr = ftdm_call_get_var(&ftdmchan->caller_data, "ss7_cld_subaddr");
|
||||
if ((cld_subAddr != NULL) && (*cld_subAddr)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called Sub-Address value \"%s\"\n", cld_subAddr);
|
||||
|
||||
|
@ -298,7 +298,8 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
|||
iam.cgPtyNum.natAddrInd.val,
|
||||
ftdmchan->caller_data.dnis.digits,
|
||||
iam.cdPtyNum.natAddrInd.val);
|
||||
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -379,7 +380,7 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
|
|||
ADDRCMPLT);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ACM\n", sngss7_info->circuit->cic);
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -403,7 +404,7 @@ void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan)
|
|||
5);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ANM\n", sngss7_info->circuit->cic);
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -438,7 +439,7 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan)
|
|||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx REL cause=%d \n",
|
||||
sngss7_info->circuit->cic,
|
||||
ftdmchan->caller_data.hangup_cause );
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -461,7 +462,7 @@ void ft_to_sngss7_rlc (ftdm_channel_t * ftdmchan)
|
|||
&rlc);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RLC\n", sngss7_info->circuit->cic);
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -482,7 +483,7 @@ void ft_to_sngss7_rsc (ftdm_channel_t * ftdmchan)
|
|||
NULL);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC\n", sngss7_info->circuit->cic);
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -503,7 +504,7 @@ void ft_to_sngss7_rsca (ftdm_channel_t * ftdmchan)
|
|||
NULL);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC-RLC\n", sngss7_info->circuit->cic);
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -524,7 +525,7 @@ void ft_to_sngss7_blo (ftdm_channel_t * ftdmchan)
|
|||
NULL);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLO\n", sngss7_info->circuit->cic);
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -545,7 +546,7 @@ void ft_to_sngss7_bla (ftdm_channel_t * ftdmchan)
|
|||
NULL);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLA\n", sngss7_info->circuit->cic);
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -567,7 +568,7 @@ ft_to_sngss7_ubl (ftdm_channel_t * ftdmchan)
|
|||
NULL);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBL\n", sngss7_info->circuit->cic);
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -588,7 +589,7 @@ void ft_to_sngss7_uba (ftdm_channel_t * ftdmchan)
|
|||
NULL);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBA\n", sngss7_info->circuit->cic);
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -609,7 +610,7 @@ void ft_to_sngss7_lpa (ftdm_channel_t * ftdmchan)
|
|||
NULL);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx LPA\n", sngss7_info->circuit->cic);
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -654,6 +655,7 @@ void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan)
|
|||
sngss7_info->circuit->cic,
|
||||
(sngss7_info->circuit->cic + sngss7_span->rx_grs.range));
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -686,7 +688,8 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan)
|
|||
sngss7_info->circuit->cic,
|
||||
sngss7_info->circuit->cic,
|
||||
(sngss7_info->circuit->cic + sngss7_span->tx_grs.range));
|
||||
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -735,7 +738,7 @@ void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan)
|
|||
|
||||
/* clean out the saved data */
|
||||
memset(&sngss7_span->rx_cgb, 0x0, sizeof(sngss7_group_data_t));
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -785,6 +788,7 @@ void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan)
|
|||
/* clean out the saved data */
|
||||
memset(&sngss7_span->rx_cgu, 0x0, sizeof(sngss7_group_data_t));
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -835,6 +839,7 @@ void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan)
|
|||
/* clean out the saved data */
|
||||
memset(&sngss7_span->tx_cgb, 0x0, sizeof(sngss7_group_data_t));
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
@ -885,6 +890,7 @@ void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan)
|
|||
/* clean out the saved data */
|
||||
memset(&sngss7_span->tx_cgu, 0x0, sizeof(sngss7_group_data_t));
|
||||
|
||||
ftdm_call_clear_vars(&ftdmchan->caller_data);
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -142,7 +142,7 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
|
|||
|
||||
if (!strcasecmp(var, "ch_map")) {
|
||||
/**********************************************************************/
|
||||
strcpy(isupCkt.ch_map, val);
|
||||
strncpy(isupCkt.ch_map, val, MAX_CIC_MAP_LENGTH-1);
|
||||
SS7_DEBUG("\tFound channel map \"%s\"\n", isupCkt.ch_map);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(var, "typeCntrl")) {
|
||||
|
@ -393,7 +393,7 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset)
|
|||
for (i = 0; i < num_parms; i++) {
|
||||
/**********************************************************************/
|
||||
if (!strcasecmp(parm->var, "name")) {
|
||||
strcpy((char *)mtpLinkSet.name, parm->val);
|
||||
strncpy((char *)mtpLinkSet.name, parm->val, MAX_NAME_LEN-1);
|
||||
SS7_DEBUG("\tFound an \"mtp_linkset\" named = %s\n", mtpLinkSet.name);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "apc")) {
|
||||
|
@ -508,7 +508,7 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *
|
|||
/* try to match the parameter to what we expect */
|
||||
/**********************************************************************/
|
||||
if (!strcasecmp(parm->var, "name")) {
|
||||
strcpy((char *)mtpLink->name, parm->val);
|
||||
strncpy((char *)mtpLink->name, parm->val, MAX_NAME_LEN-1);
|
||||
SS7_DEBUG("\tFound an \"mtp_link\" named = %s\n", mtpLink->name);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "span")) {
|
||||
|
@ -827,7 +827,7 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route)
|
|||
/* try to match the parameter to what we expect */
|
||||
/**********************************************************************/
|
||||
if (!strcasecmp(parm->var, "name")) {
|
||||
strcpy((char *)mtpRoute.name, parm->val);
|
||||
strncpy((char *)mtpRoute.name, parm->val, MAX_NAME_LEN-1);
|
||||
SS7_DEBUG("\tFound an \"mtp_route\" named = %s\n", mtpRoute.name);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "dpc")) {
|
||||
|
@ -999,7 +999,7 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
|
|||
/* try to match the parameter to what we expect */
|
||||
/**********************************************************************/
|
||||
if (!strcasecmp(parm->var, "name")) {
|
||||
strcpy((char *)sng_isup.name, parm->val);
|
||||
strncpy((char *)sng_isup.name, parm->val, MAX_NAME_LEN-1);
|
||||
SS7_DEBUG("\tFound an \"isup_interface\" named = %s\n", sng_isup.name);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "spc")) {
|
||||
|
@ -1047,6 +1047,11 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
|
|||
SS7_DEBUG("\tFound MTP3 Route = %s\n", parm->val);
|
||||
}
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "min_digits")) {
|
||||
sng_isup.min_digits = atoi(parm->val);
|
||||
|
||||
SS7_DEBUG("\tFound min_digits = %d\n", sng_isup.min_digits);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "ssf")) {
|
||||
if (!strcasecmp(parm->val, "nat")) {
|
||||
sng_isup.ssf = SSF_NAT;
|
||||
|
@ -1067,8 +1072,8 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
|
|||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "license")) {
|
||||
/**********************************************************************/
|
||||
strcpy(g_ftdm_sngss7_data.cfg.license, parm->val);
|
||||
strcpy(g_ftdm_sngss7_data.cfg.signature, parm->val);
|
||||
strncpy(g_ftdm_sngss7_data.cfg.license, parm->val, MAX_PATH-1);
|
||||
strncpy(g_ftdm_sngss7_data.cfg.signature, parm->val, MAX_PATH-1);
|
||||
strcat(g_ftdm_sngss7_data.cfg.signature, ".sig");
|
||||
SS7_DEBUG("\tFound license file = %s\n", g_ftdm_sngss7_data.cfg.license);
|
||||
SS7_DEBUG("\tFound signature file = %s\n", g_ftdm_sngss7_data.cfg.signature);
|
||||
|
@ -1304,6 +1309,13 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
|
|||
sng_isup.clg_nadi = 0x03;
|
||||
}
|
||||
|
||||
/* check if the user requested min_digits value */
|
||||
if (sng_isup.min_digits == 0) {
|
||||
/* default to 7 */
|
||||
sng_isup.min_digits = 7;
|
||||
}
|
||||
|
||||
|
||||
/* trickle down the SPC to all sub entities */
|
||||
linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].linkSetId;
|
||||
|
||||
|
@ -1359,7 +1371,7 @@ static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink)
|
|||
}
|
||||
|
||||
/* fill in the information */
|
||||
strcpy((char *)g_ftdm_sngss7_data.cfg.mtpLink[i].name, (char *)mtpLink->name);
|
||||
strncpy((char *)g_ftdm_sngss7_data.cfg.mtpLink[i].name, (char *)mtpLink->name, MAX_NAME_LEN-1);
|
||||
|
||||
g_ftdm_sngss7_data.cfg.mtpLink[i].id = mtpLink->id;
|
||||
|
||||
|
@ -1521,7 +1533,7 @@ static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet)
|
|||
{
|
||||
int i = mtpLinkSet->id;
|
||||
|
||||
strcpy((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[i].name, (char *)mtpLinkSet->name);
|
||||
strncpy((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[i].name, (char *)mtpLinkSet->name, MAX_NAME_LEN-1);
|
||||
|
||||
g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id = mtpLinkSet->id;
|
||||
g_ftdm_sngss7_data.cfg.mtpLinkSet[i].apc = mtpLinkSet->apc;
|
||||
|
@ -1559,7 +1571,7 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route)
|
|||
SS7_DEBUG("found existing mtp3_route, id is = %d\n", mtp3_route->id);
|
||||
}
|
||||
|
||||
strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, (char *)mtp3_route->name);
|
||||
strncpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, (char *)mtp3_route->name, MAX_NAME_LEN-1);
|
||||
|
||||
g_ftdm_sngss7_data.cfg.mtpRoute[i].id = mtp3_route->id;
|
||||
g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc = mtp3_route->dpc;
|
||||
|
@ -1693,7 +1705,7 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup)
|
|||
SS7_DEBUG("found existing isup interface, id is = %d\n", sng_isup->id);
|
||||
}
|
||||
|
||||
strcpy((char *)g_ftdm_sngss7_data.cfg.isupIntf[i].name, (char *)sng_isup->name);
|
||||
strncpy((char *)g_ftdm_sngss7_data.cfg.isupIntf[i].name, (char *)sng_isup->name, MAX_NAME_LEN-1);
|
||||
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].id = sng_isup->id;
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].mtpRouteId = sng_isup->mtpRouteId;
|
||||
|
@ -1705,6 +1717,7 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup)
|
|||
g_ftdm_sngss7_data.cfg.isupIntf[i].isap = sng_isup->isap;
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].cld_nadi = sng_isup->cld_nadi;
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].clg_nadi = sng_isup->clg_nadi;
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].min_digits = sng_isup->min_digits;
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].options = sng_isup->options;
|
||||
if (sng_isup->t4 != 0) {
|
||||
g_ftdm_sngss7_data.cfg.isupIntf[i].t4 = sng_isup->t4;
|
||||
|
@ -1976,7 +1989,7 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i
|
|||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[0].name, "self-route");
|
||||
strncpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[0].name, "self-route", MAX_NAME_LEN-1);
|
||||
|
||||
g_ftdm_sngss7_data.cfg.mtpRoute[0].id = 0;
|
||||
g_ftdm_sngss7_data.cfg.mtpRoute[0].dpc = spc;
|
||||
|
@ -2230,7 +2243,7 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot)
|
|||
int lower;
|
||||
int upper;
|
||||
char tmp[5]; /*KONRAD FIX ME*/
|
||||
char new_ch_map[MAX_CIC_LENGTH];
|
||||
char new_ch_map[MAX_CIC_MAP_LENGTH];
|
||||
|
||||
memset(&tmp[0], '\0', sizeof(tmp));
|
||||
memset(&new_ch_map[0], '\0', sizeof(new_ch_map));
|
||||
|
@ -2337,7 +2350,9 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot)
|
|||
/* the the rest of ch_map to new_ch_map */
|
||||
strncat(new_ch_map, &ch_map[x], strlen(&ch_map[x]));
|
||||
|
||||
|
||||
/* set the new cic map to ch_map*/
|
||||
memset(ch_map, '\0', sizeof(ch_map));
|
||||
strcpy(ch_map, new_ch_map);
|
||||
|
||||
} else if (ch_map[x] == ',') {
|
||||
|
@ -2345,16 +2360,21 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot)
|
|||
x++;
|
||||
|
||||
/* copy the rest of the list to new_ch_map */
|
||||
memset(new_ch_map, '\0', sizeof(new_ch_map));
|
||||
strcpy(new_ch_map, &ch_map[x]);
|
||||
|
||||
/* copy the new_ch_map over the old one */
|
||||
memset(ch_map, '\0', sizeof(ch_map));
|
||||
strcpy(ch_map, new_ch_map);
|
||||
|
||||
} else if (ch_map[x] == '\0') {
|
||||
|
||||
/* we're at the end of the string...copy the rest of the list to new_ch_map */
|
||||
memset(new_ch_map, '\0', sizeof(new_ch_map));
|
||||
strcpy(new_ch_map, &ch_map[x]);
|
||||
|
||||
/* set the new cic map to ch_map*/
|
||||
memset(ch_map, '\0', sizeof(ch_map));
|
||||
strcpy(ch_map, new_ch_map);
|
||||
} else {
|
||||
/* nothing to do */
|
||||
|
|
|
@ -811,13 +811,14 @@ static void wanpipe_write_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_tx_hdr_t *t
|
|||
ftdm_clear_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
|
||||
}
|
||||
|
||||
if (ftdmchan->iostats.tx.idle_packets < tx_stats->wp_api_tx_hdr_number_of_frames_in_queue) {
|
||||
ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets;
|
||||
if (ftdmchan->iostats.tx.idle_packets < tx_stats->wp_api_tx_hdr_tx_idle_packets) {
|
||||
/* HDLC channels do not always transmit, so its ok for drivers to fill with idle
|
||||
* also do not report idle warning when we just started transmitting */
|
||||
if (ftdmchan->iostats.tx.packets && FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx idle: %d\n", ftdmchan->iostats.tx.idle_packets);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx idle changed from %d to %d\n",
|
||||
ftdmchan->iostats.tx.idle_packets, tx_stats->wp_api_tx_hdr_tx_idle_packets);
|
||||
}
|
||||
ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets;
|
||||
}
|
||||
|
||||
if (!ftdmchan->iostats.tx.packets) {
|
||||
|
@ -941,7 +942,6 @@ static FIO_WRITE_FUNCTION(wanpipe_write)
|
|||
{
|
||||
int bsent = 0;
|
||||
int err = 0;
|
||||
ftdm_time_t ms = 0;
|
||||
wp_tdm_api_tx_hdr_t hdrframe;
|
||||
|
||||
/* Do we even need the headerframe here? on windows, we don't even pass it to the driver */
|
||||
|
@ -1051,16 +1051,34 @@ FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event)
|
|||
|
||||
for(i = 1; i <= span->chan_count; i++) {
|
||||
ftdm_channel_t *ftdmchan = span->channels[i];
|
||||
uint32_t chan_events = 0;
|
||||
|
||||
/* translate events from ftdm to libsnagoma. if the user don't specify which events to poll the
|
||||
* channel for, we just use SANG_WAIT_OBJ_HAS_EVENTS */
|
||||
if (poll_events) {
|
||||
if (poll_events[j] & FTDM_READ) {
|
||||
chan_events = SANG_WAIT_OBJ_HAS_INPUT;
|
||||
}
|
||||
if (poll_events[j] & FTDM_WRITE) {
|
||||
chan_events |= SANG_WAIT_OBJ_HAS_OUTPUT;
|
||||
}
|
||||
if (poll_events[j] & FTDM_EVENTS) {
|
||||
chan_events |= SANG_WAIT_OBJ_HAS_EVENTS;
|
||||
}
|
||||
} else {
|
||||
chan_events = SANG_WAIT_OBJ_HAS_EVENTS;
|
||||
}
|
||||
|
||||
#ifdef LIBSANGOMA_VERSION
|
||||
if (!ftdmchan->io_data) {
|
||||
continue; /* should never happen but happens when shutting down */
|
||||
}
|
||||
pfds[j] = ftdmchan->io_data;
|
||||
inflags[j] = poll_events ? poll_events[j] : POLLPRI;
|
||||
inflags[j] = chan_events;
|
||||
#else
|
||||
memset(&pfds[j], 0, sizeof(pfds[j]));
|
||||
pfds[j].fd = span->channels[i]->sockfd;
|
||||
pfds[j].events = poll_events ? poll_events[j] : POLLPRI;
|
||||
pfds[j].events = chan_events;
|
||||
#endif
|
||||
|
||||
/* The driver probably should be able to do this wink/flash/ringing by itself this is sort of a hack to make it work! */
|
||||
|
|
|
@ -31,10 +31,14 @@
|
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "private/ftdm_core.h"
|
||||
#include "ftmod_zt.h"
|
||||
|
||||
/* used by dahdi to indicate there is no data available, but events to read */
|
||||
#ifndef ELAST
|
||||
#define ELAST 500
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Zaptel globals
|
||||
*/
|
||||
|
@ -48,42 +52,48 @@ static struct {
|
|||
float txgain;
|
||||
} zt_globals;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
typedef unsigned long ioctlcmd;
|
||||
#else
|
||||
typedef int ioctlcmd;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief General IOCTL codes
|
||||
*/
|
||||
struct ioctl_codes {
|
||||
int GET_BLOCKSIZE;
|
||||
int SET_BLOCKSIZE;
|
||||
int FLUSH;
|
||||
int SYNC;
|
||||
int GET_PARAMS;
|
||||
int SET_PARAMS;
|
||||
int HOOK;
|
||||
int GETEVENT;
|
||||
int IOMUX;
|
||||
int SPANSTAT;
|
||||
int MAINT;
|
||||
int GETCONF;
|
||||
int SETCONF;
|
||||
int CONFLINK;
|
||||
int CONFDIAG;
|
||||
int GETGAINS;
|
||||
int SETGAINS;
|
||||
int SPANCONFIG;
|
||||
int CHANCONFIG;
|
||||
int SET_BUFINFO;
|
||||
int GET_BUFINFO;
|
||||
int AUDIOMODE;
|
||||
int ECHOCANCEL;
|
||||
int HDLCRAWMODE;
|
||||
int HDLCFCSMODE;
|
||||
int SPECIFY;
|
||||
int SETLAW;
|
||||
int SETLINEAR;
|
||||
int GETCONFMUTE;
|
||||
int ECHOTRAIN;
|
||||
int SETTXBITS;
|
||||
int GETRXBITS;
|
||||
ioctlcmd GET_BLOCKSIZE;
|
||||
ioctlcmd SET_BLOCKSIZE;
|
||||
ioctlcmd FLUSH;
|
||||
ioctlcmd SYNC;
|
||||
ioctlcmd GET_PARAMS;
|
||||
ioctlcmd SET_PARAMS;
|
||||
ioctlcmd HOOK;
|
||||
ioctlcmd GETEVENT;
|
||||
ioctlcmd IOMUX;
|
||||
ioctlcmd SPANSTAT;
|
||||
ioctlcmd MAINT;
|
||||
ioctlcmd GETCONF;
|
||||
ioctlcmd SETCONF;
|
||||
ioctlcmd CONFLINK;
|
||||
ioctlcmd CONFDIAG;
|
||||
ioctlcmd GETGAINS;
|
||||
ioctlcmd SETGAINS;
|
||||
ioctlcmd SPANCONFIG;
|
||||
ioctlcmd CHANCONFIG;
|
||||
ioctlcmd SET_BUFINFO;
|
||||
ioctlcmd GET_BUFINFO;
|
||||
ioctlcmd AUDIOMODE;
|
||||
ioctlcmd ECHOCANCEL;
|
||||
ioctlcmd HDLCRAWMODE;
|
||||
ioctlcmd HDLCFCSMODE;
|
||||
ioctlcmd SPECIFY;
|
||||
ioctlcmd SETLAW;
|
||||
ioctlcmd SETLINEAR;
|
||||
ioctlcmd GETCONFMUTE;
|
||||
ioctlcmd ECHOTRAIN;
|
||||
ioctlcmd SETTXBITS;
|
||||
ioctlcmd GETRXBITS;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1183,7 +1193,6 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
|
|||
}
|
||||
|
||||
return FTDM_FAIL;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1202,12 +1211,19 @@ static FIO_READ_FUNCTION(zt_read)
|
|||
if ((r = read(ftdmchan->sockfd, data, *datalen)) > 0) {
|
||||
break;
|
||||
}
|
||||
ftdm_sleep(10);
|
||||
if (r == 0) {
|
||||
errs--;
|
||||
else if (r == 0) {
|
||||
ftdm_sleep(10);
|
||||
if (errs) errs--;
|
||||
}
|
||||
else {
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
continue;
|
||||
if (errno == ELAST)
|
||||
break;
|
||||
|
||||
ftdm_log(FTDM_LOG_ERROR, "read failed: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (r > 0) {
|
||||
*datalen = r;
|
||||
if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) {
|
||||
|
@ -1215,7 +1231,9 @@ static FIO_READ_FUNCTION(zt_read)
|
|||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
else if (errno == ELAST) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
return r == 0 ? FTDM_TIMEOUT : FTDM_FAIL;
|
||||
}
|
||||
|
||||
|
@ -1236,6 +1254,7 @@ static FIO_WRITE_FUNCTION(zt_write)
|
|||
bytes += 2;
|
||||
}
|
||||
|
||||
tryagain:
|
||||
w = write(ftdmchan->sockfd, data, bytes);
|
||||
|
||||
if (w >= 0) {
|
||||
|
@ -1243,6 +1262,17 @@ static FIO_WRITE_FUNCTION(zt_write)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
if (errno == ELAST) {
|
||||
zt_event_t zt_event_id = 0;
|
||||
if (ioctl(ftdmchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed retrieving event after ELAST on write: %s\n", strerror(errno));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
/* we should enqueue this event somewhere so it can be retrieved by the user, for now, dropping it to see what it is! */
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dropping event %d to be able to write data\n", zt_event_id);
|
||||
goto tryagain;
|
||||
}
|
||||
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
|
|
|
@ -144,7 +144,9 @@ typedef enum {
|
|||
/*! \brief Hunting direction (when hunting for free channels) */
|
||||
typedef enum {
|
||||
FTDM_TOP_DOWN,
|
||||
FTDM_BOTTOM_UP
|
||||
FTDM_BOTTOM_UP,
|
||||
FTDM_RR_DOWN,
|
||||
FTDM_RR_UP,
|
||||
} ftdm_direction_t;
|
||||
|
||||
/*! \brief I/O channel type */
|
||||
|
@ -265,13 +267,32 @@ typedef enum {
|
|||
#define USER_LAYER1_PROT_STRINGS "V.110", "u-law", "a-law", "Invalid"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_usr_layer1_prot, ftdm_user_layer1_prot2str, ftdm_user_layer1_prot_t)
|
||||
|
||||
/*! Calling Party Category */
|
||||
typedef enum {
|
||||
FTDM_CPC_UNKNOWN,
|
||||
FTDM_CPC_OPERATOR,
|
||||
FTDM_CPC_ORDINARY,
|
||||
FTDM_CPC_PRIORITY,
|
||||
FTDM_CPC_DATA,
|
||||
FTDM_CPC_TEST,
|
||||
FTDM_CPC_PAYPHONE,
|
||||
FTDM_CPC_INVALID
|
||||
} ftdm_calling_party_category_t;
|
||||
#define CALLING_PARTY_CATEGORY_STRINGS "unknown", "operator", "ordinary", "priority", "data-call", "test-call", "payphone", "invalid"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_calling_party_category, ftdm_calling_party_category2str, ftdm_calling_party_category_t)
|
||||
|
||||
/*! \brief Digit limit used in DNIS/ANI */
|
||||
#define FTDM_DIGITS_LIMIT 25
|
||||
|
||||
/*! \brief Number abstraction */
|
||||
typedef struct {
|
||||
char digits[25];
|
||||
char digits[FTDM_DIGITS_LIMIT];
|
||||
uint8_t type;
|
||||
uint8_t plan;
|
||||
} ftdm_number_t;
|
||||
|
||||
typedef void * ftdm_variable_container_t;
|
||||
|
||||
/*! \brief Caller information */
|
||||
typedef struct ftdm_caller_data {
|
||||
char cid_date[8]; /*!< Caller ID date */
|
||||
|
@ -280,18 +301,25 @@ typedef struct ftdm_caller_data {
|
|||
ftdm_number_t ani; /*!< ANI (Automatic Number Identification) */
|
||||
ftdm_number_t dnis; /*!< DNIS (Dialed Number Identification Service) */
|
||||
ftdm_number_t rdnis; /*!< RDNIS (Redirected Dialed Number Identification Service) */
|
||||
char aniII[25]; /*! ANI II */
|
||||
char aniII[FTDM_DIGITS_LIMIT]; /*! ANI II */
|
||||
uint8_t screen; /*!< Screening */
|
||||
uint8_t pres; /*!< Presentation*/
|
||||
char collected[25]; /*!< Collected digits so far */
|
||||
char collected[FTDM_DIGITS_LIMIT]; /*!< Collected digits so far */
|
||||
int hangup_cause; /*!< Hangup cause */
|
||||
char raw_data[1024]; /*!< Protocol specific raw caller data */
|
||||
uint32_t raw_data_len; /* !< Raw data length */
|
||||
uint32_t raw_data_len; /*!< Raw data length */
|
||||
/* these 2 are undocumented right now, only used by boost: */
|
||||
/* bearer capability */
|
||||
ftdm_bearer_cap_t bearer_capability;
|
||||
/* user information layer 1 protocol */
|
||||
ftdm_user_layer1_prot_t bearer_layer1;
|
||||
ftdm_calling_party_category_t cpc; /*!< Calling party category */
|
||||
ftdm_variable_container_t variables; /*!< Variables attached to this call */
|
||||
/* We need call_id inside caller_data for the user to be able to retrieve
|
||||
* the call_id when ftdm_channel_call_place is called. This is the only time
|
||||
* that the user can use caller_data.call_id to obtain the call_id. The user
|
||||
* should use the call_id from sigmsg otherwise */
|
||||
uint32_t call_id; /*!< Unique call ID for this call */
|
||||
} ftdm_caller_data_t;
|
||||
|
||||
/*! \brief Tone type */
|
||||
|
@ -306,7 +334,8 @@ typedef enum {
|
|||
FTDM_SIGEVENT_RELEASED, /*!< Channel is completely released and available */
|
||||
FTDM_SIGEVENT_UP, /*!< Outgoing call has been answered */
|
||||
FTDM_SIGEVENT_FLASH, /*!< Flash event (typically on-hook/off-hook for analog devices) */
|
||||
FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got a response */
|
||||
FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got a response */
|
||||
FTDM_SIGEVENT_RINGING, /*!< Remote side is in ringing state */
|
||||
FTDM_SIGEVENT_PROGRESS, /*!< Outgoing call is making progress */
|
||||
FTDM_SIGEVENT_PROGRESS_MEDIA, /*!< Outgoing call is making progress and there is media available */
|
||||
FTDM_SIGEVENT_ALARM_TRAP, /*!< Hardware alarm ON */
|
||||
|
@ -316,12 +345,14 @@ typedef enum {
|
|||
FTDM_SIGEVENT_RESTART, /*!< Restart has been requested. Typically you hangup your call resources here */
|
||||
FTDM_SIGEVENT_SIGSTATUS_CHANGED, /*!< Signaling protocol status changed (ie: D-chan up), see new status in raw_data ftdm_sigmsg_t member */
|
||||
FTDM_SIGEVENT_COLLISION, /*!< Outgoing call was dropped because an incoming call arrived at the same time */
|
||||
FTDM_SIGEVENT_MSG, /*!< We received an in-call msg */
|
||||
FTDM_SIGEVENT_INVALID
|
||||
FTDM_SIGEVENT_FACILITY, /*!< In call facility event */
|
||||
FTDM_SIGEVENT_TRACE, /*!<Interpreted trace event */
|
||||
FTDM_SIGEVENT_TRACE_RAW, /*!<Raw trace event */
|
||||
FTDM_SIGEVENT_INVALID, /*!<Invalid */
|
||||
} ftdm_signal_event_t;
|
||||
#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "PROGRESS", \
|
||||
#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "RINGING", "PROGRESS", \
|
||||
"PROGRESS_MEDIA", "ALARM_TRAP", "ALARM_CLEAR", \
|
||||
"COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "MSG", "INVALID"
|
||||
"COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "FACILITY", "TRACE", "TRACE_RAW", "INVALID"
|
||||
|
||||
/*! \brief Move from string to ftdm_signal_event_t and viceversa */
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_signal_event, ftdm_signal_event2str, ftdm_signal_event_t)
|
||||
|
@ -356,6 +387,7 @@ typedef struct ftdm_channel_config {
|
|||
|
||||
/*!
|
||||
\brief Signaling status on a given span or specific channel on protocols that support it
|
||||
\note see docs/sigstatus.txt for more extensive documentation on signaling status
|
||||
*/
|
||||
typedef enum {
|
||||
/* The signaling link is down (no d-chans up in the span/group, MFC-R2 bit pattern unidentified) */
|
||||
|
@ -372,15 +404,52 @@ typedef enum {
|
|||
/*! \brief Move from string to ftdm_signaling_status_t and viceversa */
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_signaling_status, ftdm_signaling_status2str, ftdm_signaling_status_t)
|
||||
|
||||
|
||||
typedef struct {
|
||||
ftdm_signaling_status_t status;
|
||||
} ftdm_event_sigstatus_t;
|
||||
|
||||
typedef enum {
|
||||
/* This is an received frame */
|
||||
FTDM_TRACE_INCOMING,
|
||||
/* This is a transmitted frame */
|
||||
FTDM_TRACE_OUTGOING,
|
||||
/* Invalid */
|
||||
FTDM_TRACE_INVALID,
|
||||
} ftdm_trace_dir_t;
|
||||
#define TRACE_DIR_STRINGS "INCOMING", "OUTGOING", "INVALID"
|
||||
|
||||
/*! \brief Move string to ftdm_trace_dir_t and viceversa */
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_trace_dir, ftdm_trace_dir2str, ftdm_trace_dir_t)
|
||||
|
||||
typedef struct {
|
||||
/* Direction - incoming or outgoing */
|
||||
ftdm_trace_dir_t dir;
|
||||
uint8_t level; /* 1 for phy layer, 2 for q921/mtp2, 3 for q931/mtp3 */
|
||||
} ftdm_event_trace_t;
|
||||
|
||||
typedef struct {
|
||||
/* Digits collected */
|
||||
char digits[FTDM_DIGITS_LIMIT];
|
||||
} ftdm_event_collected_t;
|
||||
|
||||
/*! \brief Generic signaling message */
|
||||
struct ftdm_sigmsg {
|
||||
ftdm_signal_event_t event_id; /*!< The type of message */
|
||||
ftdm_channel_t *channel; /*!< Related channel */
|
||||
uint32_t chan_id; /*!< easy access to chan id */
|
||||
uint32_t span_id; /*!< easy access to span_id */
|
||||
ftdm_signaling_status_t sigstatus; /*!< Signaling status (valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED) */
|
||||
void *raw_data; /*!< Message specific data if any */
|
||||
uint32_t raw_data_len; /*!< Data len in case is needed */
|
||||
uint32_t call_id; /*!< unique call id for this call */
|
||||
union {
|
||||
ftdm_event_sigstatus_t sigstatus; /*!< valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED */
|
||||
ftdm_event_trace_t logevent; /*!< valid if event_id is FTDM_SIGEVENT_TRACE or FTDM_SIGEVENT_TRACE_RAW */
|
||||
ftdm_event_collected_t collected; /*!< valif if event_id is FTDM_SIGEVENT_COLLECTED_DIGIT */
|
||||
} ev_data;
|
||||
struct {
|
||||
uint8_t autofree; /*!< Whether the freetdm core will free it after message delivery */
|
||||
uint32_t len; /*!< Data len */
|
||||
void *data; /*!< Signaling module specific data */
|
||||
} raw;
|
||||
};
|
||||
|
||||
/*! \brief Crash policy
|
||||
|
@ -507,6 +576,7 @@ struct ftdm_memory_handler {
|
|||
* You don't need these unless your implementing an I/O interface module (most users don't) */
|
||||
#define FIO_CHANNEL_REQUEST_ARGS (ftdm_span_t *span, uint32_t chan_id, ftdm_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan)
|
||||
#define FIO_CHANNEL_OUTGOING_CALL_ARGS (ftdm_channel_t *ftdmchan)
|
||||
#define FIO_CHANNEL_SEND_MSG_ARGS (ftdm_channel_t *ftdmchan, ftdm_sigmsg_t *sigmsg)
|
||||
#define FIO_CHANNEL_SET_SIG_STATUS_ARGS (ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status)
|
||||
#define FIO_CHANNEL_GET_SIG_STATUS_ARGS (ftdm_channel_t *ftdmchan, ftdm_signaling_status_t *status)
|
||||
#define FIO_SPAN_SET_SIG_STATUS_ARGS (ftdm_span_t *span, ftdm_signaling_status_t status)
|
||||
|
@ -539,6 +609,7 @@ struct ftdm_memory_handler {
|
|||
* You don't need these unless your implementing an I/O interface module (most users don't) */
|
||||
typedef ftdm_status_t (*fio_channel_request_t) FIO_CHANNEL_REQUEST_ARGS ;
|
||||
typedef ftdm_status_t (*fio_channel_outgoing_call_t) FIO_CHANNEL_OUTGOING_CALL_ARGS ;
|
||||
typedef ftdm_status_t (*fio_channel_send_msg_t) FIO_CHANNEL_SEND_MSG_ARGS;
|
||||
typedef ftdm_status_t (*fio_channel_set_sig_status_t) FIO_CHANNEL_SET_SIG_STATUS_ARGS;
|
||||
typedef ftdm_status_t (*fio_channel_get_sig_status_t) FIO_CHANNEL_GET_SIG_STATUS_ARGS;
|
||||
typedef ftdm_status_t (*fio_span_set_sig_status_t) FIO_SPAN_SET_SIG_STATUS_ARGS;
|
||||
|
@ -572,6 +643,7 @@ typedef ftdm_status_t (*fio_api_t) FIO_API_ARGS ;
|
|||
* You don't need these unless your implementing an I/O interface module (most users don't) */
|
||||
#define FIO_CHANNEL_REQUEST_FUNCTION(name) ftdm_status_t name FIO_CHANNEL_REQUEST_ARGS
|
||||
#define FIO_CHANNEL_OUTGOING_CALL_FUNCTION(name) ftdm_status_t name FIO_CHANNEL_OUTGOING_CALL_ARGS
|
||||
#define FIO_CHANNEL_SEND_MSG_FUNCTION(name) ftdm_status_t name FIO_CHANNEL_SEND_MSG_ARGS
|
||||
#define FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(name) ftdm_status_t name FIO_CHANNEL_SET_SIG_STATUS_ARGS
|
||||
#define FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(name) ftdm_status_t name FIO_CHANNEL_GET_SIG_STATUS_ARGS
|
||||
#define FIO_SPAN_SET_SIG_STATUS_FUNCTION(name) ftdm_status_t name FIO_SPAN_SET_SIG_STATUS_ARGS
|
||||
|
@ -654,6 +726,14 @@ typedef enum {
|
|||
/*! \brief Override the default queue handler */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_global_set_queue_handler(ftdm_queue_handler_t *handler);
|
||||
|
||||
/*! \brief Return the availability rate for a channel
|
||||
* \param ftdmchan Channel to get the availability from
|
||||
*
|
||||
* \retval > 0 if availability is supported
|
||||
* \retval -1 if availability is not supported
|
||||
*/
|
||||
FT_DECLARE(int) ftdm_channel_get_availability(ftdm_channel_t *ftdmchan);
|
||||
|
||||
/*! \brief Answer call */
|
||||
#define ftdm_channel_call_answer(ftdmchan) _ftdm_channel_call_answer(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
|
||||
|
||||
|
@ -672,6 +752,12 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char
|
|||
/*! \brief Indicate a new condition in an incoming call recording the source code point where it was called (see ftdm_channel_call_indicate for an easy to use macro) */
|
||||
FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication);
|
||||
|
||||
/*! \brief Send a message on a call */
|
||||
#define ftdm_channel_call_send_msg(ftdmchan, sigmsg) _ftdm_channel_call_send_msg(__FILE__, __FUNCTION__, __LINE__, (ftdmchan), (sigmsg))
|
||||
|
||||
/*! \brief Send a signal on a call recording the source code point where it was called (see ftdm_channel_call_send_msg for an easy to use macro) */
|
||||
FT_DECLARE(ftdm_status_t) _ftdm_channel_call_send_msg(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_sigmsg_t *sigmsg);
|
||||
|
||||
/*! \brief Hangup the call without cause */
|
||||
#define ftdm_channel_call_hangup(ftdmchan) _ftdm_channel_call_hangup(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
|
||||
|
||||
|
@ -684,6 +770,14 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup(const char *file, const char
|
|||
/*! \brief Hangup the call with cause recording the source code point where it was called (see ftdm_channel_call_hangup_with_cause for an easy to use macro) */
|
||||
FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup_with_cause(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_call_cause_t);
|
||||
|
||||
/*! \brief Reset the channel */
|
||||
#define ftdm_channel_reset(ftdmchan) _ftdm_channel_reset(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
|
||||
|
||||
/*! \brief Reset the channel (see _ftdm_channel_reset for an easy to use macro)
|
||||
* \note if there was a call on this channel, call will be cleared without any notifications to the user
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan);
|
||||
|
||||
/*! \brief Put a call on hold (if supported by the signaling stack) */
|
||||
#define ftdm_channel_call_hold(ftdmchan) _ftdm_channel_call_hold(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
|
||||
|
||||
|
@ -723,6 +817,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_set_sig_status(ftdm_span_t *span, ftdm_signa
|
|||
/*! \brief Get span signaling status (ie: whether protocol layer is up or down) */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signaling_status_t *status);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Set user private data in the channel
|
||||
*
|
||||
|
@ -1128,6 +1223,45 @@ FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter);
|
|||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_iterator_free(ftdm_iterator_t *iter);
|
||||
|
||||
/*! \brief Add a custom variable to the call
|
||||
* \note This variables may be used by signaling modules to override signaling parameters
|
||||
* \todo Document which signaling variables are available
|
||||
* */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_call_add_var(ftdm_caller_data_t *caller_data, const char *var_name, const char *value);
|
||||
|
||||
/*! \brief Get a custom variable from the call.
|
||||
* \note The variable pointer returned is only valid during the callback receiving SIGEVENT. */
|
||||
FT_DECLARE(const char *) ftdm_call_get_var(ftdm_caller_data_t *caller_data, const char *var_name);
|
||||
|
||||
/*! \brief Get an iterator to iterate over the channel variables
|
||||
* \param caller_data The signal msg structure containing the variables
|
||||
* \param iter Optional iterator. You can reuse an old iterator (not previously freed) to avoid the extra allocation of a new iterator.
|
||||
* \note The iterator pointer returned is only valid while the signal message and it'll be destroyed when the signal message is processed.
|
||||
* This iterator is completely non-thread safe, if you are adding variables or removing variables while iterating
|
||||
* results are unpredictable
|
||||
*/
|
||||
FT_DECLARE(ftdm_iterator_t *) ftdm_call_get_var_iterator(const ftdm_caller_data_t *caller_data, ftdm_iterator_t *iter);
|
||||
|
||||
/*! \brief Get variable name and value for the current iterator position */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_call_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val);
|
||||
|
||||
/*! \brief Clear all variables attached to the call
|
||||
* \note Variables are cleared at the end of each call back, so it is not necessary for the user to call this function.
|
||||
* \todo Document which signaling variables are available
|
||||
* */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_call_clear_vars(ftdm_caller_data_t *caller_data);
|
||||
|
||||
/*! \brief Remove a variable attached to the call
|
||||
* \note Removes a variable that was attached to the call.
|
||||
* \todo Document which call variables are available
|
||||
* */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_call_remove_var(ftdm_caller_data_t *caller_data, const char *var_name);
|
||||
|
||||
/*! \brief Clears all the temporary data attached to this call
|
||||
* \note Clears caller_data->variables and caller_data->raw_data.
|
||||
* */
|
||||
FT_DECLARE(void) ftdm_call_clear_data(ftdm_caller_data_t *caller_data);
|
||||
|
||||
/*! \brief Get the span pointer associated to the channel */
|
||||
FT_DECLARE(ftdm_span_t *) ftdm_channel_get_span(const ftdm_channel_t *ftdmchan);
|
||||
|
||||
|
|
|
@ -30,6 +30,12 @@
|
|||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
* Moises Silva <moy@sangoma.com>
|
||||
* Ricardo Barroetaveña <rbarroetavena@anura.com.ar>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FTDM_CALL_UTILS_H__
|
||||
|
@ -114,5 +120,16 @@ FT_DECLARE(ftdm_status_t) ftdm_set_presentation_ind(const char *string, uint8_t
|
|||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number);
|
||||
|
||||
/*!
|
||||
* \brief Set the Calling Party Category from an enum
|
||||
*
|
||||
* \param cpc_string string value
|
||||
* \param target the target to set value to
|
||||
*
|
||||
* \retval FTDM_SUCCESS success
|
||||
* \retval FTDM_FAIL failure
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_set_calling_party_category(const char *string, uint8_t *target);
|
||||
|
||||
#endif /* __FTDM_CALL_UTILS_H__ */
|
||||
|
||||
|
|
|
@ -158,12 +158,16 @@ typedef __int64 int64_t;
|
|||
typedef __int32 int32_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int8 int8_t;
|
||||
#define FTDM_O_BINARY O_BINARY
|
||||
#define FTDM_SIZE_FMT "Id"
|
||||
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
|
||||
#else
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
|
||||
#endif /* _MSC_VER */
|
||||
#else /* __WINDOWS__ */
|
||||
#define FTDM_O_BINARY 0
|
||||
#define FTDM_SIZE_FMT "zd"
|
||||
#define FTDM_INVALID_SOCKET -1
|
||||
typedef int ftdm_socket_t;
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -39,9 +39,12 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && !defined(__USE_BSD)
|
||||
#define __USE_BSD
|
||||
#endif
|
||||
|
||||
#include "ftdm_declare.h"
|
||||
#include "ftdm_threadmutex.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef __WINDOWS__
|
||||
|
|
|
@ -411,7 +411,7 @@ struct ftdm_channel {
|
|||
uint32_t extra_id;
|
||||
ftdm_chan_type_t type;
|
||||
ftdm_socket_t sockfd;
|
||||
uint32_t flags;
|
||||
uint64_t flags;
|
||||
uint32_t pflags;
|
||||
uint32_t sflags;
|
||||
ftdm_alarm_flag_t alarm_flags;
|
||||
|
@ -493,6 +493,7 @@ struct ftdm_span {
|
|||
ftdm_trunk_type_t trunk_type;
|
||||
ftdm_analog_start_type_t start_type;
|
||||
ftdm_signal_type_t signal_type;
|
||||
uint32_t last_used_index;
|
||||
/* Private signaling data. Do not touch unless you are a signaling module */
|
||||
void *signal_data;
|
||||
fio_signal_cb_t signal_cb;
|
||||
|
@ -503,6 +504,7 @@ struct ftdm_span {
|
|||
teletone_multi_tone_t tone_finder[FTDM_TONEMAP_INVALID+1];
|
||||
ftdm_channel_t *channels[FTDM_MAX_CHANNELS_SPAN+1];
|
||||
fio_channel_outgoing_call_t outgoing_call;
|
||||
fio_channel_send_msg_t send_msg;
|
||||
fio_channel_set_sig_status_t set_channel_sig_status;
|
||||
fio_channel_get_sig_status_t get_channel_sig_status;
|
||||
fio_span_set_sig_status_t set_span_sig_status;
|
||||
|
@ -598,7 +600,6 @@ FT_DECLARE(void) ftdm_channel_rotate_tokens(ftdm_channel_t *ftdmchan);
|
|||
FT_DECLARE(int) ftdm_load_module(const char *name);
|
||||
FT_DECLARE(int) ftdm_load_module_assume(const char *name);
|
||||
FT_DECLARE(int) ftdm_vasprintf(char **ret, const char *fmt, va_list ap);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan);
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_close_all(void);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan);
|
||||
|
|
|
@ -184,6 +184,9 @@ typedef enum {
|
|||
FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 10),
|
||||
/* If this flag is set, channel will be moved to proceed state when calls goes to routing */
|
||||
FTDM_SPAN_USE_PROCEED_STATE = (1 << 11),
|
||||
/* If this flag is set, the signalling module supports jumping directly to state up, without
|
||||
going through PROGRESS/PROGRESS_MEDIA */
|
||||
FTDM_SPAN_USE_SKIP_STATES = (1 << 12),
|
||||
} ftdm_span_flag_t;
|
||||
|
||||
/*! \brief Channel supported features */
|
||||
|
@ -225,60 +228,50 @@ typedef enum {
|
|||
FTDM_CHANNEL_STATE_HANGUP,
|
||||
FTDM_CHANNEL_STATE_HANGUP_COMPLETE,
|
||||
FTDM_CHANNEL_STATE_IN_LOOP,
|
||||
FTDM_CHANNEL_STATE_RESET,
|
||||
FTDM_CHANNEL_STATE_INVALID
|
||||
} ftdm_channel_state_t;
|
||||
#define CHANNEL_STATE_STRINGS "DOWN", "HOLD", "SUSPENDED", "DIALTONE", "COLLECT", \
|
||||
"RING", "RINGING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \
|
||||
"RESTART", "PROCEED", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", \
|
||||
"HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "INVALID"
|
||||
"HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "RESET", "INVALID"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t)
|
||||
|
||||
typedef enum {
|
||||
FTDM_CHANNEL_CONFIGURED = (1 << 0),
|
||||
FTDM_CHANNEL_READY = (1 << 1),
|
||||
FTDM_CHANNEL_OPEN = (1 << 2),
|
||||
FTDM_CHANNEL_DTMF_DETECT = (1 << 3),
|
||||
FTDM_CHANNEL_SUPRESS_DTMF = (1 << 4),
|
||||
FTDM_CHANNEL_TRANSCODE = (1 << 5),
|
||||
FTDM_CHANNEL_BUFFER = (1 << 6),
|
||||
FTDM_CHANNEL_EVENT = (1 << 7),
|
||||
FTDM_CHANNEL_INTHREAD = (1 << 8),
|
||||
FTDM_CHANNEL_WINK = (1 << 9),
|
||||
FTDM_CHANNEL_FLASH = (1 << 10),
|
||||
FTDM_CHANNEL_STATE_CHANGE = (1 << 11),
|
||||
FTDM_CHANNEL_HOLD = (1 << 12),
|
||||
FTDM_CHANNEL_INUSE = (1 << 13),
|
||||
FTDM_CHANNEL_OFFHOOK = (1 << 14),
|
||||
FTDM_CHANNEL_RINGING = (1 << 15),
|
||||
FTDM_CHANNEL_PROGRESS_DETECT = (1 << 16),
|
||||
FTDM_CHANNEL_CALLERID_DETECT = (1 << 17),
|
||||
FTDM_CHANNEL_OUTBOUND = (1 << 18),
|
||||
FTDM_CHANNEL_SUSPENDED = (1 << 19),
|
||||
FTDM_CHANNEL_3WAY = (1 << 20),
|
||||
FTDM_CHANNEL_PROGRESS = (1 << 21),
|
||||
FTDM_CHANNEL_MEDIA = (1 << 22),
|
||||
FTDM_CHANNEL_ANSWERED = (1 << 23),
|
||||
FTDM_CHANNEL_MUTE = (1 << 24),
|
||||
FTDM_CHANNEL_USE_RX_GAIN = (1 << 25),
|
||||
FTDM_CHANNEL_USE_TX_GAIN = (1 << 26),
|
||||
FTDM_CHANNEL_IN_ALARM = (1 << 27),
|
||||
FTDM_CHANNEL_SIG_UP = (1 << 28),
|
||||
FTDM_CHANNEL_USER_HANGUP = (1 << 29),
|
||||
FTDM_CHANNEL_RX_DISABLED = (1 << 30),
|
||||
FTDM_CHANNEL_TX_DISABLED = (1 << 31),
|
||||
/* ok, when we reach 32, we need to move to uint64_t all the flag stuff */
|
||||
} ftdm_channel_flag_t;
|
||||
#if defined(__cplusplus) && defined(WIN32)
|
||||
// fix C2676
|
||||
__inline__ ftdm_channel_flag_t operator|=(ftdm_channel_flag_t a, int32_t b) {
|
||||
a = (ftdm_channel_flag_t)(a | b);
|
||||
return a;
|
||||
}
|
||||
__inline__ ftdm_channel_flag_t operator&=(ftdm_channel_flag_t a, int32_t b) {
|
||||
a = (ftdm_channel_flag_t)(a & b);
|
||||
return a;
|
||||
}
|
||||
#endif
|
||||
/*!< Channel flags. This used to be an enum but we reached the 32bit limit for enums, is safer this way */
|
||||
#define FTDM_CHANNEL_CONFIGURED (1ULL << 0)
|
||||
#define FTDM_CHANNEL_READY (1ULL << 1)
|
||||
#define FTDM_CHANNEL_OPEN (1ULL << 2)
|
||||
#define FTDM_CHANNEL_DTMF_DETECT (1ULL << 3)
|
||||
#define FTDM_CHANNEL_SUPRESS_DTMF (1ULL << 4)
|
||||
#define FTDM_CHANNEL_TRANSCODE (1ULL << 5)
|
||||
#define FTDM_CHANNEL_BUFFER (1ULL << 6)
|
||||
#define FTDM_CHANNEL_EVENT (1ULL << 7)
|
||||
#define FTDM_CHANNEL_INTHREAD (1ULL << 8)
|
||||
#define FTDM_CHANNEL_WINK (1ULL << 9)
|
||||
#define FTDM_CHANNEL_FLASH (1ULL << 10)
|
||||
#define FTDM_CHANNEL_STATE_CHANGE (1ULL << 11)
|
||||
#define FTDM_CHANNEL_HOLD (1ULL << 12)
|
||||
#define FTDM_CHANNEL_INUSE (1ULL << 13)
|
||||
#define FTDM_CHANNEL_OFFHOOK (1ULL << 14)
|
||||
#define FTDM_CHANNEL_RINGING (1ULL << 15)
|
||||
#define FTDM_CHANNEL_PROGRESS_DETECT (1ULL << 16)
|
||||
#define FTDM_CHANNEL_CALLERID_DETECT (1ULL << 17)
|
||||
#define FTDM_CHANNEL_OUTBOUND (1ULL << 18)
|
||||
#define FTDM_CHANNEL_SUSPENDED (1ULL << 19)
|
||||
#define FTDM_CHANNEL_3WAY (1ULL << 20)
|
||||
#define FTDM_CHANNEL_PROGRESS (1ULL << 21)
|
||||
#define FTDM_CHANNEL_MEDIA (1ULL << 22)
|
||||
#define FTDM_CHANNEL_ANSWERED (1ULL << 23)
|
||||
#define FTDM_CHANNEL_MUTE (1ULL << 24)
|
||||
#define FTDM_CHANNEL_USE_RX_GAIN (1ULL << 25)
|
||||
#define FTDM_CHANNEL_USE_TX_GAIN (1ULL << 26)
|
||||
#define FTDM_CHANNEL_IN_ALARM (1ULL << 27)
|
||||
#define FTDM_CHANNEL_SIG_UP (1ULL << 28)
|
||||
#define FTDM_CHANNEL_USER_HANGUP (1ULL << 29)
|
||||
#define FTDM_CHANNEL_RX_DISABLED (1ULL << 30)
|
||||
#define FTDM_CHANNEL_TX_DISABLED (1ULL << 31)
|
||||
/*!< The user knows about a call in this channel */
|
||||
#define FTDM_CHANNEL_CALL_STARTED (1ULL << 32)
|
||||
|
||||
typedef enum {
|
||||
ZSM_NONE,
|
||||
|
|
|
@ -48,12 +48,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#ifdef __linux__
|
||||
#ifndef __USE_BSD
|
||||
#define __USE_BSD
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "freetdm.h"
|
||||
|
||||
|
||||
|
|
|
@ -821,7 +821,7 @@ static switch_status_t channel_receive_message_cas(switch_core_session_t *sessio
|
|||
switch (msg->message_id) {
|
||||
case SWITCH_MESSAGE_INDICATE_RINGING:
|
||||
{
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
|
||||
} else {
|
||||
zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS);
|
||||
|
@ -830,7 +830,7 @@ static switch_status_t channel_receive_message_cas(switch_core_session_t *sessio
|
|||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
{
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
|
||||
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_MEDIA);
|
||||
} else {
|
||||
|
@ -841,7 +841,7 @@ static switch_status_t channel_receive_message_cas(switch_core_session_t *sessio
|
|||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||
{
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED);
|
||||
} else {
|
||||
/* lets make the ozmod_r2 module life easier by moving thru each
|
||||
|
@ -888,7 +888,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
|
|||
switch (msg->message_id) {
|
||||
case SWITCH_MESSAGE_INDICATE_RINGING:
|
||||
{
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
|
||||
} else {
|
||||
zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS);
|
||||
|
@ -897,7 +897,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
|
|||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
{
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
|
||||
zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_MEDIA);
|
||||
} else {
|
||||
|
@ -914,7 +914,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
|
|||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||
{
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED);
|
||||
} else {
|
||||
/* Don't skip messages in the ISDN call setup
|
||||
|
@ -957,7 +957,7 @@ static switch_status_t channel_receive_message_fxo(switch_core_session_t *sessio
|
|||
switch (msg->message_id) {
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED);
|
||||
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
|
||||
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_MEDIA);
|
||||
|
@ -991,7 +991,7 @@ static switch_status_t channel_receive_message_fxs(switch_core_session_t *sessio
|
|||
switch (msg->message_id) {
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||
if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED);
|
||||
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS);
|
||||
zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_MEDIA);
|
||||
|
@ -1000,7 +1000,7 @@ static switch_status_t channel_receive_message_fxs(switch_core_session_t *sessio
|
|||
}
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_RINGING:
|
||||
if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
|
||||
if (!switch_channel_test_flag(channel, CF_ANSWERED) &&
|
||||
!switch_channel_test_flag(channel, CF_EARLY_MEDIA) &&
|
||||
|
@ -1052,7 +1052,7 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
|
|||
switch (msg->message_id) {
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||
if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
if ((var = switch_channel_get_variable(channel, "openzap_pre_buffer_size"))) {
|
||||
int tmp = atoi(var);
|
||||
if (tmp > -1) {
|
||||
|
@ -1327,7 +1327,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
tech_pvt->caller_profile = caller_profile;
|
||||
|
||||
|
||||
switch_channel_set_flag(channel, CF_OUTBOUND);
|
||||
switch_channel_set_state(channel, CS_INIT);
|
||||
if (zap_channel_add_token(zchan, switch_core_session_get_uuid(*new_session), zchan->token_count) != ZAP_SUCCESS) {
|
||||
switch_core_session_destroy(new_session);
|
||||
|
@ -1678,7 +1677,9 @@ static ZIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
|
|||
switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
|
||||
}
|
||||
|
||||
if (channel_a && channel_b && !switch_channel_test_flag(channel_a, CF_OUTBOUND) && !switch_channel_test_flag(channel_b, CF_OUTBOUND)) {
|
||||
if (channel_a && channel_b && switch_channel_direction(channel_a) == SWITCH_CALL_DIRECTION_INBOUND &&
|
||||
switch_channel_direction(channel_b) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
|
||||
cause = SWITCH_CAUSE_ATTENDED_TRANSFER;
|
||||
if (br_a_uuid && br_b_uuid) {
|
||||
switch_ivr_uuid_bridge(br_a_uuid, br_b_uuid);
|
||||
|
|
|
@ -39,8 +39,9 @@
|
|||
#include <limits.h>
|
||||
#include <time.h>
|
||||
@INSERT_MATH_HEADER@
|
||||
#if !defined(SPANDSP_NO_TIFF)
|
||||
#include <tiffio.h>
|
||||
|
||||
#endif
|
||||
#include <spandsp/telephony.h>
|
||||
#include <spandsp/fast_convert.h>
|
||||
#include <spandsp/logging.h>
|
||||
|
|
773
libs/stfu/stfu.c
773
libs/stfu/stfu.c
|
@ -27,58 +27,162 @@
|
|||
*/
|
||||
#include "stfu.h"
|
||||
|
||||
//#define DB_JB 1
|
||||
|
||||
#ifndef UINT_MAX
|
||||
# define UINT_MAX 4294967295U
|
||||
#endif
|
||||
|
||||
#ifndef UINT16_MAX
|
||||
# define UINT16_MAX 65535
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* warning C4706: assignment within conditional expression*/
|
||||
#pragma warning(disable: 4706)
|
||||
/* warning C4996: 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _strdup. See online help for details. */
|
||||
#pragma warning(disable:4996)
|
||||
#endif
|
||||
|
||||
#define least1(_z) (_z ? _z : 1)
|
||||
|
||||
static int stfu_log_level = 7;
|
||||
|
||||
struct stfu_queue {
|
||||
struct stfu_frame *array;
|
||||
struct stfu_frame int_frame;
|
||||
uint32_t real_array_size;
|
||||
uint32_t array_size;
|
||||
uint32_t array_len;
|
||||
uint32_t wr_len;
|
||||
uint32_t last_index;
|
||||
int32_t last_jitter;
|
||||
};
|
||||
typedef struct stfu_queue stfu_queue_t;
|
||||
|
||||
struct stfu_instance {
|
||||
struct stfu_queue a_queue;
|
||||
struct stfu_queue b_queue;
|
||||
struct stfu_queue c_queue;
|
||||
struct stfu_queue *in_queue;
|
||||
struct stfu_queue *out_queue;
|
||||
struct stfu_queue *old_queue;
|
||||
struct stfu_frame *last_frame;
|
||||
uint32_t cur_ts;
|
||||
uint32_t last_wr_ts;
|
||||
uint32_t last_rd_ts;
|
||||
uint32_t interval;
|
||||
uint32_t samples_per_packet;
|
||||
uint32_t samples_per_second;
|
||||
uint32_t miss_count;
|
||||
uint32_t max_plc;
|
||||
uint32_t qlen;
|
||||
uint32_t max_qlen;
|
||||
uint32_t orig_qlen;
|
||||
uint32_t packet_count;
|
||||
uint32_t consecutive_good_count;
|
||||
uint32_t consecutive_bad_count;
|
||||
uint32_t period_good_count;
|
||||
uint32_t period_bad_count;
|
||||
uint32_t period_packet_in_count;
|
||||
uint32_t period_packet_out_count;
|
||||
uint32_t period_missing_count;
|
||||
|
||||
uint32_t period_need_range;
|
||||
uint32_t period_need_range_avg;
|
||||
uint32_t period_clean_count;
|
||||
|
||||
uint32_t session_clean_count;
|
||||
uint32_t session_missing_count;
|
||||
|
||||
uint32_t session_packet_in_count;
|
||||
uint32_t session_packet_out_count;
|
||||
|
||||
uint32_t sync_out;
|
||||
uint32_t sync_in;
|
||||
|
||||
|
||||
int32_t ts_diff;
|
||||
int32_t last_ts_diff;
|
||||
int32_t same_ts;
|
||||
|
||||
uint32_t period_time;
|
||||
uint32_t decrement_time;
|
||||
|
||||
uint32_t plc_len;
|
||||
uint32_t plc_pt;
|
||||
uint32_t diff;
|
||||
uint32_t diff_total;
|
||||
uint8_t ready;
|
||||
uint8_t debug;
|
||||
|
||||
char *name;
|
||||
stfu_n_call_me_t callback;
|
||||
void *udata;
|
||||
};
|
||||
|
||||
static void stfu_n_reset_counters(stfu_instance_t *i);
|
||||
static void null_logger(const char *file, const char *func, int line, int level, const char *fmt, ...);
|
||||
static void default_logger(const char *file, const char *func, int line, int level, const char *fmt, ...);
|
||||
|
||||
stfu_logger_t stfu_log = null_logger;
|
||||
|
||||
void stfu_global_set_logger(stfu_logger_t logger)
|
||||
{
|
||||
if (logger) {
|
||||
stfu_log = logger;
|
||||
} else {
|
||||
stfu_log = null_logger;
|
||||
}
|
||||
}
|
||||
|
||||
void stfu_global_set_default_logger(int level)
|
||||
{
|
||||
if (level < 0 || level > 7) {
|
||||
level = 7;
|
||||
}
|
||||
|
||||
stfu_log = default_logger;
|
||||
stfu_log_level = level;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static stfu_status_t stfu_n_resize_aqueue(stfu_queue_t *queue, uint32_t qlen)
|
||||
{
|
||||
unsigned char *m;
|
||||
|
||||
if (qlen <= queue->array_size) {
|
||||
return STFU_IT_FAILED;;
|
||||
if (qlen <= queue->real_array_size) {
|
||||
queue->array_size = qlen;
|
||||
if (queue->array_len > qlen) {
|
||||
queue->array_len = qlen;
|
||||
}
|
||||
} else {
|
||||
m = realloc(queue->array, qlen * sizeof(struct stfu_frame));
|
||||
assert(m);
|
||||
memset(m + queue->array_size * sizeof(struct stfu_frame), 0, (qlen * sizeof(struct stfu_frame)) - (queue->array_size * sizeof(struct stfu_frame)));
|
||||
queue->array = (struct stfu_frame *) m;
|
||||
queue->real_array_size = queue->array_size = qlen;
|
||||
}
|
||||
|
||||
m = realloc(queue->array, qlen * sizeof(struct stfu_frame));
|
||||
assert(m);
|
||||
memset(m + queue->array_size, 0, qlen * sizeof(struct stfu_frame) - queue->array_size);
|
||||
queue->array = (struct stfu_frame *) m;
|
||||
queue->array_size = qlen;
|
||||
return STFU_IT_WORKED;
|
||||
}
|
||||
|
||||
static void stfu_n_init_aqueue(stfu_queue_t *queue, uint32_t qlen)
|
||||
{
|
||||
|
||||
queue->array = calloc(qlen, sizeof(struct stfu_frame));
|
||||
assert(queue->array != NULL);
|
||||
memset(queue->array, 0, sizeof(struct stfu_frame) * qlen);
|
||||
queue->array_size = qlen;
|
||||
queue->real_array_size = queue->array_size = qlen;
|
||||
queue->int_frame.plc = 1;
|
||||
memset(queue->int_frame.data, 255, sizeof(queue->int_frame.data));
|
||||
}
|
||||
|
||||
|
||||
void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata)
|
||||
{
|
||||
i->callback = callback;
|
||||
i->udata = udata;
|
||||
}
|
||||
|
||||
void stfu_n_destroy(stfu_instance_t **i)
|
||||
|
@ -88,33 +192,66 @@ void stfu_n_destroy(stfu_instance_t **i)
|
|||
if (i && *i) {
|
||||
ii = *i;
|
||||
*i = NULL;
|
||||
if (ii->name) free(ii->name);
|
||||
free(ii->a_queue.array);
|
||||
free(ii->b_queue.array);
|
||||
free(ii->c_queue.array);
|
||||
free(ii);
|
||||
}
|
||||
}
|
||||
|
||||
void stfu_n_debug(stfu_instance_t *i, const char *name)
|
||||
{
|
||||
if (i->name) free(i->name);
|
||||
|
||||
if (name) {
|
||||
i->name = strdup(name);
|
||||
i->debug = 1;
|
||||
} else {
|
||||
i->name = strdup("none");
|
||||
i->debug = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void stfu_n_report(stfu_instance_t *i, stfu_report_t *r)
|
||||
{
|
||||
assert(i);
|
||||
r->in_len = i->in_queue->array_len;
|
||||
r->in_size = i->in_queue->array_size;
|
||||
r->out_len = i->out_queue->array_len;
|
||||
r->out_size = i->out_queue->array_size;
|
||||
r->qlen = i->qlen;
|
||||
r->packet_in_count = i->period_packet_in_count;
|
||||
r->clean_count = i->period_clean_count;
|
||||
r->consecutive_good_count = i->consecutive_good_count;
|
||||
r->consecutive_bad_count = i->consecutive_bad_count;
|
||||
}
|
||||
|
||||
stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen)
|
||||
{
|
||||
stfu_status_t s;
|
||||
|
||||
if (i->qlen == i->max_qlen) {
|
||||
return STFU_IT_FAILED;
|
||||
}
|
||||
|
||||
if (i->max_qlen && qlen > i->max_qlen) {
|
||||
if (i->qlen < i->max_qlen) {
|
||||
qlen = i->max_qlen;
|
||||
} else {
|
||||
return STFU_IT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if ((s = stfu_n_resize_aqueue(&i->a_queue, qlen)) == STFU_IT_WORKED) {
|
||||
s = stfu_n_resize_aqueue(&i->b_queue, qlen);
|
||||
s = stfu_n_resize_aqueue(&i->c_queue, qlen);
|
||||
|
||||
i->qlen = qlen;
|
||||
i->max_plc = 5;
|
||||
i->last_frame = NULL;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_plc)
|
||||
stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_per_packet, uint32_t samples_per_second)
|
||||
{
|
||||
struct stfu_instance *i;
|
||||
|
||||
|
@ -123,116 +260,259 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_plc)
|
|||
return NULL;
|
||||
}
|
||||
memset(i, 0, sizeof(*i));
|
||||
|
||||
i->qlen = qlen;
|
||||
i->max_qlen = max_qlen;
|
||||
i->orig_qlen = qlen;
|
||||
i->samples_per_packet = samples_per_packet;
|
||||
|
||||
stfu_n_init_aqueue(&i->a_queue, qlen);
|
||||
stfu_n_init_aqueue(&i->b_queue, qlen);
|
||||
stfu_n_init_aqueue(&i->c_queue, qlen);
|
||||
|
||||
i->in_queue = &i->a_queue;
|
||||
i->out_queue = &i->b_queue;
|
||||
i->old_queue = &i->c_queue;
|
||||
i->name = strdup("none");
|
||||
|
||||
i->max_plc = i->qlen / 2;
|
||||
|
||||
if (max_plc) {
|
||||
i->max_plc = max_plc;
|
||||
} else {
|
||||
i->max_plc = qlen / 2;
|
||||
}
|
||||
i->samples_per_second = samples_per_second ? samples_per_second : 8000;
|
||||
|
||||
i->period_time = ((i->samples_per_second * 20) / i->samples_per_packet);
|
||||
i->decrement_time = ((i->samples_per_second * 15) / i->samples_per_packet);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void stfu_n_reset_counters(stfu_instance_t *i)
|
||||
{
|
||||
if (stfu_log != null_logger && i->debug) {
|
||||
stfu_log(STFU_LOG_EMERG, "%s COUNTER RESET........\n", i->name);
|
||||
}
|
||||
|
||||
if (i->callback) {
|
||||
i->callback(i, i->udata);
|
||||
}
|
||||
|
||||
i->consecutive_good_count = 0;
|
||||
i->consecutive_bad_count = 0;
|
||||
i->period_good_count = 0;
|
||||
i->period_clean_count = 0;
|
||||
i->period_bad_count = 0;
|
||||
i->period_packet_in_count = 0;
|
||||
i->period_packet_out_count = 0;
|
||||
i->period_missing_count = 0;
|
||||
|
||||
i->period_need_range = 0;
|
||||
i->period_need_range_avg = 0;
|
||||
|
||||
i->diff = 0;
|
||||
i->diff_total = 0;
|
||||
|
||||
}
|
||||
|
||||
void stfu_n_reset(stfu_instance_t *i)
|
||||
{
|
||||
if (stfu_log != null_logger && i->debug) {
|
||||
stfu_log(STFU_LOG_EMERG, "%s RESET\n", i->name);
|
||||
}
|
||||
|
||||
i->ready = 0;
|
||||
i->in_queue = &i->a_queue;
|
||||
i->out_queue = &i->b_queue;
|
||||
i->old_queue = &i->c_queue;
|
||||
|
||||
i->in_queue->array_len = 0;
|
||||
i->out_queue->array_len = 0;
|
||||
i->out_queue->wr_len = 0;
|
||||
i->last_frame = NULL;
|
||||
i->miss_count = 0;
|
||||
i->in_queue->last_jitter = 0;
|
||||
i->out_queue->last_jitter = 0;
|
||||
|
||||
|
||||
stfu_n_reset_counters(i);
|
||||
stfu_n_sync(i, 1);
|
||||
|
||||
i->cur_ts = 0;
|
||||
i->last_wr_ts = 0;
|
||||
i->miss_count = 0;
|
||||
i->interval = 0;
|
||||
i->last_rd_ts = 0;
|
||||
i->miss_count = 0;
|
||||
i->packet_count = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int32_t stfu_n_measure_interval(stfu_queue_t *queue)
|
||||
stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets)
|
||||
{
|
||||
uint32_t index;
|
||||
int32_t d, most = 0, last = 0, this, track[STFU_MAX_TRACK] = {0};
|
||||
|
||||
for(index = 0; index < queue->array_len; index++) {
|
||||
this = queue->array[index].ts;
|
||||
if (last) {
|
||||
if (packets > i->qlen) {
|
||||
stfu_n_reset(i);
|
||||
} else {
|
||||
i->sync_out = packets;
|
||||
i->sync_in = packets;
|
||||
}
|
||||
|
||||
if ((d = this - last) > 0 && d / 10 < STFU_MAX_TRACK) {
|
||||
track[(d/10)]++;
|
||||
}
|
||||
}
|
||||
|
||||
last = this;
|
||||
}
|
||||
|
||||
for(index = 0; index < STFU_MAX_TRACK; index++) {
|
||||
if (track[index] > track[most]) {
|
||||
most = index;
|
||||
}
|
||||
}
|
||||
|
||||
return most * 10;
|
||||
return STFU_IT_WORKED;
|
||||
}
|
||||
|
||||
static int16_t stfu_n_process(stfu_instance_t *i, stfu_queue_t *queue)
|
||||
{
|
||||
if (!i->interval && !(i->interval = stfu_n_measure_interval(queue))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
static void stfu_n_swap(stfu_instance_t *i)
|
||||
{
|
||||
stfu_queue_t *last_in = i->in_queue, *last_out = i->out_queue, *last_old = i->old_queue;
|
||||
|
||||
i->ready = 1;
|
||||
|
||||
i->in_queue = last_out;
|
||||
i->out_queue = last_old;
|
||||
i->old_queue = last_in;
|
||||
|
||||
i->in_queue->array_len = 0;
|
||||
i->out_queue->wr_len = 0;
|
||||
i->last_frame = NULL;
|
||||
i->miss_count = 0;
|
||||
i->in_queue->last_index = 0;
|
||||
i->out_queue->last_index = 0;
|
||||
i->out_queue->last_jitter = 0;
|
||||
}
|
||||
|
||||
stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, int last)
|
||||
{
|
||||
uint32_t index;
|
||||
uint32_t index = 0;
|
||||
stfu_frame_t *frame;
|
||||
size_t cplen = 0;
|
||||
int good_ts = 0;
|
||||
|
||||
if (!i->samples_per_packet && ts && i->last_rd_ts) {
|
||||
i->ts_diff = ts - i->last_rd_ts;
|
||||
|
||||
if (i->last_ts_diff == i->ts_diff) {
|
||||
if (++i->same_ts == 5) {
|
||||
i->samples_per_packet = i->ts_diff;
|
||||
}
|
||||
} else {
|
||||
i->same_ts = 0;
|
||||
}
|
||||
|
||||
i->last_ts_diff = i->ts_diff;
|
||||
|
||||
if (!i->samples_per_packet) {
|
||||
i->last_rd_ts = ts;
|
||||
return STFU_IT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (i->sync_in) {
|
||||
good_ts = 1;
|
||||
i->sync_in = 0;
|
||||
} else {
|
||||
|
||||
if ((ts && ts == i->last_rd_ts + i->samples_per_packet) || (i->last_rd_ts > 4294900000 && ts < 5000)) {
|
||||
good_ts = 1;
|
||||
}
|
||||
|
||||
if (i->last_wr_ts) {
|
||||
if ((ts <= i->last_wr_ts && (i->last_wr_ts != UINT_MAX || ts == i->last_wr_ts))) {
|
||||
if (stfu_log != null_logger && i->debug) {
|
||||
stfu_log(STFU_LOG_EMERG, "%s TOO LATE !!! %u \n\n\n", i->name, ts);
|
||||
}
|
||||
if (i->in_queue->array_len < i->in_queue->array_size) {
|
||||
i->in_queue->array_len++;
|
||||
}
|
||||
return STFU_ITS_TOO_LATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (good_ts) {
|
||||
i->period_clean_count++;
|
||||
i->session_clean_count++;
|
||||
}
|
||||
|
||||
i->period_packet_in_count++;
|
||||
i->session_packet_in_count++;
|
||||
|
||||
i->period_need_range_avg = i->period_need_range / least1(i->period_missing_count);
|
||||
|
||||
if (i->period_missing_count > i->qlen * 2) {
|
||||
if (stfu_log != null_logger && i->debug) {
|
||||
stfu_log(STFU_LOG_EMERG, "%s resize %u %u\n", i->name, i->qlen, i->qlen + 1);
|
||||
}
|
||||
stfu_n_resize(i, i->qlen + 1);
|
||||
stfu_n_reset_counters(i);
|
||||
} else {
|
||||
if (i->qlen > i->orig_qlen && (i->consecutive_good_count > i->decrement_time || i->period_clean_count > i->decrement_time)) {
|
||||
stfu_n_resize(i, i->qlen - 1);
|
||||
stfu_n_reset_counters(i);
|
||||
stfu_n_sync(i, i->qlen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
i->diff = 0;
|
||||
|
||||
if (i->last_wr_ts) {
|
||||
if (ts < 1000 && i->last_wr_ts > (UINT_MAX - 1000)) {
|
||||
i->diff = abs(((UINT_MAX - i->last_wr_ts) + ts) / i->samples_per_packet);
|
||||
} else if (ts) {
|
||||
i->diff = abs(i->last_wr_ts - ts) / i->samples_per_packet;
|
||||
}
|
||||
}
|
||||
|
||||
i->diff_total += i->diff;
|
||||
|
||||
if ((i->period_packet_in_count > i->period_time)) {
|
||||
uint32_t avg;
|
||||
|
||||
avg = i->diff_total / least1(i->period_packet_in_count);
|
||||
|
||||
i->period_packet_in_count = 0;
|
||||
|
||||
if (i->period_missing_count == 0 && i->qlen > i->orig_qlen) {
|
||||
stfu_n_resize(i, i->qlen - 1);
|
||||
stfu_n_sync(i, i->qlen);
|
||||
}
|
||||
|
||||
stfu_n_reset_counters(i);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (stfu_log != null_logger && i->debug) {
|
||||
stfu_log(STFU_LOG_EMERG, "%s %u i=%u/%u - g:%u/%u c:%u/%u b:%u - %u:%u - %u %d %u %u %d %d\n", i->name,
|
||||
i->qlen, i->period_packet_in_count, i->period_time, i->consecutive_good_count,
|
||||
i->decrement_time, i->period_clean_count, i->decrement_time, i->consecutive_bad_count,
|
||||
ts, ts / i->samples_per_packet,
|
||||
i->period_missing_count, i->period_need_range_avg,
|
||||
i->last_wr_ts, ts, i->diff, i->diff_total / least1(i->period_packet_in_count));
|
||||
}
|
||||
|
||||
if (last || i->in_queue->array_len == i->in_queue->array_size) {
|
||||
stfu_queue_t *other_queue;
|
||||
|
||||
if (i->out_queue->wr_len < i->out_queue->array_len) {
|
||||
return STFU_IT_FAILED;
|
||||
}
|
||||
|
||||
other_queue = i->in_queue;
|
||||
i->in_queue = i->out_queue;
|
||||
i->out_queue = other_queue;
|
||||
|
||||
i->in_queue->array_len = 0;
|
||||
i->out_queue->wr_len = 0;
|
||||
i->last_frame = NULL;
|
||||
i->miss_count = 0;
|
||||
|
||||
if (stfu_n_process(i, i->out_queue) < 0) {
|
||||
if (i->in_queue->array_len == i->in_queue->array_size && i->out_queue->array_len == i->out_queue->array_size) {
|
||||
stfu_n_resize(i, i->out_queue->array_size * 2);
|
||||
}
|
||||
//return STFU_IT_FAILED;
|
||||
}
|
||||
for(index = 0; index < i->out_queue->array_len; index++) {
|
||||
i->out_queue->array[index].was_read = 0;
|
||||
}
|
||||
}
|
||||
stfu_n_swap(i);
|
||||
}
|
||||
|
||||
if (last) {
|
||||
return STFU_IM_DONE;
|
||||
}
|
||||
|
||||
index = i->in_queue->array_len++;
|
||||
index = i->in_queue->array_len++;
|
||||
assert(index < i->in_queue->array_size);
|
||||
frame = &i->in_queue->array[index];
|
||||
|
||||
if (i->in_queue->array_len == i->in_queue->array_size) {
|
||||
stfu_n_swap(i);
|
||||
}
|
||||
|
||||
if ((cplen = datalen) > sizeof(frame->data)) {
|
||||
cplen = sizeof(frame->data);
|
||||
}
|
||||
|
||||
i->last_rd_ts = ts;
|
||||
i->packet_count++;
|
||||
|
||||
memcpy(frame->data, data, cplen);
|
||||
|
||||
frame->pt = pt;
|
||||
frame->ts = ts;
|
||||
frame->dlen = cplen;
|
||||
|
@ -241,23 +521,51 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void
|
|||
return STFU_IT_WORKED;
|
||||
}
|
||||
|
||||
static int stfu_n_find_frame(stfu_queue_t *queue, uint32_t ts, stfu_frame_t **r_frame, uint32_t *index)
|
||||
static int stfu_n_find_any_frame(stfu_instance_t *in, stfu_queue_t *queue, stfu_frame_t **r_frame)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
stfu_frame_t *frame = NULL;
|
||||
|
||||
assert(r_frame);
|
||||
assert(index);
|
||||
|
||||
*r_frame = NULL;
|
||||
|
||||
for(i = 0; i < queue->array_len; i++) {
|
||||
for(i = 0; i < queue->real_array_size; i++) {
|
||||
frame = &queue->array[i];
|
||||
if (!frame->was_read) {
|
||||
*r_frame = frame;
|
||||
queue->last_index = i;
|
||||
frame->was_read = 1;
|
||||
in->period_packet_out_count++;
|
||||
in->session_packet_out_count++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t ts, stfu_frame_t **r_frame)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
stfu_frame_t *frame = NULL;
|
||||
|
||||
if (r_frame) {
|
||||
*r_frame = NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < queue->array_size; i++) {
|
||||
frame = &queue->array[i];
|
||||
|
||||
if (frame->ts == ts) {
|
||||
*r_frame = frame;
|
||||
*index = i;
|
||||
frame->was_read = 1;
|
||||
if (r_frame) {
|
||||
*r_frame = frame;
|
||||
queue->last_index = i;
|
||||
frame->was_read = 1;
|
||||
in->period_packet_out_count++;
|
||||
in->session_packet_out_count++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -267,47 +575,300 @@ static int stfu_n_find_frame(stfu_queue_t *queue, uint32_t ts, stfu_frame_t **r_
|
|||
|
||||
stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
|
||||
{
|
||||
uint32_t index;
|
||||
stfu_frame_t *rframe = NULL;
|
||||
|
||||
if (((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) {
|
||||
return NULL;
|
||||
}
|
||||
int found = 0;
|
||||
|
||||
if (i->cur_ts == 0) {
|
||||
i->cur_ts = i->out_queue->array[0].ts;
|
||||
} else {
|
||||
i->cur_ts += i->interval;
|
||||
if (!i->samples_per_packet) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!i->ready) {
|
||||
if (stfu_log != null_logger && i->debug) {
|
||||
stfu_log(STFU_LOG_EMERG, "%s XXXSKIP\n", i->name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (stfu_n_find_frame(i->out_queue, i->cur_ts, &rframe, &index) || stfu_n_find_frame(i->in_queue, i->cur_ts, &rframe, &index)) {
|
||||
|
||||
if (i->cur_ts == 0 && i->last_wr_ts < 1000) {
|
||||
uint32_t x = 0;
|
||||
for (x = 0; x < i->out_queue->array_len; x++) {
|
||||
if (!i->out_queue->array[x].was_read) {
|
||||
i->cur_ts = i->out_queue->array[x].ts;
|
||||
break;
|
||||
}
|
||||
if (i->cur_ts == 0) {
|
||||
if (stfu_log != null_logger && i->debug) {
|
||||
stfu_log(STFU_LOG_EMERG, "%s XXXPUNT\n", i->name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
i->cur_ts = i->cur_ts + i->samples_per_packet;
|
||||
}
|
||||
|
||||
found = stfu_n_find_frame(i, i->out_queue, i->cur_ts, &rframe);
|
||||
|
||||
if (found) {
|
||||
if (i->out_queue->array_len) {
|
||||
i->out_queue->array_len--;
|
||||
}
|
||||
} else {
|
||||
found = stfu_n_find_frame(i, i->in_queue, i->cur_ts, &rframe);
|
||||
|
||||
if (!found) {
|
||||
found = stfu_n_find_frame(i, i->old_queue, i->cur_ts, &rframe);
|
||||
}
|
||||
}
|
||||
|
||||
if (i->sync_out) {
|
||||
if (!found) {
|
||||
if ((found = stfu_n_find_any_frame(i, i->out_queue, &rframe))) {
|
||||
i->cur_ts = rframe->ts;
|
||||
}
|
||||
|
||||
if (stfu_log != null_logger && i->debug) {
|
||||
stfu_log(STFU_LOG_EMERG, "%s SYNC %u %u:%u\n", i->name, i->sync_out, i->cur_ts, i->cur_ts / i->samples_per_packet);
|
||||
}
|
||||
|
||||
}
|
||||
i->sync_out = 0;
|
||||
}
|
||||
|
||||
if (!i->cur_ts) {
|
||||
if (stfu_log != null_logger && i->debug) {
|
||||
stfu_log(STFU_LOG_EMERG, "%s NO TS\n", i->name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (!found && i->samples_per_packet) {
|
||||
uint32_t y;
|
||||
stfu_frame_t *frame = NULL;
|
||||
|
||||
int32_t delay = i->last_rd_ts - i->cur_ts;
|
||||
uint32_t need = abs(i->last_rd_ts - i->cur_ts) / i->samples_per_packet;
|
||||
|
||||
|
||||
i->period_missing_count++;
|
||||
i->session_missing_count++;
|
||||
i->period_need_range += need;
|
||||
|
||||
if (stfu_log != null_logger && i->debug) {
|
||||
stfu_log(STFU_LOG_EMERG, "%s MISSING %u:%u %u %u %d %u %d\n", i->name,
|
||||
i->cur_ts, i->cur_ts / i->samples_per_packet, i->packet_count, i->last_rd_ts, delay, i->qlen, need);
|
||||
}
|
||||
|
||||
if (i->packet_count > i->orig_qlen * 100 && delay > 0 && need > i->qlen && need < (i->qlen + 5)) {
|
||||
i->packet_count = 0;
|
||||
}
|
||||
|
||||
if (stfu_log != null_logger && i->debug) {
|
||||
stfu_log(STFU_LOG_EMERG, "%s ", i->name);
|
||||
for(y = 0; y < i->out_queue->array_size; y++) {
|
||||
if ((y % 5) == 0) stfu_log(STFU_LOG_EMERG, "\n%s ", i->name);
|
||||
frame = &i->out_queue->array[y];
|
||||
stfu_log(STFU_LOG_EMERG, "%u:%u\t", frame->ts, frame->ts / i->samples_per_packet);
|
||||
}
|
||||
stfu_log(STFU_LOG_EMERG, "\n%s ", i->name);
|
||||
|
||||
|
||||
for(y = 0; y < i->in_queue->array_size; y++) {
|
||||
if ((y % 5) == 0) stfu_log(STFU_LOG_EMERG, "\n%s ", i->name);
|
||||
frame = &i->in_queue->array[y];
|
||||
stfu_log(STFU_LOG_EMERG, "%u:%u\t", frame->ts, frame->ts / i->samples_per_packet);
|
||||
}
|
||||
stfu_log(STFU_LOG_EMERG, "\n%s\n\n\n", i->name);
|
||||
|
||||
}
|
||||
|
||||
if (delay < 0) {
|
||||
stfu_n_reset(i);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (stfu_log != null_logger && i->debug) {
|
||||
if (found) {
|
||||
stfu_log(STFU_LOG_EMERG, "%s O: %u:%u %u\n", i->name, rframe->ts, rframe->ts / i->samples_per_packet, rframe->plc);
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
i->consecutive_good_count++;
|
||||
i->period_good_count++;
|
||||
i->consecutive_bad_count = 0;
|
||||
} else {
|
||||
i->consecutive_bad_count++;
|
||||
i->period_bad_count++;
|
||||
i->consecutive_good_count = 0;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
i->last_frame = rframe;
|
||||
i->out_queue->wr_len++;
|
||||
i->last_wr_ts = rframe->ts;
|
||||
i->miss_count = 0;
|
||||
i->out_queue->wr_len++;
|
||||
i->last_wr_ts = rframe->ts;
|
||||
|
||||
i->miss_count = 0;
|
||||
if (rframe->dlen) {
|
||||
i->plc_len = rframe->dlen;
|
||||
}
|
||||
|
||||
i->plc_pt = rframe->pt;
|
||||
|
||||
} else {
|
||||
i->last_wr_ts = i->cur_ts;
|
||||
rframe = &i->out_queue->int_frame;
|
||||
|
||||
if (i->last_frame && i->last_frame != rframe) {
|
||||
rframe->dlen = i->last_frame->dlen;
|
||||
/* poor man's plc.. Copy the last frame, but we flag it so you can use a better one if you wish */
|
||||
memcpy(rframe->data, i->last_frame->data, rframe->dlen);
|
||||
rframe->dlen = i->plc_len;
|
||||
rframe->pt = i->plc_pt;
|
||||
rframe->ts = i->cur_ts;
|
||||
i->miss_count++;
|
||||
|
||||
if (stfu_log != null_logger && i->debug) {
|
||||
stfu_log(STFU_LOG_EMERG, "%s PLC %d %d %ld %u:%u\n", i->name,
|
||||
i->miss_count, rframe->plc, rframe->dlen, rframe->ts, rframe->ts / i->samples_per_packet);
|
||||
}
|
||||
|
||||
rframe->ts = i->cur_ts;
|
||||
|
||||
if (++i->miss_count > i->max_plc) {
|
||||
i->out_queue->wr_len = i->out_queue->array_size;
|
||||
i->cur_ts = 0;
|
||||
if (i->miss_count > i->max_plc) {
|
||||
stfu_n_reset(i);
|
||||
rframe = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return rframe;
|
||||
return rframe;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
#ifndef vsnprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
int vasprintf(char **ret, const char *format, va_list ap);
|
||||
|
||||
int stfu_vasprintf(char **ret, const char *fmt, va_list ap)
|
||||
{
|
||||
#if !defined(WIN32) && !defined(__sun)
|
||||
return vasprintf(ret, fmt, ap);
|
||||
#else
|
||||
char *buf;
|
||||
int len;
|
||||
size_t buflen;
|
||||
va_list ap2;
|
||||
char *tmp = NULL;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1500
|
||||
/* hack for incorrect assumption in msvc header files for code analysis */
|
||||
__analysis_assume(tmp);
|
||||
#endif
|
||||
ap2 = ap;
|
||||
#else
|
||||
va_copy(ap2, ap);
|
||||
#endif
|
||||
|
||||
len = vsnprintf(tmp, 0, fmt, ap2);
|
||||
|
||||
if (len > 0 && (buf = malloc((buflen = (size_t) (len + 1)))) != NULL) {
|
||||
len = vsnprintf(buf, buflen, fmt, ap);
|
||||
*ret = buf;
|
||||
} else {
|
||||
*ret = NULL;
|
||||
len = -1;
|
||||
}
|
||||
|
||||
va_end(ap2);
|
||||
return len;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int stfu_snprintf(char *buffer, size_t count, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = vsnprintf(buffer, count-1, fmt, ap);
|
||||
if (ret < 0)
|
||||
buffer[count-1] = '\0';
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void null_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
|
||||
{
|
||||
if (file && func && line && level && fmt) {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char *LEVEL_NAMES[] = {
|
||||
"EMERG",
|
||||
"ALERT",
|
||||
"CRIT",
|
||||
"ERROR",
|
||||
"WARNING",
|
||||
"NOTICE",
|
||||
"INFO",
|
||||
"DEBUG",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *cut_path(const char *in)
|
||||
{
|
||||
const char *p, *ret = in;
|
||||
char delims[] = "/\\";
|
||||
char *i;
|
||||
|
||||
for (i = delims; *i; i++) {
|
||||
p = in;
|
||||
while ((p = strchr(p, *i)) != 0) {
|
||||
ret = ++p;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void default_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
|
||||
{
|
||||
const char *fp;
|
||||
char *data;
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
if (level < 0 || level > 7) {
|
||||
level = 7;
|
||||
}
|
||||
if (level > stfu_log_level) {
|
||||
return;
|
||||
}
|
||||
|
||||
fp = cut_path(file);
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
ret = stfu_vasprintf(&data, fmt, ap);
|
||||
|
||||
if (ret != -1) {
|
||||
fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], file, line, func, data);
|
||||
free(data);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
|
|
100
libs/stfu/stfu.h
100
libs/stfu/stfu.h
|
@ -38,6 +38,8 @@ extern "C" {
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef uint32_t
|
||||
|
@ -62,6 +64,85 @@ typedef unsigned long in_addr_t;
|
|||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
typedef SOCKET stfu_socket_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int8 int8_t;
|
||||
typedef intptr_t stfu_ssize_t;
|
||||
typedef int stfu_filehandle_t;
|
||||
#define STFU_SOCK_INVALID INVALID_SOCKET
|
||||
#define strerror_r(num, buf, size) strerror_s(buf, size, num)
|
||||
#if defined(STFU_DECLARE_STATIC)
|
||||
#define STFU_DECLARE(type) type __stdcall
|
||||
#define STFU_DECLARE_NONSTD(type) type __cdecl
|
||||
#define STFU_DECLARE_DATA
|
||||
#elif defined(STFU_EXPORTS)
|
||||
#define STFU_DECLARE(type) __declspec(dllexport) type __stdcall
|
||||
#define STFU_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl
|
||||
#define STFU_DECLARE_DATA __declspec(dllexport)
|
||||
#else
|
||||
#define STFU_DECLARE(type) __declspec(dllimport) type __stdcall
|
||||
#define STFU_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl
|
||||
#define STFU_DECLARE_DATA __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define STFU_DECLARE(type) type
|
||||
#define STFU_DECLARE_NONSTD(type) type
|
||||
#define STFU_DECLARE_DATA
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#define STFU_SOCK_INVALID -1
|
||||
typedef int stfu_socket_t;
|
||||
typedef ssize_t stfu_ssize_t;
|
||||
typedef int stfu_filehandle_t;
|
||||
#endif
|
||||
|
||||
|
||||
#define STFU_PRE __FILE__, __FUNCTION__, __LINE__
|
||||
#define STFU_LOG_LEVEL_DEBUG 7
|
||||
#define STFU_LOG_LEVEL_INFO 6
|
||||
#define STFU_LOG_LEVEL_NOTICE 5
|
||||
#define STFU_LOG_LEVEL_WARNING 4
|
||||
#define STFU_LOG_LEVEL_ERROR 3
|
||||
#define STFU_LOG_LEVEL_CRIT 2
|
||||
#define STFU_LOG_LEVEL_ALERT 1
|
||||
#define STFU_LOG_LEVEL_EMERG 0
|
||||
|
||||
#define STFU_LOG_DEBUG STFU_PRE, STFU_LOG_LEVEL_DEBUG
|
||||
#define STFU_LOG_INFO STFU_PRE, STFU_LOG_LEVEL_INFO
|
||||
#define STFU_LOG_NOTICE STFU_PRE, STFU_LOG_LEVEL_NOTICE
|
||||
#define STFU_LOG_WARNING STFU_PRE, STFU_LOG_LEVEL_WARNING
|
||||
#define STFU_LOG_ERROR STFU_PRE, STFU_LOG_LEVEL_ERROR
|
||||
#define STFU_LOG_CRIT STFU_PRE, STFU_LOG_LEVEL_CRIT
|
||||
#define STFU_LOG_ALERT STFU_PRE, STFU_LOG_LEVEL_ALERT
|
||||
#define STFU_LOG_EMERG STFU_PRE, STFU_LOG_LEVEL_EMERG
|
||||
typedef void (*stfu_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...);
|
||||
|
||||
|
||||
int stfu_vasprintf(char **ret, const char *fmt, va_list ap);
|
||||
|
||||
extern stfu_logger_t stfu_log;
|
||||
|
||||
/*! Sets the logger for libstfu. Default is the null_logger */
|
||||
void stfu_global_set_logger(stfu_logger_t logger);
|
||||
/*! Sets the default log level for libstfu */
|
||||
void stfu_global_set_default_logger(int level);
|
||||
|
||||
#define STFU_DATALEN 16384
|
||||
#define STFU_QLEN 300
|
||||
#define STFU_MAX_TRACK 256
|
||||
|
@ -69,7 +150,8 @@ typedef unsigned long in_addr_t;
|
|||
typedef enum {
|
||||
STFU_IT_FAILED,
|
||||
STFU_IT_WORKED,
|
||||
STFU_IM_DONE
|
||||
STFU_IM_DONE,
|
||||
STFU_ITS_TOO_LATE
|
||||
} stfu_status_t;
|
||||
|
||||
struct stfu_frame {
|
||||
|
@ -86,21 +168,25 @@ struct stfu_instance;
|
|||
typedef struct stfu_instance stfu_instance_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t in_len;
|
||||
uint32_t in_size;
|
||||
uint32_t out_len;
|
||||
uint32_t out_size;
|
||||
|
||||
uint32_t qlen;
|
||||
uint32_t packet_in_count;
|
||||
uint32_t clean_count;
|
||||
uint32_t consecutive_good_count;
|
||||
uint32_t consecutive_bad_count;
|
||||
} stfu_report_t;
|
||||
|
||||
typedef void (*stfu_n_call_me_t)(stfu_instance_t *i, void *);
|
||||
|
||||
void stfu_n_report(stfu_instance_t *i, stfu_report_t *r);
|
||||
void stfu_n_destroy(stfu_instance_t **i);
|
||||
stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_plc);
|
||||
stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_per_packet, uint32_t samples_per_second);
|
||||
stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen);
|
||||
stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, int last);
|
||||
stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i);
|
||||
void stfu_n_reset(stfu_instance_t *i);
|
||||
stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets);
|
||||
void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata);
|
||||
void stfu_n_debug(stfu_instance_t *i, const char *name);
|
||||
|
||||
#define stfu_im_done(i) stfu_n_add_data(i, 0, NULL, 0, 1)
|
||||
#define stfu_n_eat(i,t,p,d,l) stfu_n_add_data(i, t, p, d, l, 0)
|
||||
|
|
|
@ -31,7 +31,8 @@
|
|||
* this file does not exist!!!!
|
||||
*
|
||||
*/
|
||||
|
||||
#define SPANDSP_NO_TIFF 1
|
||||
#include "spandsp.h"
|
||||
#include "switch_profile.h"
|
||||
|
||||
#ifndef WIN32
|
||||
|
@ -169,6 +170,7 @@ struct switch_core_session {
|
|||
switch_log_level_t loglevel;
|
||||
uint32_t soft_lock;
|
||||
switch_ivr_dmachine_t *dmachine;
|
||||
plc_state_t *plc;
|
||||
};
|
||||
|
||||
struct switch_media_bug {
|
||||
|
|
|
@ -1110,6 +1110,8 @@ SWITCH_DECLARE(int) switch_sockaddr_equal(const switch_sockaddr_t *sa1, const sw
|
|||
SWITCH_DECLARE(switch_status_t) switch_sockaddr_info_get(switch_sockaddr_t ** sa, const char *hostname,
|
||||
int32_t family, switch_port_t port, int32_t flags, switch_memory_pool_t *pool);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_sockaddr_create(switch_sockaddr_t **sa, switch_memory_pool_t *pool);
|
||||
|
||||
/**
|
||||
* Send data over a network.
|
||||
* @param sock The socket to send the data over.
|
||||
|
|
|
@ -312,6 +312,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_caller_extension_masquerade(switc
|
|||
*/
|
||||
SWITCH_DECLARE(void) switch_channel_set_caller_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension);
|
||||
|
||||
SWITCH_DECLARE(void) switch_channel_sort_cid(switch_channel_t *channel, switch_bool_t in);
|
||||
|
||||
/*!
|
||||
\brief Retrieve caller extension from a given channel
|
||||
\param channel channel to retrieve extension from
|
||||
|
|
|
@ -229,7 +229,14 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_sessi
|
|||
\param queue_frames the number of frames to delay
|
||||
\return SWITCH_STATUS_SUCCESS
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, uint32_t queue_frames);
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session,
|
||||
uint32_t queue_frames,
|
||||
uint32_t max_queue_frames,
|
||||
uint32_t samples_per_packet, uint32_t samples_per_second);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp_session, const char *name);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session);
|
||||
|
||||
/*!
|
||||
\brief Set an RTP Flag
|
||||
|
|
|
@ -790,6 +790,7 @@ typedef enum {
|
|||
SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION,
|
||||
SWITCH_MESSAGE_INDICATE_UDPTL_MODE,
|
||||
SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS,
|
||||
SWITCH_MESSAGE_INDICATE_JITTER_BUFFER,
|
||||
SWITCH_MESSAGE_INVALID
|
||||
} switch_core_session_message_types_t;
|
||||
|
||||
|
@ -1093,6 +1094,8 @@ typedef enum {
|
|||
CF_PASSTHRU_PTIME_MISMATCH,
|
||||
CF_BRIDGE_NOWRITE,
|
||||
CF_RECOVERED,
|
||||
CF_JITTERBUFFER,
|
||||
CF_DIALPLAN,
|
||||
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
|
||||
CF_FLAG_MAX
|
||||
} switch_channel_flag_t;
|
||||
|
|
|
@ -2491,24 +2491,101 @@ SWITCH_STANDARD_API(uuid_display_function)
|
|||
#define SIMPLIFY_SYNTAX "<uuid>"
|
||||
SWITCH_STANDARD_API(uuid_simplify_function)
|
||||
{
|
||||
char *mydata = NULL, *argv[2] = { 0 };
|
||||
int argc = 0;
|
||||
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
if (zstr(cmd)) {
|
||||
stream->write_function(stream, "-USAGE: %s\n", SIMPLIFY_SYNTAX);
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
|
||||
mydata = strdup(cmd);
|
||||
switch_assert(mydata);
|
||||
|
||||
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
|
||||
if (argc < 1) {
|
||||
goto error;
|
||||
}
|
||||
if (argv[0]) {
|
||||
switch_core_session_message_t msg = { 0 };
|
||||
switch_core_session_t *lsession = NULL;
|
||||
|
||||
msg.message_id = SWITCH_MESSAGE_INDICATE_SIMPLIFY;
|
||||
msg.string_arg = cmd;
|
||||
msg.string_arg = argv[0];
|
||||
msg.from = __FILE__;
|
||||
|
||||
if ((lsession = switch_core_session_locate(cmd))) {
|
||||
if ((lsession = switch_core_session_locate(argv[0]))) {
|
||||
status = switch_core_session_receive_message(lsession, &msg);
|
||||
switch_core_session_rwunlock(lsession);
|
||||
}
|
||||
goto ok;
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
|
||||
error:
|
||||
stream->write_function(stream, "-USAGE: %s\n", SIMPLIFY_SYNTAX);
|
||||
switch_safe_free(mydata);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
ok:
|
||||
switch_safe_free(mydata);
|
||||
|
||||
if (status == SWITCH_STATUS_SUCCESS) {
|
||||
stream->write_function(stream, "+OK Success\n");
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR Operation Failed\n");
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#define JITTERBUFFER_SYNTAX "<uuid> [0|<min_msec>[:<max_msec>]]"
|
||||
SWITCH_STANDARD_API(uuid_jitterbuffer_function)
|
||||
{
|
||||
char *mydata = NULL, *argv[2] = { 0 };
|
||||
int argc = 0;
|
||||
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
if (zstr(cmd)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
mydata = strdup(cmd);
|
||||
switch_assert(mydata);
|
||||
|
||||
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
|
||||
if (argc < 2) {
|
||||
goto error;
|
||||
}
|
||||
if (argv[1]) {
|
||||
switch_core_session_message_t msg = { 0 };
|
||||
switch_core_session_t *lsession = NULL;
|
||||
|
||||
msg.message_id = SWITCH_MESSAGE_INDICATE_JITTER_BUFFER;
|
||||
msg.string_arg = argv[1];
|
||||
msg.from = __FILE__;
|
||||
|
||||
if ((lsession = switch_core_session_locate(argv[0]))) {
|
||||
status = switch_core_session_receive_message(lsession, &msg);
|
||||
switch_core_session_rwunlock(lsession);
|
||||
}
|
||||
goto ok;
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
|
||||
error:
|
||||
stream->write_function(stream, "-USAGE: %s\n", JITTERBUFFER_SYNTAX);
|
||||
switch_safe_free(mydata);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
ok:
|
||||
switch_safe_free(mydata);
|
||||
|
||||
if (status == SWITCH_STATUS_SUCCESS) {
|
||||
stream->write_function(stream, "+OK Success\n");
|
||||
} else {
|
||||
|
@ -4255,21 +4332,33 @@ SWITCH_STANDARD_API(strftime_tz_api_function)
|
|||
char *format = NULL;
|
||||
const char *tz_name = NULL;
|
||||
char date[80] = "";
|
||||
char *mycmd = NULL, *p;
|
||||
switch_time_t when = 0;
|
||||
|
||||
if (!zstr(cmd)) {
|
||||
format = strchr(cmd, ' ');
|
||||
tz_name = cmd;
|
||||
if (format) {
|
||||
if (cmd) mycmd = strdup(cmd);
|
||||
|
||||
if (!zstr(mycmd)) {
|
||||
tz_name = mycmd;
|
||||
|
||||
if ((format = strchr(mycmd, ' '))) {
|
||||
*format++ = '\0';
|
||||
}
|
||||
|
||||
if ((p = strchr(format, '|'))) {
|
||||
*p++ = '\0';
|
||||
when = atol(format);
|
||||
format = p;
|
||||
}
|
||||
}
|
||||
|
||||
if (switch_strftime_tz(tz_name, format, date, sizeof(date), 0) == SWITCH_STATUS_SUCCESS) { /* The lookup of the zone may fail. */
|
||||
if (switch_strftime_tz(tz_name, format, date, sizeof(date), when * 1000000) == SWITCH_STATUS_SUCCESS) { /* The lookup of the zone may fail. */
|
||||
stream->write_function(stream, "%s", date);
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR Invalid Timezone\n");
|
||||
}
|
||||
|
||||
switch_safe_free(mycmd);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -4692,7 +4781,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
|||
SWITCH_ADD_API(commands_api_interface, "show", "Show", show_function, SHOW_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "sql_escape", "Escape a string to prevent sql injection", sql_escape, SQL_ESCAPE_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "status", "status", status_function, "");
|
||||
SWITCH_ADD_API(commands_api_interface, "strftime_tz", "strftime_tz", strftime_tz_api_function, "<Timezone_name> [format string]");
|
||||
SWITCH_ADD_API(commands_api_interface, "strftime_tz", "strftime_tz", strftime_tz_api_function, "<Timezone_name> [<epoch>|][format string]");
|
||||
SWITCH_ADD_API(commands_api_interface, "stun", "stun", stun_function, "<stun_server>[:port]");
|
||||
SWITCH_ADD_API(commands_api_interface, "system", "Execute a system command", system_function, SYSTEM_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "time_test", "time_test", time_test_function, "<mss> [count]");
|
||||
|
@ -4735,6 +4824,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
|||
SWITCH_ADD_API(commands_api_interface, "uuid_transfer", "Transfer a session", transfer_function, TRANSFER_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_dual_transfer", "Transfer a session and its partner", dual_transfer_function, DUAL_TRANSFER_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_simplify", "Try to cut out of a call path / attended xfer", uuid_simplify_function, SIMPLIFY_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_jitterbuffer", "Try to cut out of a call path / attended xfer",
|
||||
uuid_jitterbuffer_function, JITTERBUFFER_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "xml_locate", "find some xml", xml_locate_function, "[root | <section> <tag> <tag_attr_name> <tag_attr_val>]");
|
||||
SWITCH_ADD_API(commands_api_interface, "xml_wrap", "Wrap another api command in xml", xml_wrap_api_function, "<command> <args>");
|
||||
switch_console_set_complete("add alias add");
|
||||
|
@ -4831,6 +4922,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
|||
switch_console_set_complete("add uuid_flush_dtmf ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_getvar ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_hold ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_jitterbuffer ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_kill ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_limit_release ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_loglevel ::console::list_uuid console");
|
||||
|
@ -4853,6 +4945,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
|||
switch_console_set_complete("add uuid_session_heartbeat ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_setvar_multi ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_setvar ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_simplify ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_transfer ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_dual_transfer ::console::list_uuid");
|
||||
switch_console_set_complete("add version");
|
||||
|
|
|
@ -2456,7 +2456,7 @@ static void conference_loop_output(conference_member_t *member)
|
|||
switch_event_destroy(&event);
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
/* test to see if outbound channel has answered */
|
||||
if (switch_channel_test_flag(channel, CF_ANSWERED) && !switch_test_flag(member->conference, CFLAG_ANSWERED)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG,
|
||||
|
@ -2599,7 +2599,7 @@ static void conference_loop_output(conference_member_t *member)
|
|||
switch_channel_cause2str(switch_channel_get_cause(channel)));
|
||||
|
||||
/* if it's an outbound channel, store the release cause in the conference struct, we might need it */
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
member->conference->bridge_hangup_cause = switch_channel_get_cause(channel);
|
||||
}
|
||||
|
||||
|
@ -4366,6 +4366,8 @@ static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switc
|
|||
}
|
||||
}
|
||||
|
||||
switch_channel_set_variable(channel, "last_transfered_conference", argv[2]);
|
||||
|
||||
unlock_member(member);
|
||||
|
||||
stream->write_function(stream, "OK Member '%d' sent to conference %s.\n", member->id, argv[2]);
|
||||
|
@ -5374,6 +5376,14 @@ SWITCH_STANDARD_APP(conference_function)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_RECOVERED)) {
|
||||
const char *check = switch_channel_get_variable(channel, "last_transfered_conference");
|
||||
|
||||
if (!zstr(check)) {
|
||||
conf_name = (char *) check;
|
||||
}
|
||||
}
|
||||
|
||||
switch_event_create(¶ms, SWITCH_EVENT_COMMAND);
|
||||
switch_assert(params);
|
||||
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "conf_name", conf_name);
|
||||
|
@ -5436,7 +5446,7 @@ SWITCH_STANDARD_APP(conference_function)
|
|||
launch_conference_thread(conference);
|
||||
|
||||
} else {
|
||||
int enforce_security = !switch_channel_test_flag(channel, CF_OUTBOUND);
|
||||
int enforce_security = switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND;
|
||||
const char *pvar = switch_channel_get_variable(channel, "conference_enforce_security");
|
||||
|
||||
if (pvar) {
|
||||
|
@ -5645,7 +5655,7 @@ SWITCH_STANDARD_APP(conference_function)
|
|||
} else {
|
||||
/* if we're not using "bridge:" set the conference answered flag */
|
||||
/* and this isn't an outbound channel, answer the call */
|
||||
if (!switch_channel_test_flag(channel, CF_OUTBOUND))
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND)
|
||||
switch_set_flag(conference, CFLAG_ANSWERED);
|
||||
}
|
||||
|
||||
|
|
|
@ -269,7 +269,7 @@ SWITCH_STANDARD_APP(bind_digit_action_function)
|
|||
}
|
||||
|
||||
|
||||
#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR pause OR resume"
|
||||
#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR nogrammar <gram_name> OR pause OR resume OR stop OR param <name> <value>"
|
||||
SWITCH_STANDARD_APP(detect_speech_function)
|
||||
{
|
||||
char *argv[4];
|
||||
|
@ -957,6 +957,17 @@ SWITCH_STANDARD_APP(redirect_function)
|
|||
switch_core_session_receive_message(session, &msg);
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_APP(jitterbuffer_function)
|
||||
{
|
||||
switch_core_session_message_t msg = { 0 };
|
||||
|
||||
/* Tell the channel to change the jitter buffer */
|
||||
msg.from = __FILE__;
|
||||
msg.string_arg = data;
|
||||
msg.message_id = SWITCH_MESSAGE_INDICATE_JITTER_BUFFER;
|
||||
switch_core_session_receive_message(session, &msg);
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_APP(display_function)
|
||||
{
|
||||
switch_core_session_message_t msg = { 0 };
|
||||
|
@ -1303,13 +1314,22 @@ SWITCH_STANDARD_API(strftime_api_function)
|
|||
char date[80] = "";
|
||||
switch_time_t thetime;
|
||||
char *p;
|
||||
if (!zstr(cmd) && (p = strchr(cmd, '|'))) {
|
||||
thetime = switch_time_make(atoi(cmd), 0);
|
||||
char *mycmd = NULL;
|
||||
|
||||
if (!zstr(cmd)) {
|
||||
mycmd = strdup(cmd);
|
||||
}
|
||||
|
||||
if (!zstr(mycmd) && (p = strchr(cmd, '|'))) {
|
||||
*p++ = '\0';
|
||||
|
||||
thetime = switch_time_make(atol(cmd), 0);
|
||||
cmd = p + 1;
|
||||
} else {
|
||||
thetime = switch_micro_time_now();
|
||||
}
|
||||
switch_time_exp_lt(&tm, thetime);
|
||||
|
||||
if (zstr(cmd)) {
|
||||
switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
|
||||
} else {
|
||||
|
@ -3513,6 +3533,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
|
|||
SWITCH_ADD_APP(app_interface, "ivr", "Run an ivr menu", "Run an ivr menu.", ivr_application_function, "<menu_name>", SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "redirect", "Send session redirect", "Send a redirect message to a session.", redirect_function, "<redirect_data>",
|
||||
SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "jitterbuffer", "Send session jitterbuffer", "Send a jitterbuffer message to a session.",
|
||||
jitterbuffer_function, "<jitterbuffer_data>", SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "send_display", "Send session a new display", "Send session a new display.", display_function, "<text>",
|
||||
SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "respond", "Send session respond", "Send a respond message to a session.", respond_function, "<respond_data>",
|
||||
|
|
|
@ -291,6 +291,7 @@ static switch_status_t fifo_queue_popfly(fifo_queue_t *queue, const char *uuid)
|
|||
struct fifo_node {
|
||||
char *name;
|
||||
switch_mutex_t *mutex;
|
||||
switch_mutex_t *update_mutex;
|
||||
fifo_queue_t *fifo_list[MAX_PRI];
|
||||
switch_hash_t *consumer_hash;
|
||||
int outbound_priority;
|
||||
|
@ -801,6 +802,7 @@ static fifo_node_t *create_node(const char *name, uint32_t importance, switch_mu
|
|||
switch_core_hash_init(&node->consumer_hash, node->pool);
|
||||
switch_thread_rwlock_create(&node->rwlock, node->pool);
|
||||
switch_mutex_init(&node->mutex, SWITCH_MUTEX_NESTED, node->pool);
|
||||
switch_mutex_init(&node->update_mutex, SWITCH_MUTEX_NESTED, node->pool);
|
||||
cbt.buf = outbound_count;
|
||||
cbt.len = sizeof(outbound_count);
|
||||
sql = switch_mprintf("select count(*) from fifo_outbound where fifo_name = '%q'", name);
|
||||
|
@ -1193,10 +1195,10 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void
|
|||
|
||||
|
||||
if (node) {
|
||||
switch_thread_rwlock_wrlock(node->rwlock);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
node->busy = 0;
|
||||
node->ring_consumer_count = 1;
|
||||
switch_thread_rwlock_unlock(node->rwlock);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
} else {
|
||||
goto end;
|
||||
}
|
||||
|
@ -1437,10 +1439,10 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void
|
|||
cbh->ready = 1;
|
||||
|
||||
if (node) {
|
||||
switch_thread_rwlock_wrlock(node->rwlock);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
node->ring_consumer_count = 0;
|
||||
node->busy = 0;
|
||||
switch_thread_rwlock_unlock(node->rwlock);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1501,10 +1503,10 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj)
|
|||
switch_mutex_unlock(globals.mutex);
|
||||
|
||||
if (node) {
|
||||
switch_thread_rwlock_wrlock(node->rwlock);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
node->ring_consumer_count++;
|
||||
node->busy = 0;
|
||||
switch_thread_rwlock_unlock(node->rwlock);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
}
|
||||
|
||||
switch_event_create(&ovars, SWITCH_EVENT_REQUEST_PARAMS);
|
||||
|
@ -1601,12 +1603,12 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj)
|
|||
|
||||
switch_event_destroy(&ovars);
|
||||
if (node) {
|
||||
switch_thread_rwlock_wrlock(node->rwlock);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
if (node->ring_consumer_count-- < 0) {
|
||||
node->ring_consumer_count = 0;
|
||||
}
|
||||
node->busy = 0;
|
||||
switch_thread_rwlock_unlock(node->rwlock);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
}
|
||||
switch_core_destroy_memory_pool(&h->pool);
|
||||
|
||||
|
@ -1754,9 +1756,35 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o
|
|||
if (globals.debug) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Trying priority: %d\n", cur_priority);
|
||||
|
||||
|
||||
restart:
|
||||
|
||||
for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) {
|
||||
switch_hash_this(hi, &var, NULL, &val);
|
||||
if ((node = (fifo_node_t *) val)) {
|
||||
|
||||
if (node->ready == FIFO_DELAY_DESTROY) {
|
||||
int doit = 0;
|
||||
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
doit = node->consumer_count == 0 && node_caller_count(node) == 0;
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
|
||||
if (doit) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s removed.\n", node->name);
|
||||
switch_core_hash_delete(globals.fifo_hash, node->name);
|
||||
|
||||
node->ready = 0;
|
||||
switch_mutex_lock(node->mutex);
|
||||
switch_core_hash_destroy(&node->consumer_hash);
|
||||
switch_mutex_unlock(node->mutex);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
switch_core_destroy_memory_pool(&node->pool);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (node->outbound_priority == 0) node->outbound_priority = 5;
|
||||
if (node->has_outbound && node->ready && !node->busy && node->outbound_priority == cur_priority) {
|
||||
ppl_waiting = node_caller_count(node);
|
||||
|
@ -2219,6 +2247,7 @@ SWITCH_STANDARD_APP(fifo_function)
|
|||
if (!(node = switch_core_hash_find(globals.fifo_hash, nlist[i]))) {
|
||||
node = create_node(nlist[i], importance, globals.sql_mutex);
|
||||
node->ready = 1;
|
||||
switch_thread_rwlock_rdlock(node->rwlock);
|
||||
}
|
||||
node_list[node_count++] = node;
|
||||
}
|
||||
|
@ -2306,7 +2335,7 @@ SWITCH_STANDARD_APP(fifo_function)
|
|||
|
||||
switch_channel_answer(channel);
|
||||
|
||||
switch_thread_rwlock_wrlock(node->rwlock);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
|
||||
if ((pri = switch_channel_get_variable(channel, "fifo_priority"))) {
|
||||
p = atoi(pri);
|
||||
|
@ -2344,7 +2373,7 @@ SWITCH_STANDARD_APP(fifo_function)
|
|||
switch_channel_set_variable(channel, "fifo_priority", tmp);
|
||||
}
|
||||
|
||||
switch_thread_rwlock_unlock(node->rwlock);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
|
||||
ts = switch_micro_time_now();
|
||||
switch_time_exp_lt(&tm, ts);
|
||||
|
@ -2450,9 +2479,9 @@ SWITCH_STANDARD_APP(fifo_function)
|
|||
}
|
||||
|
||||
switch_mutex_lock(globals.mutex);
|
||||
switch_thread_rwlock_wrlock(node->rwlock);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
node_remove_uuid(node, uuid);
|
||||
switch_thread_rwlock_unlock(node->rwlock);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
send_presence(node);
|
||||
check_cancel(node);
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
|
@ -2682,9 +2711,9 @@ SWITCH_STANDARD_APP(fifo_function)
|
|||
}
|
||||
|
||||
if (pop && !node_caller_count(node)) {
|
||||
switch_thread_rwlock_wrlock(node->rwlock);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
node->start_waiting = 0;
|
||||
switch_thread_rwlock_unlock(node->rwlock);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3074,21 +3103,9 @@ SWITCH_STANDARD_APP(fifo_function)
|
|||
|
||||
done:
|
||||
|
||||
switch_mutex_lock(globals.mutex);
|
||||
if (node && node->ready == FIFO_DELAY_DESTROY && node->consumer_count == 0 && node_caller_count(node) == 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "%s removed.\n", node->name);
|
||||
switch_core_hash_delete(globals.fifo_hash, node->name);
|
||||
switch_thread_rwlock_wrlock(node->rwlock);
|
||||
node->ready = 0;
|
||||
switch_mutex_lock(node->mutex);
|
||||
switch_core_hash_destroy(&node->consumer_hash);
|
||||
switch_mutex_unlock(node->mutex);
|
||||
if (node) {
|
||||
switch_thread_rwlock_unlock(node->rwlock);
|
||||
switch_core_destroy_memory_pool(&node->pool);
|
||||
|
||||
}
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
|
||||
|
||||
switch_channel_clear_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_BRIDGE_TAG);
|
||||
|
||||
|
@ -3699,9 +3716,9 @@ SWITCH_STANDARD_API(fifo_api_function)
|
|||
switch_hash_this(hi, &var, NULL, &val);
|
||||
node = (fifo_node_t *) val;
|
||||
len = node_caller_count(node);
|
||||
switch_thread_rwlock_wrlock(node->rwlock);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
stream->write_function(stream, "%s:%d:%d:%d\n", (char *) var, node->consumer_count, node_caller_count(node), len);
|
||||
switch_thread_rwlock_unlock(node->rwlock);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
x++;
|
||||
}
|
||||
|
||||
|
@ -3710,9 +3727,9 @@ SWITCH_STANDARD_API(fifo_api_function)
|
|||
}
|
||||
} else if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) {
|
||||
len = node_caller_count(node);
|
||||
switch_thread_rwlock_wrlock(node->rwlock);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
stream->write_function(stream, "%s:%d:%d:%d\n", argv[1], node->consumer_count, node_caller_count(node), len);
|
||||
switch_thread_rwlock_unlock(node->rwlock);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
} else {
|
||||
stream->write_function(stream, "none\n");
|
||||
}
|
||||
|
@ -3722,9 +3739,9 @@ SWITCH_STANDARD_API(fifo_api_function)
|
|||
switch_hash_this(hi, &var, NULL, &val);
|
||||
node = (fifo_node_t *) val;
|
||||
len = node_caller_count(node);
|
||||
switch_thread_rwlock_wrlock(node->rwlock);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
stream->write_function(stream, "%s:%d\n", (char *) var, node->has_outbound);
|
||||
switch_thread_rwlock_unlock(node->rwlock);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
x++;
|
||||
}
|
||||
|
||||
|
@ -3733,9 +3750,9 @@ SWITCH_STANDARD_API(fifo_api_function)
|
|||
}
|
||||
} else if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) {
|
||||
len = node_caller_count(node);
|
||||
switch_thread_rwlock_wrlock(node->rwlock);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
stream->write_function(stream, "%s:%d\n", argv[1], node->has_outbound);
|
||||
switch_thread_rwlock_unlock(node->rwlock);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
} else {
|
||||
stream->write_function(stream, "none\n");
|
||||
}
|
||||
|
@ -4108,7 +4125,7 @@ static switch_status_t load_config(int reload, int del_all)
|
|||
node->ready = FIFO_DELAY_DESTROY;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s removed.\n", node->name);
|
||||
switch_thread_rwlock_wrlock(node->rwlock);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
for (x = 0; x < MAX_PRI; x++) {
|
||||
while (fifo_queue_pop(node->fifo_list[x], &pop, 2) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_destroy(&pop);
|
||||
|
@ -4117,7 +4134,7 @@ static switch_status_t load_config(int reload, int del_all)
|
|||
|
||||
switch_core_hash_delete(globals.fifo_hash, node->name);
|
||||
switch_core_hash_destroy(&node->consumer_hash);
|
||||
switch_thread_rwlock_unlock(node->rwlock);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
switch_core_destroy_memory_pool(&node->pool);
|
||||
goto top;
|
||||
}
|
||||
|
@ -4393,7 +4410,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fifo_shutdown)
|
|||
switch_hash_this(hi, NULL, NULL, &val);
|
||||
node = (fifo_node_t *) val;
|
||||
|
||||
switch_thread_rwlock_wrlock(node->rwlock);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
switch_mutex_lock(node->mutex);
|
||||
for (x = 0; x < MAX_PRI; x++) {
|
||||
while (fifo_queue_pop(node->fifo_list[x], &pop, 2) == SWITCH_STATUS_SUCCESS) {
|
||||
|
@ -4403,7 +4420,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fifo_shutdown)
|
|||
switch_mutex_unlock(node->mutex);
|
||||
switch_core_hash_delete(globals.fifo_hash, node->name);
|
||||
switch_core_hash_destroy(&node->consumer_hash);
|
||||
switch_thread_rwlock_unlock(node->rwlock);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
switch_core_destroy_memory_pool(&node->pool);
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,6 @@ SWITCH_STANDARD_API(dump_hash)
|
|||
static switch_status_t process_event(switch_event_t *event)
|
||||
{
|
||||
switch_core_session_t *session = NULL;
|
||||
switch_channel_t *channel;
|
||||
char *username[3] = { 0 };
|
||||
char *domain[3] = { 0 };
|
||||
char key[512];
|
||||
|
@ -172,18 +171,19 @@ static switch_status_t process_event(switch_event_t *event)
|
|||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
session = switch_core_session_locate(uuid);
|
||||
channel = switch_core_session_get_channel(session);
|
||||
if ((session = switch_core_session_locate(uuid))) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UserSpy retrieved uuid %s for key %s, activating eavesdrop \n", uuid, key);
|
||||
my_uuid = switch_event_get_header(event, "Unique-ID");
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UserSpy retrieved uuid %s for key %s, activating eavesdrop \n", uuid, key);
|
||||
my_uuid = switch_event_get_header(event, "Unique-ID");
|
||||
|
||||
switch_channel_set_variable(channel, "spy_uuid", my_uuid);
|
||||
switch_channel_set_variable(channel, "spy_uuid", my_uuid);
|
||||
|
||||
switch_channel_set_state(channel, CS_EXCHANGE_MEDIA);
|
||||
switch_channel_set_flag(channel, CF_BREAK);
|
||||
switch_channel_set_state(channel, CS_EXCHANGE_MEDIA);
|
||||
switch_channel_set_flag(channel, CF_BREAK);
|
||||
|
||||
switch_core_session_rwunlock(session);
|
||||
switch_core_session_rwunlock(session);
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
|
|
@ -1324,7 +1324,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
caller_profile = tech_pvt->caller_profile;
|
||||
caller_profile->destination_number = rdest;
|
||||
|
||||
switch_channel_set_flag(channel, CF_OUTBOUND);
|
||||
switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
|
||||
switch_channel_set_state(channel, CS_INIT);
|
||||
gsmopen_call(tech_pvt, rdest, 30);
|
||||
|
|
|
@ -725,7 +725,6 @@ FSH323Connection::FSH323Connection(FSH323EndPoint& endpoint, H323Transport* tran
|
|||
name += outbound_profile->destination_number;
|
||||
switch_channel_set_name(m_fsChannel, name);
|
||||
|
||||
switch_channel_set_flag(m_fsChannel, CF_OUTBOUND);
|
||||
switch_channel_set_state(m_fsChannel, CS_INIT);
|
||||
}
|
||||
|
||||
|
@ -1508,7 +1507,7 @@ switch_status_t FSH323Connection::receive_message(switch_core_session_message_t
|
|||
break;
|
||||
}
|
||||
case SWITCH_MESSAGE_INDICATE_ANSWER: {
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
AnsweringCall(H323Connection::AnswerCallNow);
|
||||
|
|
|
@ -868,7 +868,6 @@ switch_status_t Board::KhompPvt::justStart(switch_caller_profile_t *profile)
|
|||
_caller_profile = switch_caller_profile_clone(_session, profile);
|
||||
switch_channel_set_caller_profile(channel, _caller_profile);
|
||||
|
||||
switch_channel_set_flag(channel, CF_OUTBOUND);
|
||||
switch_channel_set_state(channel, CS_INIT);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -580,7 +580,6 @@ FSConnection::FSConnection(OpalCall & call, FSEndPoint & endpoint, void* userDat
|
|||
name += outbound_profile->destination_number;
|
||||
switch_channel_set_name(m_fsChannel, name);
|
||||
|
||||
switch_channel_set_flag(m_fsChannel, CF_OUTBOUND);
|
||||
switch_channel_set_state(m_fsChannel, CS_INIT);
|
||||
}
|
||||
}
|
||||
|
@ -966,7 +965,7 @@ switch_status_t FSConnection::receive_message(switch_core_session_message_t *msg
|
|||
It would only happen if someone called switch_channel_answer() instead of switch_channel_mark_answered() on an outbound call.
|
||||
it should not do anything if someone does it by accident somewhere hense this in both cases:
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -1025,7 +1024,7 @@ switch_status_t FSConnection::receive_message(switch_core_session_message_t *msg
|
|||
{
|
||||
int fixed = 0;
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ sub _find {
|
|||
my ($name, $value) = ($1,hex($2));
|
||||
$sub{$name} = sub () { $value };
|
||||
$const{$name} = $value;
|
||||
} elsif(/^\s*struct\s+([a-z_]+)\s*\{\s*$/) {
|
||||
} elsif(/^\s*struct\s+PACKED\s+([a-z_]+)\s*\{\s*$/) {
|
||||
my $struct_name = $1;
|
||||
$struct{$struct_name} = [];
|
||||
while(<$fh>) {
|
||||
|
|
|
@ -1080,8 +1080,6 @@ switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, swi
|
|||
switch_channel_set_caller_profile(nchannel, caller_profile);
|
||||
tech_pvt->caller_profile = caller_profile;
|
||||
|
||||
switch_channel_set_flag(nchannel, CF_OUTBOUND);
|
||||
|
||||
if ((sql = switch_mprintf(
|
||||
"INSERT INTO skinny_active_lines "
|
||||
"(device_name, device_instance, line_instance, channel_uuid, call_id, call_state) "
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#define SKINNY_EVENT_UNREGISTER "skinny::unregister"
|
||||
#define SKINNY_EVENT_EXPIRE "skinny::expire"
|
||||
#define SKINNY_EVENT_ALARM "skinny::alarm"
|
||||
#define SKINNY_EVENT_XML_ALARM "skinny::xml_alarm"
|
||||
#define SKINNY_EVENT_CALL_STATE "skinny::call_state"
|
||||
#define SKINNY_EVENT_USER_TO_DEVICE "skinny::user_to_device"
|
||||
#define SKINNY_EVENT_DEVICE_TO_USER "skinny::device_to_user"
|
||||
|
|
|
@ -547,12 +547,15 @@ struct PACKED service_url_stat_res_message {
|
|||
#define USER_TO_DEVICE_DATA_VERSION1_MESSAGE 0x013F
|
||||
/* See struct PACKED extended_data_message */
|
||||
|
||||
/* XMLAlarmMessage */
|
||||
#define XML_ALARM_MESSAGE 0x015A
|
||||
|
||||
/*****************************************************************************/
|
||||
/* SKINNY MESSAGE */
|
||||
/*****************************************************************************/
|
||||
#define SKINNY_MESSAGE_FIELD_SIZE 4 /* 4-bytes field */
|
||||
#define SKINNY_MESSAGE_HEADERSIZE 12 /* three 4-bytes fields */
|
||||
#define SKINNY_MESSAGE_MAXSIZE 1000
|
||||
#define SKINNY_MESSAGE_MAXSIZE 2048
|
||||
|
||||
union skinny_data {
|
||||
/* no data for KEEP_ALIVE_MESSAGE */
|
||||
|
@ -624,8 +627,7 @@ union skinny_data {
|
|||
struct extended_data_message extended_data;
|
||||
|
||||
uint16_t as_uint16;
|
||||
char as_char;
|
||||
void *raw;
|
||||
char as_char[1];
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -343,7 +343,7 @@ switch_status_t skinny_session_send_call_info(switch_core_session_t *session, li
|
|||
zstr((called_party_number = switch_channel_get_variable(channel, "destination_number")))) {
|
||||
called_party_number = "0000000000";
|
||||
}
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
call_type = SKINNY_INBOUND_CALL;
|
||||
} else {
|
||||
call_type = SKINNY_OUTBOUND_CALL;
|
||||
|
@ -1674,7 +1674,7 @@ switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *liste
|
|||
);
|
||||
|
||||
switch_set_flag_locked(tech_pvt, TFLAG_IO);
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
switch_channel_mark_answered(channel);
|
||||
}
|
||||
if (switch_channel_test_flag(channel, CF_HOLD)) {
|
||||
|
@ -1963,6 +1963,26 @@ switch_status_t skinny_handle_extended_data_message(listener_t *listener, skinny
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t skinny_handle_xml_alarm(listener_t *listener, skinny_message_t *request)
|
||||
{
|
||||
switch_event_t *event = NULL;
|
||||
char *tmp = NULL;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
|
||||
"Received XML alarm.\n");
|
||||
/* skinny::xml_alarm event */
|
||||
skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_XML_ALARM);
|
||||
/* Ensure that the body is null-terminated */
|
||||
tmp = malloc(request->length - 4 + 1);
|
||||
memcpy(tmp, request->data.as_char, request->length - 4);
|
||||
tmp[request->length - 4] = '\0';
|
||||
switch_event_add_body(event, "%s", tmp);
|
||||
switch_safe_free(tmp);
|
||||
switch_event_fire(&event);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *request)
|
||||
{
|
||||
if (listener->profile->debug >= 10 || request->type != KEEP_ALIVE_MESSAGE) {
|
||||
|
@ -1970,7 +1990,7 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re
|
|||
"Received %s (type=%x,length=%d) from %s:%d.\n", skinny_message_type2str(request->type), request->type, request->length,
|
||||
listener->device_name, listener->device_instance);
|
||||
}
|
||||
if(zstr(listener->device_name) && request->type != REGISTER_MESSAGE && request->type != ALARM_MESSAGE) {
|
||||
if(zstr(listener->device_name) && request->type != REGISTER_MESSAGE && request->type != ALARM_MESSAGE && request->type != XML_ALARM_MESSAGE) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
||||
"Device should send a register message first.\n");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
|
@ -2032,6 +2052,8 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re
|
|||
return skinny_handle_extended_data_message(listener, request);
|
||||
case DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE:
|
||||
return skinny_handle_extended_data_message(listener, request);
|
||||
case XML_ALARM_MESSAGE:
|
||||
return skinny_handle_xml_alarm(listener, request);
|
||||
default:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
|
||||
"Unhandled request %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length);
|
||||
|
|
|
@ -99,6 +99,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = {
|
|||
{"DisplayPriNotifyMessage", DISPLAY_PRI_NOTIFY_MESSAGE},
|
||||
{"ServiceUrlStatMessage", SERVICE_URL_STAT_RES_MESSAGE},
|
||||
{"UserToDeviceDataVersion1Message", USER_TO_DEVICE_DATA_VERSION1_MESSAGE},
|
||||
{"XMLAlarmMessage", XML_ALARM_MESSAGE},
|
||||
{NULL, 0}
|
||||
};
|
||||
SKINNY_DECLARE_ID2STR(skinny_message_type2str, SKINNY_MESSAGE_TYPES, "UnknownMessage")
|
||||
|
|
|
@ -87,7 +87,7 @@ uint32_t func(const char *str)\
|
|||
}
|
||||
|
||||
|
||||
extern struct skinny_table SKINNY_MESSAGE_TYPES[65];
|
||||
extern struct skinny_table SKINNY_MESSAGE_TYPES[66];
|
||||
const char *skinny_message_type2str(uint32_t id);
|
||||
uint32_t skinny_str2message_type(const char *str);
|
||||
#define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES)
|
||||
|
|
|
@ -526,6 +526,10 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session)
|
|||
switch_core_timer_destroy(&tech_pvt->timer_read);
|
||||
}
|
||||
|
||||
if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) {
|
||||
switch_core_timer_destroy(&tech_pvt->timer_read_srv);
|
||||
}
|
||||
|
||||
if (tech_pvt->timer_write.timer_interface && tech_pvt->timer_write.timer_interface->timer_next) {
|
||||
switch_core_timer_destroy(&tech_pvt->timer_write);
|
||||
}
|
||||
|
@ -1121,6 +1125,9 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
|
|||
if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) {
|
||||
switch_core_timer_sync(&tech_pvt->timer_read);
|
||||
}
|
||||
if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) {
|
||||
switch_core_timer_sync(&tech_pvt->timer_read_srv);
|
||||
}
|
||||
switch_mutex_unlock(tech_pvt->mutex_audio_srv);
|
||||
}
|
||||
|
||||
|
@ -1146,6 +1153,9 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
|
|||
if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) {
|
||||
switch_core_timer_sync(&tech_pvt->timer_read);
|
||||
}
|
||||
if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) {
|
||||
switch_core_timer_sync(&tech_pvt->timer_read_srv);
|
||||
}
|
||||
switch_mutex_unlock(tech_pvt->mutex_audio_srv);
|
||||
}
|
||||
|
||||
|
@ -1168,6 +1178,9 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
|
|||
if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) {
|
||||
switch_core_timer_sync(&tech_pvt->timer_read);
|
||||
}
|
||||
if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) {
|
||||
switch_core_timer_sync(&tech_pvt->timer_read_srv);
|
||||
}
|
||||
switch_mutex_unlock(tech_pvt->mutex_audio_srv);
|
||||
}
|
||||
|
||||
|
@ -1351,7 +1364,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
caller_profile = tech_pvt->caller_profile;
|
||||
caller_profile->destination_number = rdest;
|
||||
|
||||
switch_channel_set_flag(channel, CF_OUTBOUND);
|
||||
switch_mutex_lock(tech_pvt->flag_mutex);
|
||||
switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
|
||||
switch_mutex_unlock(tech_pvt->flag_mutex);
|
||||
|
@ -2168,6 +2180,13 @@ int start_audio_threads(private_t *tech_pvt)
|
|||
|
||||
switch_core_timer_sync(&tech_pvt->timer_read);
|
||||
|
||||
if (switch_core_timer_init(&tech_pvt->timer_read_srv, "soft", MS_SKYPOPEN, SAMPLES_PER_FRAME, skypopen_module_pool) != SWITCH_STATUS_SUCCESS) {
|
||||
ERRORA("setup timer failed\n", SKYPOPEN_P_LOG);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
switch_core_timer_sync(&tech_pvt->timer_read_srv);
|
||||
|
||||
if (switch_core_timer_init(&tech_pvt->timer_write, "soft", MS_SKYPOPEN, SAMPLES_PER_FRAME, skypopen_module_pool) != SWITCH_STATUS_SUCCESS) {
|
||||
ERRORA("setup timer failed\n", SKYPOPEN_P_LOG);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
# Comment/uncomment the following line to disable/enable debugging
|
||||
#DEBUG = y
|
||||
#LDDINC=/usr/src/linux-headers-2.6.32-26-server/include
|
||||
|
||||
# Add your debugging flag (or not) to CFLAGS
|
||||
ifeq ($(DEBUG),y)
|
||||
DEBFLAGS = -O -g -DSKYPOPEN_DEBUG # "-O" is needed to expand inlines
|
||||
else
|
||||
DEBFLAGS = -O2 -Wall
|
||||
endif
|
||||
|
||||
EXTRA_CFLAGS += $(DEBFLAGS)
|
||||
EXTRA_CFLAGS += -I$(LDDINC)
|
||||
|
||||
ifneq ($(KERNELRELEASE),)
|
||||
# call from kernel build system
|
||||
|
||||
skypopen-objs := main.o
|
||||
|
||||
obj-m := skypopen.o
|
||||
|
||||
else
|
||||
|
||||
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
|
||||
PWD := $(shell pwd)
|
||||
|
||||
modules:
|
||||
$(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules
|
||||
|
||||
endif
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
|
||||
|
||||
depend .depend dep:
|
||||
$(CC) $(EXTRA_CFLAGS) -M *.c > .depend
|
||||
|
||||
|
||||
ifeq (.depend,$(wildcard .depend))
|
||||
include .depend
|
||||
endif
|
|
@ -0,0 +1,470 @@
|
|||
/*
|
||||
* main.c -- the bare skypopen char module
|
||||
*
|
||||
* Copyright (C) 2010 Giovanni Maruzzelli
|
||||
* Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
|
||||
* Copyright (C) 2001 O'Reilly & Associates
|
||||
*
|
||||
* The source code in this file can be freely used, adapted,
|
||||
* and redistributed in source or binary form, so long as an
|
||||
* acknowledgment appears in derived source files. The citation
|
||||
* should list that the code comes from the book "Linux Device
|
||||
* Drivers" by Alessandro Rubini and Jonathan Corbet, published
|
||||
* by O'Reilly & Associates. No warranty is attached;
|
||||
* we cannot take responsibility for errors or fitness for use.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <linux/kernel.h> /* printk() */
|
||||
#include <linux/slab.h> /* kmalloc() */
|
||||
#include <linux/fs.h> /* everything... */
|
||||
#include <linux/errno.h> /* error codes */
|
||||
#include <linux/types.h> /* size_t */
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/fcntl.h> /* O_ACCMODE */
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/cdev.h>
|
||||
|
||||
#include <asm/system.h> /* cli(), *_flags */
|
||||
#include <asm/uaccess.h> /* copy_*_user */
|
||||
|
||||
#include <linux/soundcard.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/ktime.h>
|
||||
|
||||
#include "skypopen.h" /* local definitions */
|
||||
|
||||
/*
|
||||
* Our parameters which can be set at load time.
|
||||
*/
|
||||
|
||||
int skypopen_major = SKYPOPEN_MAJOR;
|
||||
int skypopen_minor = 3;
|
||||
int skypopen_nr_devs = SKYPOPEN_NR_DEVS; /* number of bare skypopen devices */
|
||||
|
||||
module_param(skypopen_major, int, S_IRUGO);
|
||||
module_param(skypopen_minor, int, S_IRUGO);
|
||||
module_param(skypopen_nr_devs, int, S_IRUGO);
|
||||
|
||||
MODULE_AUTHOR("Original: Alessandro Rubini, Jonathan Corbet. Modified by: Giovanni Maruzzelli for FreeSWITCH skypopen");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
static struct skypopen_dev *skypopen_devices; /* allocated in skypopen_init_module */
|
||||
|
||||
static int unload = 0;
|
||||
#ifdef CENTOS
|
||||
#define HRTIMER_MODE_REL HRTIMER_REL
|
||||
#endif// CENTOS
|
||||
|
||||
#ifndef WANT_HRTIMER
|
||||
void my_timer_callback_inq( unsigned long data )
|
||||
{
|
||||
struct skypopen_dev *dev = (void *)data;
|
||||
|
||||
wake_up_interruptible(&dev->inq);
|
||||
mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) );
|
||||
|
||||
}
|
||||
|
||||
void my_timer_callback_outq( unsigned long data )
|
||||
{
|
||||
struct skypopen_dev *dev = (void *)data;
|
||||
|
||||
wake_up_interruptible(&dev->outq);
|
||||
mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) );
|
||||
}
|
||||
#else// WANT_HRTIMER
|
||||
|
||||
#ifndef CENTOS
|
||||
static enum hrtimer_restart my_hrtimer_callback_inq( struct hrtimer *timer_inq )
|
||||
{
|
||||
struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq);
|
||||
ktime_t now;
|
||||
|
||||
if(unload)
|
||||
return HRTIMER_NORESTART;
|
||||
|
||||
now = ktime_get();
|
||||
hrtimer_forward(&dev->timer_inq, now, ktime_set(0, SKYPOPEN_SLEEP * 1000000));
|
||||
wake_up_interruptible(&dev->inq);
|
||||
|
||||
return HRTIMER_RESTART;
|
||||
}
|
||||
static enum hrtimer_restart my_hrtimer_callback_outq( struct hrtimer *timer_outq )
|
||||
{
|
||||
struct skypopen_dev *dev = container_of(timer_outq, struct skypopen_dev, timer_outq);
|
||||
ktime_t now;
|
||||
|
||||
if(unload)
|
||||
return HRTIMER_NORESTART;
|
||||
|
||||
now = ktime_get();
|
||||
hrtimer_forward(&dev->timer_outq, now, ktime_set(0, SKYPOPEN_SLEEP * 1000000));
|
||||
wake_up_interruptible(&dev->outq);
|
||||
|
||||
return HRTIMER_RESTART;
|
||||
}
|
||||
#else// CENTOS
|
||||
static int my_hrtimer_callback_inq( struct hrtimer *timer_inq )
|
||||
{
|
||||
struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq);
|
||||
|
||||
if(unload)
|
||||
return HRTIMER_NORESTART;
|
||||
|
||||
hrtimer_forward(&dev->timer_inq, timer_inq->expires, ktime_set(0, SKYPOPEN_SLEEP * 1000000));
|
||||
wake_up_interruptible(&dev->inq);
|
||||
|
||||
return HRTIMER_RESTART;
|
||||
}
|
||||
static int my_hrtimer_callback_outq( struct hrtimer *timer_outq )
|
||||
{
|
||||
struct skypopen_dev *dev = container_of(timer_outq, struct skypopen_dev, timer_outq);
|
||||
|
||||
if(unload)
|
||||
return HRTIMER_NORESTART;
|
||||
|
||||
hrtimer_forward(&dev->timer_outq, timer_outq->expires, ktime_set(0, SKYPOPEN_SLEEP * 1000000));
|
||||
wake_up_interruptible(&dev->outq);
|
||||
|
||||
return HRTIMER_RESTART;
|
||||
}
|
||||
#endif// CENTOS
|
||||
#endif// WANT_HRTIMER
|
||||
|
||||
/* The clone-specific data structure includes a key field */
|
||||
|
||||
struct skypopen_listitem {
|
||||
struct skypopen_dev device;
|
||||
dev_t key;
|
||||
struct list_head list;
|
||||
|
||||
};
|
||||
|
||||
/* The list of devices, and a lock to protect it */
|
||||
static LIST_HEAD(skypopen_c_list);
|
||||
static spinlock_t skypopen_c_lock = SPIN_LOCK_UNLOCKED;
|
||||
|
||||
/* Look for a device or create one if missing */
|
||||
static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key)
|
||||
{
|
||||
struct skypopen_listitem *lptr;
|
||||
#ifdef WANT_HRTIMER
|
||||
#if 0
|
||||
ktime_t ktime_inq;
|
||||
ktime_t ktime_outq;
|
||||
#endif //0
|
||||
#endif// WANT_HRTIMER
|
||||
|
||||
list_for_each_entry(lptr, &skypopen_c_list, list) {
|
||||
if (lptr->key == key)
|
||||
return &(lptr->device);
|
||||
}
|
||||
|
||||
/* not found */
|
||||
lptr = kmalloc(sizeof(struct skypopen_listitem), GFP_KERNEL);
|
||||
if (!lptr)
|
||||
return NULL;
|
||||
|
||||
/* initialize the device */
|
||||
memset(lptr, 0, sizeof(struct skypopen_listitem));
|
||||
lptr->key = key;
|
||||
|
||||
init_waitqueue_head(&lptr->device.inq);
|
||||
init_waitqueue_head(&lptr->device.outq);
|
||||
#ifndef WANT_HRTIMER
|
||||
setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr );
|
||||
setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr );
|
||||
printk( "Starting skypopen OSS driver read timer (%dms) skype client:(%d)\n", SKYPOPEN_SLEEP, current->tgid );
|
||||
mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) );
|
||||
printk( "Starting skypopen OSS driver write timer (%dms) skype client:(%d)\n", SKYPOPEN_SLEEP, current->tgid );
|
||||
mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) );
|
||||
#else// WANT_HRTIMER
|
||||
#if 0
|
||||
ktime_inq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000);
|
||||
hrtimer_init( &lptr->device.timer_inq, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
|
||||
lptr->device.timer_inq.function = &my_hrtimer_callback_inq;
|
||||
hrtimer_start( &lptr->device.timer_inq, ktime_inq, HRTIMER_MODE_REL );
|
||||
|
||||
ktime_outq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000);
|
||||
hrtimer_init( &lptr->device.timer_outq, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
|
||||
lptr->device.timer_outq.function = &my_hrtimer_callback_outq;
|
||||
hrtimer_start( &lptr->device.timer_outq, ktime_outq, HRTIMER_MODE_REL );
|
||||
#endif
|
||||
|
||||
#endif// WANT_HRTIMER
|
||||
|
||||
/* place it in the list */
|
||||
list_add(&lptr->list, &skypopen_c_list);
|
||||
|
||||
return &(lptr->device);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open and close
|
||||
*/
|
||||
static int skypopen_c_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct skypopen_dev *dev;
|
||||
dev_t key;
|
||||
|
||||
key = current->tgid;
|
||||
|
||||
/* look for a skypopenc device in the list */
|
||||
spin_lock(&skypopen_c_lock);
|
||||
dev = skypopen_c_lookfor_device(key);
|
||||
spin_unlock(&skypopen_c_lock);
|
||||
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
/* then, everything else is copied from the bare skypopen device */
|
||||
filp->private_data = dev;
|
||||
return 0; /* success */
|
||||
}
|
||||
|
||||
static int skypopen_c_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
/*
|
||||
* Nothing to do, because the device is persistent.
|
||||
* A `real' cloned device should be freed on last close
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count,
|
||||
loff_t *f_pos)
|
||||
{
|
||||
DEFINE_WAIT(wait);
|
||||
struct skypopen_dev *dev = filp->private_data;
|
||||
|
||||
if(unload)
|
||||
return -1;
|
||||
|
||||
#ifdef WANT_HRTIMER
|
||||
#if 1
|
||||
if(dev->timer_inq_started == 0){
|
||||
ktime_t ktime_inq;
|
||||
|
||||
ktime_inq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000);
|
||||
hrtimer_init( &dev->timer_inq, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
|
||||
dev->timer_inq.function = &my_hrtimer_callback_inq;
|
||||
hrtimer_start( &dev->timer_inq, ktime_inq, HRTIMER_MODE_REL );
|
||||
dev->timer_inq_started = 1;
|
||||
}
|
||||
#endif
|
||||
#endif// WANT_HRTIMER
|
||||
|
||||
|
||||
//printk("READ\n");
|
||||
prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE);
|
||||
schedule();
|
||||
finish_wait(&dev->inq, &wait);
|
||||
return count;
|
||||
|
||||
}
|
||||
|
||||
static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count,
|
||||
loff_t *f_pos)
|
||||
{
|
||||
DEFINE_WAIT(wait);
|
||||
struct skypopen_dev *dev = filp->private_data;
|
||||
|
||||
if(unload)
|
||||
return -1;
|
||||
|
||||
#ifdef WANT_HRTIMER
|
||||
#if 1
|
||||
if(dev->timer_outq_started == 0){
|
||||
ktime_t ktime_outq;
|
||||
|
||||
ktime_outq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000);
|
||||
hrtimer_init( &dev->timer_outq, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
|
||||
dev->timer_outq.function = &my_hrtimer_callback_outq;
|
||||
hrtimer_start( &dev->timer_outq, ktime_outq, HRTIMER_MODE_REL );
|
||||
dev->timer_outq_started = 1;
|
||||
}
|
||||
#endif
|
||||
#endif// WANT_HRTIMER
|
||||
|
||||
|
||||
//printk("WRITE\n");
|
||||
prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE);
|
||||
schedule();
|
||||
finish_wait(&dev->outq, &wait);
|
||||
return count;
|
||||
|
||||
}
|
||||
/*
|
||||
* The ioctl() implementation
|
||||
*/
|
||||
|
||||
static int skypopen_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
void __user *argp = (void __user *)arg;
|
||||
int __user *p = argp;
|
||||
|
||||
switch (cmd) {
|
||||
case OSS_GETVERSION:
|
||||
return put_user(SOUND_VERSION, p);
|
||||
case SNDCTL_DSP_GETBLKSIZE:
|
||||
return put_user(SKYPOPEN_BLK, p);
|
||||
case SNDCTL_DSP_GETFMTS:
|
||||
return put_user(28731, p);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct file_operations skypopen_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.read = skypopen_read,
|
||||
.write = skypopen_write,
|
||||
.ioctl = skypopen_ioctl,
|
||||
.open = skypopen_c_open,
|
||||
.release = skypopen_c_release,
|
||||
};
|
||||
|
||||
/*
|
||||
* Finally, the module stuff
|
||||
*/
|
||||
|
||||
/*
|
||||
* The cleanup function is used to handle initialization failures as well.
|
||||
* Thefore, it must be careful to work correctly even if some of the items
|
||||
* have not been initialized
|
||||
*/
|
||||
|
||||
void skypopen_cleanup_module(void)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
struct skypopen_listitem *lptr, *next;
|
||||
dev_t devno = MKDEV(skypopen_major, skypopen_minor);
|
||||
|
||||
|
||||
unload = 1;
|
||||
|
||||
msleep(100);
|
||||
|
||||
/* Get rid of our char dev entries */
|
||||
if (skypopen_devices) {
|
||||
for (i = 0; i < skypopen_nr_devs; i++) {
|
||||
cdev_del(&skypopen_devices[i].cdev);
|
||||
}
|
||||
kfree(skypopen_devices);
|
||||
}
|
||||
|
||||
/* And all the cloned devices */
|
||||
list_for_each_entry_safe(lptr, next, &skypopen_c_list, list) {
|
||||
#ifndef WANT_HRTIMER
|
||||
ret= del_timer( &lptr->device.timer_inq );
|
||||
printk( "Stopped skypopen OSS driver read timer\n");
|
||||
ret= del_timer( &lptr->device.timer_outq );
|
||||
printk( "Stopped skypopen OSS driver write timer\n");
|
||||
#else// WANT_HRTIMER
|
||||
if(lptr->device.timer_inq_started){
|
||||
ret = hrtimer_cancel( &lptr->device.timer_inq );
|
||||
printk( "Stopped skypopen OSS driver read HRtimer\n");
|
||||
}
|
||||
if(lptr->device.timer_outq_started){
|
||||
ret = hrtimer_cancel( &lptr->device.timer_outq );
|
||||
printk( "Stopped skypopen OSS driver write HRtimer\n");
|
||||
}
|
||||
|
||||
#endif// WANT_HRTIMER
|
||||
list_del(&lptr->list);
|
||||
kfree(lptr);
|
||||
}
|
||||
/* cleanup_module is never called if registering failed */
|
||||
unregister_chrdev_region(devno, skypopen_nr_devs);
|
||||
printk("skypopen OSS driver unloaded\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set up the char_dev structure for this device.
|
||||
*/
|
||||
static void skypopen_setup_cdev(struct skypopen_dev *dev, int index)
|
||||
{
|
||||
int err, devno = MKDEV(skypopen_major, skypopen_minor + index);
|
||||
|
||||
cdev_init(&dev->cdev, &skypopen_fops);
|
||||
dev->cdev.owner = THIS_MODULE;
|
||||
dev->cdev.ops = &skypopen_fops;
|
||||
err = cdev_add (&dev->cdev, devno, 1);
|
||||
/* Fail gracefully if need be */
|
||||
if (err)
|
||||
printk(KERN_NOTICE "Error %d adding skypopen%d", err, index);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int skypopen_init_module(void)
|
||||
{
|
||||
int result, i;
|
||||
dev_t dev = 0;
|
||||
|
||||
printk("skypopen OSS driver loading (www.freeswitch.org)\n");
|
||||
/*
|
||||
* Get a range of minor numbers to work with, asking for a dynamic
|
||||
* major unless directed otherwise at load time.
|
||||
*/
|
||||
if (skypopen_major) {
|
||||
dev = MKDEV(skypopen_major, skypopen_minor);
|
||||
result = register_chrdev_region(dev, skypopen_nr_devs, "dsp");
|
||||
} else {
|
||||
result = alloc_chrdev_region(&dev, skypopen_minor, skypopen_nr_devs,
|
||||
"dsp");
|
||||
skypopen_major = MAJOR(dev);
|
||||
}
|
||||
if (result < 0) {
|
||||
printk(KERN_WARNING "skypopen OSS driver: can't get major %d\n", skypopen_major);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate the devices -- we can't have them static, as the number
|
||||
* can be specified at load time
|
||||
*/
|
||||
skypopen_devices = kmalloc(skypopen_nr_devs * sizeof(struct skypopen_dev), GFP_KERNEL);
|
||||
if (!skypopen_devices) {
|
||||
result = -ENOMEM;
|
||||
goto fail; /* Make this more graceful */
|
||||
}
|
||||
memset(skypopen_devices, 0, skypopen_nr_devs * sizeof(struct skypopen_dev));
|
||||
|
||||
/* Initialize each device. */
|
||||
for (i = 0; i < skypopen_nr_devs; i++) {
|
||||
skypopen_setup_cdev(&skypopen_devices[i], i);
|
||||
}
|
||||
|
||||
/* At this point call the init function for any friend device */
|
||||
dev = MKDEV(skypopen_major, skypopen_minor + skypopen_nr_devs);
|
||||
return 0; /* succeed */
|
||||
|
||||
fail:
|
||||
skypopen_cleanup_module();
|
||||
return result;
|
||||
}
|
||||
|
||||
module_init(skypopen_init_module);
|
||||
module_exit(skypopen_cleanup_module);
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* skypopen.h -- definitions for the char module
|
||||
*
|
||||
* Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
|
||||
* Copyright (C) 2001 O'Reilly & Associates
|
||||
*
|
||||
* The source code in this file can be freely used, adapted,
|
||||
* and redistributed in source or binary form, so long as an
|
||||
* acknowledgment appears in derived source files. The citation
|
||||
* should list that the code comes from the book "Linux Device
|
||||
* Drivers" by Alessandro Rubini and Jonathan Corbet, published
|
||||
* by O'Reilly & Associates. No warranty is attached;
|
||||
* we cannot take responsibility for errors or fitness for use.
|
||||
*
|
||||
* $Id: skypopen.h,v 1.15 2004/11/04 17:51:18 rubini Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SKYPOPEN_H_
|
||||
#define _SKYPOPEN_H_
|
||||
|
||||
#include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */
|
||||
|
||||
#define SKYPOPEN_BLK 960
|
||||
#define SKYPOPEN_SLEEP 10
|
||||
|
||||
#define CENTOS
|
||||
|
||||
#ifndef SKYPOPEN_MAJOR
|
||||
#define SKYPOPEN_MAJOR 14 /* dynamic major by default */
|
||||
#endif
|
||||
|
||||
#ifndef SKYPOPEN_NR_DEVS
|
||||
#define SKYPOPEN_NR_DEVS 1 /* skypopen0 through skypopen3 */
|
||||
#endif
|
||||
|
||||
#define WANT_HRTIMER
|
||||
struct skypopen_dev {
|
||||
struct cdev cdev; /* Char device structure */
|
||||
wait_queue_head_t inq; /* read and write queues */
|
||||
wait_queue_head_t outq; /* read and write queues */
|
||||
#ifndef WANT_HRTIMER
|
||||
struct timer_list timer_inq;
|
||||
struct timer_list timer_outq;
|
||||
#else// WANT_HRTIMER
|
||||
struct hrtimer timer_inq;
|
||||
struct hrtimer timer_outq;
|
||||
#endif// WANT_HRTIMER
|
||||
int timer_inq_started;
|
||||
int timer_outq_started;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* The different configurable parameters
|
||||
*/
|
||||
extern int skypopen_major; /* main.c */
|
||||
extern int skypopen_nr_devs;
|
||||
|
||||
|
||||
/*
|
||||
* Prototypes for shared functions
|
||||
*/
|
||||
|
||||
//ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count,
|
||||
//loff_t *f_pos);
|
||||
//ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count,
|
||||
//loff_t *f_pos);
|
||||
//int skypopen_ioctl(struct inode *inode, struct file *filp,
|
||||
//unsigned int cmd, unsigned long arg);
|
||||
|
||||
#endif /* _SKYPOPEN_H_ */
|
|
@ -76,8 +76,8 @@
|
|||
|
||||
#define SAMPLERATE_SKYPOPEN 16000
|
||||
#define MS_SKYPOPEN 20
|
||||
#define SAMPLES_PER_FRAME SAMPLERATE_SKYPOPEN/(1000/MS_SKYPOPEN)
|
||||
#define BYTES_PER_FRAME SAMPLES_PER_FRAME * sizeof(short)
|
||||
#define SAMPLES_PER_FRAME (SAMPLERATE_SKYPOPEN/(1000/MS_SKYPOPEN))
|
||||
#define BYTES_PER_FRAME (SAMPLES_PER_FRAME * sizeof(short))
|
||||
|
||||
#ifdef SKYPOPEN_C_VER
|
||||
#ifdef MODSKYPOPEN_C_VER
|
||||
|
@ -341,6 +341,7 @@ struct private_object {
|
|||
chat_t chats[MAX_CHATS];
|
||||
uint32_t report_incoming_chatmessages;
|
||||
switch_timer_t timer_read;
|
||||
switch_timer_t timer_read_srv;
|
||||
switch_timer_t timer_write;
|
||||
int begin_to_write;
|
||||
int begin_to_read;
|
||||
|
|
|
@ -547,6 +547,9 @@ int skypopen_signaling_read(private_t *tech_pvt)
|
|||
if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) {
|
||||
switch_core_timer_sync(&tech_pvt->timer_read);
|
||||
}
|
||||
if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) {
|
||||
switch_core_timer_sync(&tech_pvt->timer_read_srv);
|
||||
}
|
||||
switch_mutex_unlock(tech_pvt->mutex_audio_srv);
|
||||
}
|
||||
|
||||
|
@ -878,7 +881,7 @@ void *skypopen_do_tcp_srv_thread_func(void *obj)
|
|||
|| tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPOPEN_STATE_UP)) {
|
||||
|
||||
unsigned int fdselect;
|
||||
int rt;
|
||||
int rt=1;
|
||||
fd_set fs;
|
||||
struct timeval to;
|
||||
int nospace;
|
||||
|
@ -891,7 +894,10 @@ void *skypopen_do_tcp_srv_thread_func(void *obj)
|
|||
to.tv_usec = MS_SKYPOPEN * 1000 * 3;
|
||||
to.tv_sec = 0;
|
||||
|
||||
rt = select(fdselect + 1, &fs, NULL, NULL, &to);
|
||||
if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) {
|
||||
switch_core_timer_next(&tech_pvt->timer_read_srv);
|
||||
}
|
||||
//rt = select(fdselect + 1, &fs, NULL, NULL, &to);
|
||||
if (rt > 0) {
|
||||
|
||||
if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) {
|
||||
|
|
|
@ -508,7 +508,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
|
|||
TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)), TAG_END());
|
||||
}
|
||||
} else {
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Sending CANCEL to %s\n", switch_channel_get_name(channel));
|
||||
if (!tech_pvt->got_bye) {
|
||||
switch_channel_set_variable(channel, "sip_hangup_disposition", "send_cancel");
|
||||
|
@ -573,7 +573,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
|||
char *sticky = NULL;
|
||||
const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full");
|
||||
|
||||
if (sofia_test_flag(tech_pvt, TFLAG_ANS) || switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (sofia_test_flag(tech_pvt, TFLAG_ANS) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -653,7 +653,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
|||
switch_channel_clear_flag(channel, CF_PROXY_MODE);
|
||||
}
|
||||
|
||||
if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
|
||||
tech_pvt->num_codecs = 0;
|
||||
sofia_glue_tech_prepare_codecs(tech_pvt);
|
||||
|
@ -723,7 +723,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
|||
TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
|
||||
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
|
||||
NUTAG_SESSION_TIMER(session_timeout),
|
||||
TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
|
||||
NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
|
||||
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
|
||||
SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
|
||||
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
|
||||
|
@ -739,7 +739,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
|||
TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
|
||||
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
|
||||
NUTAG_SESSION_TIMER(session_timeout),
|
||||
TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
|
||||
NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
|
||||
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
|
||||
SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
|
||||
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
|
||||
|
@ -906,7 +906,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
|
|||
tech_pvt->read_frame.flags = SFF_NONE;
|
||||
|
||||
status = switch_rtp_zerocopy_read_frame(tech_pvt->rtp_session, &tech_pvt->read_frame, flags);
|
||||
|
||||
|
||||
if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
|
||||
if (status == SWITCH_STATUS_TIMEOUT) {
|
||||
|
||||
|
@ -1084,7 +1084,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
|
|||
tech_pvt->last_ts = 0;
|
||||
|
||||
/* inform them of the codec they are actually sending */
|
||||
|
||||
#if 0
|
||||
if (++tech_pvt->codec_reinvites > 2) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
|
||||
"Ok, some devices *cough* X-lite *cough*\n"
|
||||
|
@ -1093,7 +1093,10 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
|
|||
} else {
|
||||
sofia_glue_do_invite(session);
|
||||
}
|
||||
#endif
|
||||
|
||||
*frame = &silence_frame;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1332,6 +1335,60 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
|||
}
|
||||
}
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_JITTER_BUFFER:
|
||||
{
|
||||
if (switch_rtp_ready(tech_pvt->rtp_session)) {
|
||||
int len, maxlen = 0, qlen = 0, maxqlen = 50;
|
||||
|
||||
if (msg->string_arg) {
|
||||
char *p;
|
||||
const char *s;
|
||||
|
||||
if (!strncasecmp(msg->string_arg, "debug:", 6)) {
|
||||
s = msg->string_arg + 6;
|
||||
if (s && !strcmp(s, "off")) {
|
||||
s = NULL;
|
||||
}
|
||||
switch_rtp_debug_jitter_buffer(tech_pvt->rtp_session, s);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
if ((len = atoi(msg->string_arg))) {
|
||||
qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000);
|
||||
}
|
||||
|
||||
if (qlen) {
|
||||
if ((p = strchr(msg->string_arg, ':'))) {
|
||||
p++;
|
||||
maxlen = atol(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (maxlen) {
|
||||
maxqlen = maxlen / (tech_pvt->read_impl.microseconds_per_packet / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
if (qlen) {
|
||||
if (switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen, maxqlen,
|
||||
tech_pvt->read_impl.samples_per_packet,
|
||||
tech_pvt->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session),
|
||||
SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames) (%d max frames)\n", len, qlen, maxqlen);
|
||||
switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session),
|
||||
SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", len, qlen);
|
||||
}
|
||||
|
||||
} else {
|
||||
switch_rtp_deactivate_jitter_buffer(tech_pvt->rtp_session);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_DEBUG_AUDIO:
|
||||
{
|
||||
if (switch_rtp_ready(tech_pvt->rtp_session) && !zstr(msg->string_array_arg[0]) && !zstr(msg->string_array_arg[1])) {
|
||||
|
@ -1629,7 +1686,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
|||
sofia_glue_tech_set_local_sdp(tech_pvt, NULL, SWITCH_FALSE);
|
||||
|
||||
if (!(switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_test_flag(channel, CF_EARLY_MEDIA))) {
|
||||
if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
|
||||
|
||||
tech_pvt->num_codecs = 0;
|
||||
|
@ -2144,7 +2201,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
|||
} else {
|
||||
if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || !tech_pvt->iananame) {
|
||||
sofia_clear_flag_locked(tech_pvt, TFLAG_LATE_NEGOTIATION);
|
||||
if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
|
||||
|
||||
tech_pvt->num_codecs = 0;
|
||||
|
|
|
@ -225,6 +225,7 @@ typedef enum {
|
|||
PFLAG_DEL_SUBS_ON_REG,
|
||||
PFLAG_IGNORE_183NOSDP,
|
||||
PFLAG_PRESENCE_PROBE_ON_REGISTER,
|
||||
PFLAG_NO_CONNECTION_REUSE,
|
||||
/* No new flags below this line */
|
||||
PFLAG_MAX
|
||||
} PFLAGS;
|
||||
|
|
|
@ -357,7 +357,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
switch_channel_answer(channel);
|
||||
switch_channel_set_variable(channel, "auto_answer_destination", switch_channel_get_variable(channel, "destination_number"));
|
||||
switch_ivr_session_transfer(session, "auto_answer", NULL, NULL);
|
||||
|
@ -1486,6 +1486,8 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
|
|||
TAG_IF(profile->timer_t2, NTATAG_SIP_T2(profile->timer_t2)),
|
||||
TAG_IF(profile->timer_t4, NTATAG_SIP_T4(profile->timer_t4)),
|
||||
SIPTAG_ACCEPT_STR("application/sdp, multipart/mixed"),
|
||||
TAG_IF(sofia_test_pflag(profile, PFLAG_NO_CONNECTION_REUSE),
|
||||
TPTAG_REUSE(0)),
|
||||
TAG_END()); /* Last tag should always finish the sequence */
|
||||
|
||||
if (!profile->nua) {
|
||||
|
@ -1715,16 +1717,9 @@ void launch_sofia_profile_thread(sofia_profile_t *profile)
|
|||
|
||||
static void logger(void *logarg, char const *fmt, va_list ap)
|
||||
{
|
||||
/* gcc 4.4 gets mad at us for testing if (ap) so let's try to work around it....*/
|
||||
void *ap_ptr = (void *) (intptr_t) ap;
|
||||
|
||||
if (!fmt) return;
|
||||
|
||||
if (ap_ptr) {
|
||||
switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, fmt, ap);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, "%s", fmt);
|
||||
}
|
||||
switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, fmt, ap);
|
||||
}
|
||||
|
||||
static su_log_t *sofia_get_logger(const char *name)
|
||||
|
@ -3673,6 +3668,13 @@ switch_status_t config_sofia(int reload, char *profile_name)
|
|||
} else {
|
||||
profile->timer_t4 = 4000;
|
||||
}
|
||||
} else if (!strcasecmp(var, "reuse-connections")) {
|
||||
switch_bool_t value = switch_true(val);
|
||||
if (!value) {
|
||||
sofia_set_pflag(profile, PFLAG_NO_CONNECTION_REUSE);
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_NO_CONNECTION_REUSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4112,7 +4114,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
|
|||
|
||||
}
|
||||
|
||||
if (channel && sip && (status == 300 || status == 301 || status == 302 || status == 305) && switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (channel && sip && (status == 300 || status == 301 || status == 302 || status == 305) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
sip_contact_t *p_contact = sip->sip_contact;
|
||||
int i = 0;
|
||||
char var_name[80];
|
||||
|
@ -4643,7 +4645,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
|||
status = 183;
|
||||
}
|
||||
|
||||
if (channel && (status == 180 || status == 183) && switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
if (channel && (status == 180 || status == 183) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
const char *val;
|
||||
if ((val = switch_channel_get_variable(channel, "sip_auto_answer")) && switch_true(val)) {
|
||||
nua_notify(nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR("talk"), TAG_END());
|
||||
|
@ -4690,7 +4692,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
|||
|
||||
if (r_sdp) {
|
||||
if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
|
||||
if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && !switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA");
|
||||
}
|
||||
sofia_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA);
|
||||
|
@ -4713,7 +4715,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
|||
}
|
||||
goto done;
|
||||
} else {
|
||||
if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) && !switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
|
||||
if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "DELAYED NEGOTIATION");
|
||||
} else {
|
||||
if (sofia_glue_tech_media(tech_pvt, (char *) r_sdp) != SWITCH_STATUS_SUCCESS) {
|
||||
|
@ -4908,7 +4910,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
|||
sofia_glue_tech_set_local_sdp(tech_pvt, NULL, SWITCH_FALSE);
|
||||
|
||||
if (!switch_channel_media_ready(channel)) {
|
||||
if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) {
|
||||
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
//const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
|
||||
|
||||
tech_pvt->num_codecs = 0;
|
||||
|
@ -6253,7 +6255,8 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
|
|||
|
||||
if (!is_nat && profile->nat_acl_count) {
|
||||
uint32_t x = 0;
|
||||
int ok = 1;
|
||||
int contact_private_ip = 1;
|
||||
int network_private_ip = 0;
|
||||
char *last_acl = NULL;
|
||||
const char *contact_host = NULL;
|
||||
|
||||
|
@ -6262,14 +6265,37 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
|
|||
}
|
||||
|
||||
if (!zstr(contact_host)) {
|
||||
/* NAT mode double check logic and examples.
|
||||
|
||||
Example 1: the contact_host is 192.168.1.100 and the network_ip is also 192.168.1.100 the end point
|
||||
is most likely behind nat with us so we need to veto that decision to turn on nat processing.
|
||||
|
||||
Example 2: the contact_host is 192.168.1.100 and the network_ip is 192.0.2.100 which is a public internet ip
|
||||
the remote endpoint is likely behind a remote nat traversing the public internet.
|
||||
|
||||
This secondary check is here to double check the conclusion of nat settigs to ensure we don't set net
|
||||
in cases where we don't really need to be doing this.
|
||||
|
||||
Why would you want to do this? Well if your FreeSWITCH is behind nat and you want to talk to endpoints behind
|
||||
remote NAT over the public internet in addition to endpoints behind nat with you. This simplifies that process.
|
||||
|
||||
*/
|
||||
|
||||
for (x = 0; x < profile->nat_acl_count; x++) {
|
||||
last_acl = profile->nat_acl[x];
|
||||
if (!(ok = switch_check_network_list_ip(contact_host, last_acl))) {
|
||||
if ((contact_private_ip = switch_check_network_list_ip(contact_host, last_acl))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (contact_private_ip) {
|
||||
for (x = 0; x < profile->nat_acl_count; x++) {
|
||||
if ((network_private_ip = switch_check_network_list_ip(network_ip, profile->nat_acl[x]))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
if (contact_private_ip && !network_private_ip) {
|
||||
is_nat = last_acl;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2342,7 +2342,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
|
|||
nua_invite(tech_pvt->nh,
|
||||
NUTAG_AUTOANSWER(0),
|
||||
NUTAG_SESSION_TIMER(session_timeout),
|
||||
TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
|
||||
NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
|
||||
TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)),
|
||||
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
|
||||
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
|
||||
|
@ -2669,7 +2669,8 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
|
|||
tech_pvt->rm_encoding,
|
||||
tech_pvt->codec_ms,
|
||||
tech_pvt->rm_rate);
|
||||
|
||||
|
||||
switch_yield(tech_pvt->read_impl.microseconds_per_packet);
|
||||
switch_core_session_lock_codec_write(tech_pvt->session);
|
||||
switch_core_session_lock_codec_read(tech_pvt->session);
|
||||
resetting = 1;
|
||||
|
@ -3153,18 +3154,37 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
|
|||
|
||||
if ((val = switch_channel_get_variable(tech_pvt->channel, "jitterbuffer_msec"))) {
|
||||
int len = atoi(val);
|
||||
int maxlen = 0;
|
||||
char *p;
|
||||
|
||||
if (len < 100 || len > 1000) {
|
||||
if ((p = strchr(val, ':'))) {
|
||||
p++;
|
||||
maxlen = atoi(p);
|
||||
}
|
||||
|
||||
if (len < 20 || len > 10000) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR,
|
||||
"Invalid Jitterbuffer spec [%d] must be between 100 and 1000\n", len);
|
||||
"Invalid Jitterbuffer spec [%d] must be between 20 and 10000\n", len);
|
||||
} else {
|
||||
int qlen;
|
||||
|
||||
int qlen, maxqlen = 50;
|
||||
|
||||
qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", len,
|
||||
qlen);
|
||||
switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen);
|
||||
if (maxlen) {
|
||||
maxqlen = maxlen / (tech_pvt->read_impl.microseconds_per_packet / 1000);
|
||||
}
|
||||
|
||||
if (switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen, maxqlen,
|
||||
tech_pvt->read_impl.samples_per_packet,
|
||||
tech_pvt->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session),
|
||||
SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", len, qlen);
|
||||
switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session),
|
||||
SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", len, qlen);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4668,8 +4688,8 @@ void sofia_glue_pass_sdp(private_object_t *tech_pvt, char *sdp)
|
|||
switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, sdp);
|
||||
|
||||
if (!sofia_test_flag(tech_pvt, TFLAG_CHANGE_MEDIA) && !sofia_test_flag(tech_pvt, TFLAG_RECOVERING) &&
|
||||
(switch_channel_test_flag(other_channel, CF_OUTBOUND) &&
|
||||
switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND) && switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE))) {
|
||||
(switch_channel_direction(other_channel) == SWITCH_CALL_DIRECTION_OUTBOUND &&
|
||||
switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_OUTBOUND && switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE))) {
|
||||
switch_ivr_nomedia(val, SMF_FORCE);
|
||||
sofia_set_flag_locked(tech_pvt, TFLAG_CHANGE_MEDIA);
|
||||
}
|
||||
|
@ -5041,9 +5061,20 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName
|
|||
const char *port = switch_channel_get_variable(channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
|
||||
const char *r_ip = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE);
|
||||
const char *r_port = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE);
|
||||
const char *use_uuid;
|
||||
|
||||
sofia_set_flag(tech_pvt, TFLAG_RECOVERING);
|
||||
|
||||
if ((use_uuid = switch_channel_get_variable(channel, "origination_uuid"))) {
|
||||
if (switch_core_session_set_uuid(session, use_uuid) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(channel),
|
||||
use_uuid);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n",
|
||||
switch_channel_get_name(channel), use_uuid);
|
||||
}
|
||||
}
|
||||
|
||||
if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && ip && port) {
|
||||
const char *tmp;
|
||||
tech_pvt->iananame = tech_pvt->rm_encoding = (char *) switch_channel_get_variable(channel, "sip_use_codec_name");
|
||||
|
|
|
@ -90,6 +90,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
|
|||
char *user_via = NULL;
|
||||
char *contact_str = NULL;
|
||||
char *dup_dest = NULL;
|
||||
char *remote_host = NULL;
|
||||
|
||||
if (!to) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing To: header.\n");
|
||||
|
@ -185,11 +186,9 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
|
|||
|
||||
/* sofia_glue is running sofia_overcome_sip_uri_weakness we do not, not sure if it matters */
|
||||
|
||||
remote_ip = malloc(sizeof(80));
|
||||
dup_dest = strdup(dst->contact);
|
||||
|
||||
if (switch_stristr("fs_path", dst->contact)) {
|
||||
char *remote_host = NULL;
|
||||
const char *s;
|
||||
|
||||
if ((s = switch_stristr("fs_path=", dst->contact))) {
|
||||
|
@ -202,7 +201,6 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
|
|||
if (!zstr(remote_host)) {
|
||||
switch_split_user_domain(remote_host, NULL, &remote_ip);
|
||||
}
|
||||
switch_safe_free(remote_host);
|
||||
}
|
||||
|
||||
if (zstr(remote_ip)) {
|
||||
|
@ -236,7 +234,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
|
|||
}
|
||||
|
||||
switch_safe_free(dup_dest);
|
||||
free(remote_ip);
|
||||
switch_safe_free(remote_host);
|
||||
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
|
@ -820,7 +818,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
|||
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_dialog_callback, &dh);
|
||||
switch_safe_free(sql);
|
||||
|
||||
if ((sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
|
||||
if ((sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
|
||||
"sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
|
||||
"sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
|
||||
"sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue