mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-04 19:31:56 +00:00
Merge branch 'master' into netborder
Conflicts: libs/freetdm/src/ftdm_io.c libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c libs/freetdm/src/include/freetdm.h
This commit is contained in:
@@ -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}
|
||||
@@ -1641,6 +1642,7 @@ Global
|
||||
{D5D2BF72-29FE-4982-A9FA-82AB2086DB1B}.All|Win32.Build.0 = Release|Win32
|
||||
{D5D2BF72-29FE-4982-A9FA-82AB2086DB1B}.All|x64.ActiveCfg = Release|Win32
|
||||
{D5D2BF72-29FE-4982-A9FA-82AB2086DB1B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{D5D2BF72-29FE-4982-A9FA-82AB2086DB1B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{D5D2BF72-29FE-4982-A9FA-82AB2086DB1B}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{D5D2BF72-29FE-4982-A9FA-82AB2086DB1B}.Debug|x64.Build.0 = Debug|Win32
|
||||
{D5D2BF72-29FE-4982-A9FA-82AB2086DB1B}.Release|Win32.ActiveCfg = Release|Win32
|
||||
@@ -2046,6 +2048,7 @@ Global
|
||||
{B808178B-82F0-4CF4-A2B1-921939FA24D0}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B808178B-82F0-4CF4-A2B1-921939FA24D0}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{B808178B-82F0-4CF4-A2B1-921939FA24D0}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B808178B-82F0-4CF4-A2B1-921939FA24D0}.Release|Win32.Build.0 = Release|Win32
|
||||
{B808178B-82F0-4CF4-A2B1-921939FA24D0}.Release|x64.ActiveCfg = Release|Win32
|
||||
{9778F1C0-09BC-4698-8EBC-BD982247209A}.All|Win32.ActiveCfg = Release|Win32
|
||||
{9778F1C0-09BC-4698-8EBC-BD982247209A}.All|x64.ActiveCfg = Release|x64
|
||||
|
||||
@@ -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}
|
||||
|
||||
+4
-2
@@ -276,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
|
||||
|
||||
@@ -304,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
|
||||
|
||||
|
||||
@@ -73,6 +73,8 @@ endpoints/mod_loopback
|
||||
#event_handlers/mod_event_multicast
|
||||
event_handlers/mod_event_socket
|
||||
event_handlers/mod_cdr_csv
|
||||
event_handlers/mod_cdr_sqlite
|
||||
#event_handlers/mod_cdr_pg_csv
|
||||
#event_handlers/mod_radius_cdr
|
||||
#event_handlers/mod_erlang_event
|
||||
formats/mod_native_file
|
||||
@@ -100,6 +102,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
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
<configuration name="cdr_pg_csv.conf" description="CDR PG CSV Format">
|
||||
<settings>
|
||||
<!-- Log a-leg (a), b-leg (b) or both (ab) -->
|
||||
<param name="legs" value="a"/>
|
||||
<!-- See parameters for PQconnectdb() at http://www.postgresql.org/docs/8.4/static/libpq-connect.html -->
|
||||
<param name="db-info" value="host=localhost dbname=cdr connect_timeout=10" />
|
||||
<!-- CDR table name -->
|
||||
<!--<param name="db-table" value="cdr"/>-->
|
||||
<param name="default-template" value="example"/>
|
||||
<!-- 'cdr-pg-csv' will always be appended to log-base -->
|
||||
<!--<param name="log-base" value="/var/log"/>-->
|
||||
<param name="default-template" value="example"/>
|
||||
<!-- Disk spool format if DB connection/insert fails - csv (default) or sql -->
|
||||
<param name="spool-format" value="csv"/>
|
||||
<param name="rotate-on-hup" value="true"/>
|
||||
<!-- This is like the info app but after the call is hung up -->
|
||||
<!--<param name="debug" value="true"/>-->
|
||||
<param name="rotate-on-hup" value="true"/>
|
||||
<!-- may be a b or ab -->
|
||||
<param name="legs" value="a"/>
|
||||
<param name="debug" value="true"/>
|
||||
<!-- The parameters for pqconnectdb(), see there -->
|
||||
<param name="db-info" value="host=localhost dbname=cdr connect_timeout=10" />
|
||||
</settings>
|
||||
<templates>
|
||||
<template name="sql">INSERT INTO cdr VALUES ("${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}", "${accountcode}");</template>
|
||||
<template name="example">"${local_ip_v4}","${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}","${accountcode}","${read_codec}","${write_codec}","${sip_hangup_disposition}","${ani}"</template>
|
||||
<template name="snom">"${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}", "${accountcode}","${read_codec}","${write_codec}","${sip_user_agent}","${call_clientcode}","${sip_rtp_rxstat}","${sip_rtp_txstat}","${sofia_record_file}"</template>
|
||||
<template name="linksys">"${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}","${accountcode}","${read_codec}","${write_codec}","${sip_user_agent}","${sip_p_rtp_stat}"</template>
|
||||
<template name="asterisk">"${accountcode}","${caller_id_number}","${destination_number}","${context}","${caller_id}","${channel_name}","${bridge_channel}","${last_app}","${last_arg}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${amaflags}","${uuid}","${userfield}"</template>
|
||||
</templates>
|
||||
</configuration>
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<configuration name="cdr_sqlite.conf" description="SQLite CDR">
|
||||
<settings>
|
||||
<!-- SQLite database name (.db suffix will be automatically appended) -->
|
||||
<!-- <param name="db-name" value="cdr"/> -->
|
||||
<!-- CDR table name -->
|
||||
<!-- <param name="db-table" value="cdr"/> -->
|
||||
<!-- Log a-leg (a), b-leg (b) or both (ab) -->
|
||||
<param name="legs" value="a"/>
|
||||
<!-- Default template to use when inserting records -->
|
||||
<param name="default-template" value="example"/>
|
||||
<!-- This is like the info app but after the call is hung up -->
|
||||
<!--<param name="debug" value="true"/>-->
|
||||
</settings>
|
||||
<templates>
|
||||
<!-- Note that field order must match SQL table schema, otherwise insert will fail -->
|
||||
<template name="example">"${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}",${duration},${billsec},"${hangup_cause}","${uuid}","${bleg_uuid}","${accountcode}"</template>
|
||||
</templates>
|
||||
</configuration>
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
<!-- Event Handlers -->
|
||||
<load module="mod_cdr_csv"/>
|
||||
<!-- <load module="mod_cdr_sqlite"/> -->
|
||||
<!-- <load module="mod_event_multicast"/> -->
|
||||
<load module="mod_event_socket"/>
|
||||
<!-- <load module="mod_zeroconf"/> -->
|
||||
|
||||
@@ -23,7 +23,13 @@
|
||||
<settings>
|
||||
<!--Colorize the Console -->
|
||||
<param name="colorize-console" value="true"/>
|
||||
<!--Most channels to allow at once -->
|
||||
<!--
|
||||
Max number of sessions to allow at any given time.
|
||||
|
||||
NOTICE: If you're driving 28 T1's in a single box you should set this to 644*2 or 1288
|
||||
this will ensure you're able to use the entire DS3 without a problem. Otherwise you'll
|
||||
be 144 channels short of always filling that DS3 up which can translate into waste.
|
||||
-->
|
||||
<param name="max-sessions" value="1000"/>
|
||||
<!--Most channels to create per second -->
|
||||
<param name="sessions-per-second" value="30"/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<include>
|
||||
<user id="default"> <!--if id is numeric mailbox param is not necessary-->
|
||||
<!--
|
||||
ATTENTION PLEASE READ THIS... (I know you won't but you've been warrned)
|
||||
ATTENTION PLEASE READ THIS... (I know you won't but you've been warned)
|
||||
|
||||
Let it be known that this user can register without a password but since we do not assign
|
||||
this user a user_context and we don't authenticate this user they will be put in context 'public'.
|
||||
|
||||
@@ -37,6 +37,7 @@ Content-Transfer-Encoding: 7bit
|
||||
Created: ${voicemail_time}<br>
|
||||
Duration: ${voicemail_message_len}<br>
|
||||
Account: ${voicemail_account}@${voicemail_domain}<br>
|
||||
</font>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -204,6 +204,9 @@
|
||||
<X-PRE-PROCESS cmd="set" data="fr-ring=%(1500,3500,440.0,0.0)"/>
|
||||
<X-PRE-PROCESS cmd="set" data="rs-ring=%(1000,4000,425.0,0.0)"/>
|
||||
<X-PRE-PROCESS cmd="set" data="ru-ring=%(800,3200,425,0)"/>
|
||||
<X-PRE-PROCESS cmd="set" data="de-ring=%(1000,4000,425,0)"/>
|
||||
<X-PRE-PROCESS cmd="set" data="dz-ring=%(1500,3500,425.0,0.0)"/>
|
||||
<X-PRE-PROCESS cmd="set" data="pl-ring=%(1000,4000,425,0)"/>
|
||||
<X-PRE-PROCESS cmd="set" data="bong-ring=v=-7;%(100,0,941.0,1477.0);v=-7;>=2;+=.1;%(1400,0,350,440)"/>
|
||||
<X-PRE-PROCESS cmd="set" data="sit=%(274,0,913.8);%(274,0,1370.6);%(380,0,1776.7)"/>
|
||||
<!--
|
||||
|
||||
@@ -37,6 +37,7 @@ Content-Transfer-Encoding: 7bit
|
||||
Created: ${voicemail_time}<br>
|
||||
Duration: ${voicemail_message_len}<br>
|
||||
Account: ${voicemail_account}@${voicemail_domain}<br>
|
||||
</font>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -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
|
||||
|
||||
Vendored
+6
@@ -1,3 +1,9 @@
|
||||
freeswitch (1.0.head~git.master.20101222.1-1) unstable; urgency=low
|
||||
|
||||
* cleaning work
|
||||
|
||||
-- Michal Bielicki <michal.bielicki@seventhsignal.de> Wed, 22 Dec 2010 22:48:02 +0200
|
||||
|
||||
freeswitch (1.0.head~git.master.20101015.1-1) unstable; urgency=low
|
||||
|
||||
* reintroduced mod_flite
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
freeswitch-sounds-en-us-callie (1.0.head-git.master,20101014.1-1) unstable; urgency=low
|
||||
freeswitch-sounds-en-us-callie (1.0.14~git.master.20101222.1-1) unstable; urgency=low
|
||||
|
||||
* Change upstream package version numbering scheme for unreleased versions:
|
||||
new format is major.minor.micro~git.branch.date.commits-1
|
||||
* Bumped up to 1.0.14 version
|
||||
* Clean ups
|
||||
|
||||
-- Michal Bielicki <michal.bielicki@seventhsignal.de> Wed, 22 Dec 2010 22:55:02 +0200
|
||||
|
||||
freeswitch-sounds-en-us-callie (1.0.head~git.master.20101014.1-1) unstable; urgency=low
|
||||
|
||||
* Change upstream package version numbering scheme for unreleased versions: new format is major.minor.micro~git.branch.date.commits-1
|
||||
* Change source format to 3.0 (quilt).
|
||||
* Upgrade debhelper compatibility to version 7.
|
||||
|
||||
-- Michal Bielicki <michal.bielicki@seventhsignal.de> Fr, 14 Oct 2010 05:05:02 +0200
|
||||
-- Michal Bielicki <michal.bielicki@seventhsignal.de> Fri, 14 Oct 2010 05:05:02 +0200
|
||||
|
||||
freeswitch-sounds-en-us-callie (1.0.12-0ubuntu1) jaunty; urgency=low
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
freeswitch-sounds-en-us-callie-8000_1.0.12-0ubuntu1_all.deb net extra
|
||||
freeswitch-sounds-en-us-callie-16000_1.0.12-0ubuntu1_all.deb net extra
|
||||
freeswitch-sounds-en-us-callie-32000_1.0.12-0ubuntu1_all.deb net extra
|
||||
freeswitch-sounds-en-us-callie-48000_1.0.12-0ubuntu1_all.deb net extra
|
||||
freeswitch-sounds-en-us-callie_1.0.12-0ubuntu1_all.deb net extra
|
||||
freeswitch-sounds-en-us-callie-omega_1.0.12-0ubuntu1_all.deb net extra
|
||||
+7
-1
@@ -1,3 +1,9 @@
|
||||
freeswitch-sounds-music (1.0.8~git.master.20101222.1-1) unstable; urgency=low
|
||||
|
||||
* Clean ups
|
||||
|
||||
-- Michal Bielicki <michal.bielicki@seventhsignal.de> Wed, 22 Dec 2010 22:55:02 +0200
|
||||
|
||||
freeswitch-sounds-music (1.0.head-git.master,20101014.1-1) unstable; urgency=low
|
||||
|
||||
* Change upstream package version numbering scheme for unreleased versions:
|
||||
@@ -5,7 +11,7 @@ freeswitch-sounds-music (1.0.head-git.master,20101014.1-1) unstable; urgency=low
|
||||
* Change source format to 3.0 (quilt).
|
||||
* Upgrade debhelper compatibility to version 7.
|
||||
|
||||
-- Michal Bielicki <michal.bielicki@seventhsignal.de> Fr, 14 Oct 2010 05:05:02 +0200
|
||||
-- Michal Bielicki <michal.bielicki@seventhsignal.de> Fri, 14 Oct 2010 05:05:02 +0200
|
||||
|
||||
freeswitch-sounds-music (1.0.8-0ubuntu3) jaunty; urgency=low
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
freeswitch-sounds-music-8000_1.0.8-0ubuntu3_all.deb net extra
|
||||
freeswitch-sounds-music-16000_1.0.8-0ubuntu3_all.deb net extra
|
||||
freeswitch-sounds-music-32000_1.0.8-0ubuntu3_all.deb net extra
|
||||
freeswitch-sounds-music-48000_1.0.8-0ubuntu3_all.deb net extra
|
||||
freeswitch-sounds-music_1.0.8-0ubuntu3_all.deb net extra
|
||||
freeswitch-sounds-music-omega_1.0.8-0ubuntu3_all.deb net extra
|
||||
@@ -1,3 +1,9 @@
|
||||
freeswitch-sounds-ru-ru-elena (1.0.8~git.master.20101222.1-1) unstable; urgency=low
|
||||
|
||||
* Clean ups
|
||||
|
||||
-- Michal Bielicki <michal.bielicki@seventhsignal.de> Wed, 22 Dec 2010 22:55:02 +0200
|
||||
|
||||
freeswitch-sounds-ru-ru-elena (1.0.head-git.master,20101014.1-1) unstable; urgency=low
|
||||
|
||||
* Change upstream package version numbering scheme for unreleased versions:
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
freeswitch-sounds-ru-ru-elena-8000_1.0.12-0ubuntu3_all.deb net extra
|
||||
freeswitch-sounds-ru-ru-elena-16000_1.0.12-0ubuntu3_all.deb net extra
|
||||
freeswitch-sounds-ru-ru-elena-32000_1.0.12-0ubuntu3_all.deb net extra
|
||||
freeswitch-sounds-ru-ru-elena-48000_1.0.12-0ubuntu3_all.deb net extra
|
||||
freeswitch-sounds-ru-ru-elena_1.0.12-0ubuntu3_all.deb net extra
|
||||
freeswitch-sounds-ru-ru-elena-omega_1.0.12-0ubuntu3_all.deb net extra
|
||||
Vendored
+2
-2
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
sounds_en_us_callie="freeswitch-sounds-en-us-callie-48000-1.0.12.tar.gz"
|
||||
sounds_en_us_callie="freeswitch-sounds-en-us-callie-48000-1.0.14.tar.gz"
|
||||
sounds_music="freeswitch-sounds-music-48000-1.0.8.tar.gz"
|
||||
sounds_ru_RU_elena="freeswitch-sounds-ru-RU-elena-48000-1.0.12.tar.gz"
|
||||
|
||||
@@ -27,4 +27,4 @@ if [ ! -f $sounds_ru_RU_elena ]
|
||||
wget http://files.freeswitch.org/$sounds_ru_RU_elena
|
||||
fi
|
||||
tar zxvf $sounds_ru_RU_elena
|
||||
cd ..
|
||||
cd ..
|
||||
|
||||
+50
-1
@@ -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
|
||||
@@ -33,6 +34,7 @@ freeswitch (1.0.7)
|
||||
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
|
||||
@@ -78,7 +80,6 @@ freeswitch (1.0.7)
|
||||
core: change channel app_flags to be realm specific and default old version to use __FILE__ as the realm name to avoid cross fire between apps using app flags (r:09c1815c)
|
||||
core: preanswer before getting variables to avoid crash (r:25fe16df)
|
||||
core: Windows: Don't report "unknown command" on console when empty command has been given (r:c8f9fb56/FSCORE-641)
|
||||
embedded languages: Provide core level support for conditional Set Global Variable (r:c017c24b/FSCORE-612)
|
||||
core: Windows: Add start parameter -monotonic-clock, replaces build flag WIN32_MONOTONIC (r:3515c7a0/FSCORE-643)
|
||||
core: Improve RTP timing on playback of files (r:d6d7773c/FSCORE-639)
|
||||
core: Allows bind_meta_app to use chars other than * (r:fd254766/FSCORE-630)
|
||||
@@ -145,7 +146,28 @@ freeswitch (1.0.7)
|
||||
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)
|
||||
core: cid logic changes for calle[re] (r:8f452bc5)
|
||||
core: change switch_strip_spaces to specify if you want it to dup the string or destroy the current buffer (r:4d7e4f1e)
|
||||
core: fix secondary issue with min_digits = 0 and terminator key pressed to cancel (r:fe005bdd/FS-2789)
|
||||
core: fix dtmf issue with jb on (r:90e58696)
|
||||
core: fix ignore_early_media=ring_ready (r:5b752c54)
|
||||
core: prevent race on execute_on_answer called from the B-leg of a call (r:751e0291)
|
||||
core: drop rtp frame that was already replaced with a cng frame (r:34a0ca50)
|
||||
core: fix partial match counting as exact match in dmachine (r:5eb951aa)
|
||||
core: try to adjust the timer to be ok with the horrible 10000 microsecond kernel resolution on amazon ec3 but that doesn't mean it's not horribly wrong to run the kernel that slow (r:903b2901)
|
||||
embedded languages: Provide core level support for conditional Set Global Variable (r:c017c24b/FSCORE-612)
|
||||
embedded languages: add insertFile front end to switch_ivr_insert_file and reswig (r:c4e350ab)
|
||||
lang: Improve French phrase files (FSCONFIG-23)
|
||||
lang: Update langs - Add pt_PT, update es to have es_ES and es_MX, update mod_say_es and add mod_say_pt (FS-2937) (r:c81a9448/FS-2937)
|
||||
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)
|
||||
libdingaling: Fix crash in new GV interface when exceeding 24 calls (r:be00609a/FS-2171)
|
||||
@@ -163,9 +185,13 @@ freeswitch (1.0.7)
|
||||
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)
|
||||
libesl: Noevent/Noevents disparity (r:d29d83d7/ESL-53)
|
||||
libfreetdm: implemented freetdm config nodes and ss7 initial configuration
|
||||
libfreetdm: fix codec for CAS signaling (r:b76e7f18)
|
||||
libfreetdm: freetdm: ss7- added support for incoming group blocks, started adding support for ansi (r:c219a73c)
|
||||
libg7221: A bunch of tweaks to the G.722.1 codec (r:5d548570)
|
||||
libgnutls: link to libgcrypt as well, please report any platforms this breaks, but it should be portable (r:c569fb0f/FS-1248)
|
||||
libopenzap: Add CLI tracing
|
||||
libs: Merged OpenZAP and FreeTDM into the FreeSWITCH tree.
|
||||
@@ -203,6 +229,8 @@ freeswitch (1.0.7)
|
||||
mod_callcenter: Fix bad return type so it compile on archlinux, thx bougyman (r:3a475986)
|
||||
mod_callcenter: Make callcenter_config agent get return the value of the item requested. Also added queue param max-wait-time-with-no-agent-time-reached: If the max-wai-time-with-no-agent is already reached for the queue, then new caller can wait for x amount of second before it kicked out of the queue rather than get rejected automatically. (r:81a03869)
|
||||
mod_callcenter: Add new event socket agent-offering. Plus some documentation and better handling of bad agent type -- FS-2869 (r:80174cf3/FS-2869)
|
||||
mod_cdr_sqlite: initial commit (r:f625fe3b)
|
||||
mod_cdr_sqlite: config file for mod_cdr_sqlite (r:25bc8fe3)
|
||||
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
|
||||
@@ -220,6 +248,10 @@ freeswitch (1.0.7)
|
||||
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_commands: add uuid_buglist to fetch the current media-bugs attached to a given session uuid (r:f6eab64c)
|
||||
mod_commands: add recovery_refresh app and api and use it in mod_conference to send a message to the channel telling it to sync its recovery snapshot (r:650393fb)
|
||||
mod_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
|
||||
@@ -229,6 +261,10 @@ 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_conference: Add a chan var conference_enter_sound to override conference enter-sound param on the profile (r:651acc62)
|
||||
mod_conference: Add an unique id to the conference obj so that we can track conferences. (r:479f3de2)
|
||||
mod_conference: Fix corrupted audio when playing "you are now (un)muted..." (r:10257c7d/FS-2768)
|
||||
mod_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)
|
||||
@@ -264,6 +300,7 @@ freeswitch (1.0.7)
|
||||
mod_fifo: fix fifo race in use count dec (r:402e383b)
|
||||
mod_fifo: add outbound_ring_timeout param to mod_fifo (r:3885eea7)
|
||||
mod_fifo: add default_lag to fifo (r:dd4fb5be)
|
||||
mod_fifo: Fix crash when using fifo_destroy_after_use (r:ee562c82/FS-2879)
|
||||
mod_freetdm: Fix for TON and NPI not passed through to channel variables on incoming calls
|
||||
mod_freetdm: add pvt data to freetdm channels fix fxs features (r:9d456900)
|
||||
mod_freetdm: export and import boost custom data (r:edb2d582)
|
||||
@@ -341,6 +378,7 @@ freeswitch (1.0.7)
|
||||
mod_lua: Add switch_core_sqldb functionality from inside Lua script (r:26f2e095/FS-1384)
|
||||
mod_lua: Made 2nd arg to freeswitch.Dbh:query (cb func) optional (r:87db11af)
|
||||
mod_lua: Added SAF_ROUTING_EXEC flag to lua app, so it can be run inline (r:7d5ca1c0)
|
||||
mod_lua: spelling error in -ERR return code encounterd -> encountered (r:86e7cdc5/FS-2949)
|
||||
mod_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)
|
||||
@@ -401,6 +439,7 @@ freeswitch (1.0.7)
|
||||
mod_skypopen: making XEvents to works when EARLYMEDIA, and correctly manage threads death
|
||||
mod_skypopen: now answer a call only when directed to do it (before was trying to answer any incoming call). Lot of changes to a messy part, so maybe some problem will come out... (r:45c6c4d3)
|
||||
mod_skypopen: ignore early media sent by channels to be bridged before our channel is answered (r:ef14b78a)
|
||||
mod_snapshot: fix bad codepaths in mod_snapshot (r:844ac220)
|
||||
mod_sndfile: Add support for .alaw and .ulaw to mod_sndfile (r:facf09b8/MODFORM-41)
|
||||
mod_sndfile: return break in mod_sndfile when seek returns failure (r:564dc7e4)
|
||||
mod_sofia: Send SIP MESSAGE to unregistered users by prefixing sip: to user@domain
|
||||
@@ -500,6 +539,15 @@ freeswitch (1.0.7)
|
||||
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_sofia: prevent race on codec change mid-call (r:668763f4)
|
||||
mod_sofia: improve fail2ban logging (r:f4d52d4c/FS-2943)
|
||||
mod_sofia: refactor sofia_contact to try the profile_name first then the domain to resolve the profile then fall back to querying every profile to reduce confusion with multi-homers (d'oh) also special profile name * will force a search-all situation (r:81608da0)
|
||||
mod_sofia: support allowing pidf-ful presence clients to share the same account and 'appear offline' without influencing each other =/ also refactor the contact generation string based on nat into a helper function (r:97a68c50)
|
||||
mod_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)
|
||||
@@ -515,6 +563,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
|
||||
|
||||
+12
-23
@@ -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>
|
||||
+3
-1
@@ -379,7 +379,7 @@ ENDPOINTS_MODULES="endpoints/mod_dingaling endpoints/mod_loopback ../../libs/fre
|
||||
# Event Handlers
|
||||
#
|
||||
######################################################################################################################
|
||||
EVENT_HANDLERS_MODULES="event_handlers/mod_cdr_csv event_handlers/mod_event_socket event_handlers/mod_event_multicast"
|
||||
EVENT_HANDLERS_MODULES="event_handlers/mod_cdr_csv event_handlers/mod_cdr_sqlite event_handlers/mod_event_socket event_handlers/mod_event_multicast"
|
||||
######################################################################################################################
|
||||
#
|
||||
# File and Audio Format Handlers
|
||||
@@ -620,6 +620,7 @@ fi
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/callcenter.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_csv.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_pg_csv.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_sqlite.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cidlookup.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/conference.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/console.conf.xml
|
||||
@@ -746,6 +747,7 @@ fi
|
||||
%{prefix}/mod/mod_bv.so*
|
||||
%{prefix}/mod/mod_callcenter.so*
|
||||
%{prefix}/mod/mod_cdr_csv.so*
|
||||
%{prefix}/mod/mod_cdr_sqlite.so*
|
||||
%{prefix}/mod/mod_celt.so*
|
||||
%{prefix}/mod/mod_cidlookup.so*
|
||||
%{prefix}/mod/mod_cluechoo.so*
|
||||
|
||||
+3
-3
@@ -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
|
||||
|
||||
+2
-2
@@ -656,7 +656,7 @@ static int process_command(esl_handle_t *handle, const char *cmd)
|
||||
"-----------------------------------------------\n"
|
||||
"/help \tHelp\n"
|
||||
"/exit, /quit, /bye, ... \tExit the program.\n"
|
||||
"/event, /noevent, /nixevent\tEvent commands.\n"
|
||||
"/event, /noevents, /nixevent\tEvent commands.\n"
|
||||
"/log, /nolog \tLog commands.\n"
|
||||
"/uuid \tFilter logs for a single call uuid\n"
|
||||
"/filter \tFilter commands.\n"
|
||||
@@ -692,7 +692,7 @@ static int process_command(esl_handle_t *handle, const char *cmd)
|
||||
|
||||
} else if (
|
||||
!strncasecmp(cmd, "event", 5) ||
|
||||
!strncasecmp(cmd, "noevent", 7) ||
|
||||
!strncasecmp(cmd, "noevents", 8) ||
|
||||
!strncasecmp(cmd, "nixevent", 8) ||
|
||||
!strncasecmp(cmd, "log", 3) ||
|
||||
!strncasecmp(cmd, "nolog", 5) ||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ESL", "esl_lua.2008.vcproj", "{86B6AB99-A261-455A-9CD6-9142A5A1652E}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Debug|x64.Build.0 = Debug|x64
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Release|Win32.Build.0 = Release|Win32
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Release|x64.ActiveCfg = Release|x64
|
||||
{86B6AB99-A261-455A-9CD6-9142A5A1652E}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,351 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="ESL"
|
||||
ProjectGUID="{86B6AB99-A261-455A-9CD6-9142A5A1652E}"
|
||||
RootNamespace="esl_lua.2008"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="0"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\";"$(ProjectDir)..\src\include""
|
||||
PreprocessorDefinitions="ESL_DECLARE_STATIC;WIN32"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="esl.lib lua5.1.lib ws2_32.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""$(ProjectDir)..\..\..\$(ConfigurationName)";"$(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\$(ConfigurationName)""
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\";"$(ProjectDir)..\src\include""
|
||||
PreprocessorDefinitions="ESL_DECLARE_STATIC;WIN32"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="esl.lib lua5.1.lib ws2_32.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""$(ProjectDir)..\..\..\$(ConfigurationName)";"$(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\$(ConfigurationName)""
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\";"$(ProjectDir)..\src\include""
|
||||
PreprocessorDefinitions="ESL_DECLARE_STATIC;WIN32"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="esl.lib lua5.1.lib ws2_32.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""$(ProjectDir)..\..\..\$(PlatformName)\$(ConfigurationName)";"$(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\$(PlatformName)\$(ConfigurationName)""
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\";"$(ProjectDir)..\src\include""
|
||||
PreprocessorDefinitions="ESL_DECLARE_STATIC;WIN32"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="esl.lib lua5.1.lib ws2_32.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""$(ProjectDir)..\..\..\$(PlatformName)\$(ConfigurationName)";"$(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\$(PlatformName)\$(ConfigurationName)""
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\src\esl_oop.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\esl_wrap.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -40,7 +40,8 @@ sub set_callback($;$$) {
|
||||
$self->{_callback}->{$event} = shift;
|
||||
my $subclass = shift;
|
||||
if($subclass) {
|
||||
$self->{_custom_subclass} = split(/,/, $subclass);
|
||||
my @subclasses = split(/,/, $subclass);
|
||||
$self->{_custom_subclass} = \@subclasses;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +80,7 @@ sub run($;) {
|
||||
for(;;) {
|
||||
# Only register for events we have callbacks for.
|
||||
for my $key ( keys %{$self->{_callback}} ) {
|
||||
if ($key eq "CUSTOM") {
|
||||
if ($key =~ m/custom/i) {
|
||||
foreach $subclass (@{$self->{_custom_subclass}}) {
|
||||
$self->{_esl}->events("plain", "$key $subclass");
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
+86
-69
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
*/
|
||||
@@ -73,6 +73,7 @@ libfreetdm_la_SOURCES = \
|
||||
$(SRC)/hashtable.c \
|
||||
$(SRC)/hashtable_itr.c \
|
||||
$(SRC)/ftdm_io.c \
|
||||
$(SRC)/ftdm_state.c \
|
||||
$(SRC)/ftdm_queue.c \
|
||||
$(SRC)/ftdm_sched.c \
|
||||
$(SRC)/ftdm_call_utils.c \
|
||||
|
||||
@@ -12,31 +12,81 @@ with the signaling protocols that you can run on top of your I/O interfaces.
|
||||
<settings>
|
||||
<param name="debug" value="0"/>
|
||||
<!--<param name="hold-music" value="$${moh_uri}"/>-->
|
||||
<!-- Analog global options (they apply to all spans)
|
||||
Remember you can only choose between either call-swap
|
||||
or 3-way, not both!
|
||||
-->
|
||||
<!--<param name="enable-analog-option" value="call-swap"/>-->
|
||||
<!--<param name="enable-analog-option" value="3-way"/>-->
|
||||
</settings>
|
||||
|
||||
<!-- Sample analog configuration -->
|
||||
<!-- Sample analog configuration (The analog_spans tag is for ftmod_analog) -->
|
||||
<analog_spans>
|
||||
<!-- The span name must match the name in your freetdm.conf -->
|
||||
<span name="myAnalog">
|
||||
<!--<param name="hold-music" value="$${moh_uri}"/>-->
|
||||
<!--<param name="enable-analog-option" value="call-swap"/>-->
|
||||
<!--<param name="enable-analog-option" value="3-way"/>-->
|
||||
<!--
|
||||
3-way allows you to flash your FXS line and dial
|
||||
another number and put all the parties in a conference
|
||||
|
||||
call-swap allows you to flash your FXS line and swap
|
||||
between one call and another
|
||||
|
||||
Remember you can only choose between either call-swap
|
||||
or 3-way, not both!
|
||||
|
||||
<param name="enable-analog-option" value="call-swap"/>
|
||||
<param name="enable-analog-option" value="3-way"/>
|
||||
-->
|
||||
|
||||
<!-- Tones are defined in tones.conf
|
||||
This setting is very important for analog lines to
|
||||
work properly
|
||||
-->
|
||||
<param name="tonegroup" value="us"/>
|
||||
|
||||
<!-- How much time to wait for digits (in FXS lines) -->
|
||||
<param name="digit-timeout" value="2000"/>
|
||||
|
||||
<!-- Maximum number of digits to wait for (in FXS lines) -->
|
||||
<param name="max-digits" value="11"/>
|
||||
<param name="dialplan" value="XML"/>
|
||||
<param name="context" value="default"/>
|
||||
|
||||
<!-- whether you want to wait for caller id -->
|
||||
<param name="enable-callerid" value="true"/>
|
||||
|
||||
<!-- whether you want to enable callwaiting feature -->
|
||||
<!--<param name="callwaiting" value="true"/>-->
|
||||
|
||||
<!-- whether you want to answer/hangup on polarity reverse for outgoing calls in FXO devices
|
||||
and send polarity reverse on answer/hangup for incoming calls in FXS devices -->
|
||||
<!--<param name="answer-polarity-reverse" value="false"/>-->
|
||||
<!--<param name="hangup-polarity-reverse" value="false"/>-->
|
||||
<!--
|
||||
Minimum delay (in milliseconds) required between an answer polarity reverse
|
||||
and hangup polarity reverse in order to assume the second polarity reverse is a real hangup
|
||||
<param name="polarity-delay" value="600"/>
|
||||
-->
|
||||
|
||||
<!-- regex to stop dialing when it matches -->
|
||||
<!--<param name="dial-regex" value="5555"/>-->
|
||||
|
||||
<!-- regex to stop dialing when it does not match -->
|
||||
<!--<param name="fail-dial-regex" value="^5"/>-->
|
||||
|
||||
<!-- FreeSWITCH dialplan type and context to send the calls -->
|
||||
<param name="dialplan" value="XML"/>
|
||||
<param name="context" value="default"/>
|
||||
</span>
|
||||
</analog_spans>
|
||||
|
||||
<!-- openr2 (MFC-R2 signaling) spans
|
||||
<!--
|
||||
|
||||
openr2 (MFC-R2 signaling) spans (ftmod_r2)
|
||||
|
||||
In order to use this type of spans your FreeTDM must have been compiled with ftmod_r2 module.
|
||||
The module is compiled if the openr2 library is present when running the ./configure script
|
||||
in the FreeTDM source code
|
||||
|
||||
MFC-R2 signaling has lots of variants from country to country and even sometimes
|
||||
minor variants inside the same country. The only mandatory parameters here are:
|
||||
variant, but typically you also want to set max_ani and max_dnis.
|
||||
@@ -46,6 +96,7 @@ with the signaling protocols that you can run on top of your I/O interfaces.
|
||||
best defaults for your country. If you want to contribute your configs for a particular
|
||||
country send them to the e-mail of the primary OpenR2 developer that you can find in the
|
||||
AUTHORS file of the OpenR2 package, they will be added to the samples directory of openr2.
|
||||
|
||||
-->
|
||||
<r2_spans>
|
||||
<span name="wp1" cfgprofile="testr2">
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
;M3UA SS7 Links Config
|
||||
;
|
||||
;ss7box-m3ua_mode => true
|
||||
;local_sctp_ip => localhost
|
||||
;local sctp_port => 30000
|
||||
;remote_sctp_ip => localhost
|
||||
;remote_sctp_port => 30001
|
||||
;opc => 0-0-0
|
||||
;dpc => 0-0-0
|
||||
|
||||
|
||||
; AP Specific Stuff. This will likely move later.
|
||||
|
||||
; CNAM Gateways
|
||||
cnam1_dpc => 0-0-0
|
||||
cnam1_ssn => 253
|
||||
cnam2_dpc => 0-0-0
|
||||
cnam2_ssn => 253
|
||||
cnam3_dpc => 0-0-0
|
||||
cnam3_ssn => 253
|
||||
|
||||
;LNP Gateways
|
||||
lnp1_dpc => 0-0-0
|
||||
lnp1_ssn => 253
|
||||
lnp2_dpc => 0-0-0
|
||||
lnp2_ssn => 253
|
||||
lnp3_dpc => 0-0-0
|
||||
lnp3_ssn => 253
|
||||
|
||||
;LNP Gateways
|
||||
sms8001_dpc => 0-0-0
|
||||
sms8001_ssn => 253
|
||||
sms8002_dpc => 0-0-0
|
||||
sms8002_ssn => 253
|
||||
sms8003_dpc => 0-0-0
|
||||
sms8003_ssn => 253
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ AC_ARG_WITH([pritap],
|
||||
[AS_HELP_STRING([--with-pritap], [Install ftmod_pritap])],
|
||||
[case "${withval}" in
|
||||
no) enable_pritap="no" ;;
|
||||
*) enable_pritab="yes" ;;
|
||||
*) enable_pritap="yes" ;;
|
||||
esac],
|
||||
[enable_pritap="no"]
|
||||
)
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
Last Updated: Fri 30 Dec, 2010
|
||||
|
||||
== Background ==
|
||||
|
||||
FreeTDM is a threaded library. As such, locking considerations must be taken when using it and when writing code inside the library.
|
||||
|
||||
At the moment locks are not exposed to users. This means API users cannot acquire a lock on a channel or span structure. There is no
|
||||
need for users to lock channels or spans since all their interactions with those structures should be done thru the FreeTDM API which
|
||||
can (and in most cases must) internally lock on their behalf.
|
||||
|
||||
Internally, locking can be done either by the core or the signaling modules. To better understand the locking considerations we must
|
||||
understand first the threading model of FreeTDM.
|
||||
|
||||
== Threading Model ==
|
||||
|
||||
At startup, when the user calls ftdm_global_init(), just one timing thread is created to dispatch internal timers. If you write
|
||||
a signaling module or any other code using the scheduling API, you can choose to run your schedule in this timing thread or in
|
||||
a thread of your choice. This is the only thread launched at initialization.
|
||||
|
||||
If the application decides to use ftdm_global_configuration(), which reads freetdm.conf to create the spans and channels data
|
||||
structures, then possibly another thread will be launched for CPU usage monitoring (only if enabled in the configuration cpu_monitor=yes
|
||||
This thread sole purpose is to check the CPU and raise an alarm if reaches a configurable threshold, the alarm then is checked to avoid
|
||||
placing or receiving further calls.
|
||||
|
||||
At this point FreeTDM has initialized and configured its channels input output configuration.
|
||||
|
||||
The user is then supposed to configure the signaling via ftdm_configure_span_signaling() and then start the signaling work
|
||||
using ftdm_span_start(). This will typically launch at least 1 thread per span. Some signaling modules (actually just the analog one)
|
||||
launches another thread per channel when receiving a call. The rest of the signaling modules currently launch only one thread per
|
||||
span and the signaling for all channels within the span is handled in that thread. We call that thread 'the signaling thread'.
|
||||
|
||||
At this point the user can start placing calls using the FreeTDM call API ftdm_channel_call_place(). Any of the possible threads in
|
||||
which the user calls the FreeTDM API is called 'the user thread', depending on the application thread model (the application using FreeTDM)
|
||||
this user thread may be different each time or the same all the time, we cannot make any assumptions. In the case of FreeSWITCH, the most
|
||||
common user of FreeTDM, the user thread is most of the cases a thread for each new call leg.
|
||||
|
||||
At this point we have identified 4 types of threads.
|
||||
|
||||
1. The timing thread (the core thread that triggers timers).
|
||||
Its responsibility is simply check for timers that were scheduled and trigger them when the time comes. This means that if you decide
|
||||
to use the scheduling API in freerun mode (where you use the core timer thread) you callbacks will be executed in this global thread
|
||||
and you MUST not block at all since there might be other events waiting.
|
||||
|
||||
2. The CPU thread (we don't really care about this one as it does not interact with channels or spans).
|
||||
|
||||
3. The signaling thread.
|
||||
There is one thread of this per span. This thread takes care of reading signaling specific messages from the network (ISDN network, etc) and
|
||||
changing the channel call state accordingly and processing state changes caused by user API calls (like ftdm_channel_call_hangup for example).
|
||||
|
||||
4. The user thread.
|
||||
This is a thread in which the user decides to execute FreeTDM APIs, in some cases it might even be the same than the signaling thread (because
|
||||
most SIGEVENT notifications are delivered by the signaling thread, however we are advicing users to not use FreeTDM unsafe APIs from the
|
||||
thread where they receive SIGEVENT notifications as some APIs may block for a few milliseconds, effectively blocking the whole signaling thread
|
||||
that is servicing a span.
|
||||
|
||||
== Application Locking ==
|
||||
|
||||
Users of the FreeTDM API will typically have locking of their own for their own application-specific data structures (in the case of FreeSWITCH, the
|
||||
session lock for example). Other application-specific locks may be involved.
|
||||
|
||||
== DeadLocks ==
|
||||
|
||||
As soon as we think of application locks, and we mix them with the FreeTDM internal locks, the possibility of deadlocks arise.
|
||||
|
||||
A typical deadlock scenario when 2 locks are involved is:
|
||||
|
||||
- User Thread - - Signaling Thread -
|
||||
1. Application locks applock. 1. A network message is received for a channel.
|
||||
|
||||
2. Aplication invokes a FreeTDM call API (ie: ftdm_channel_call_hangup()). 2. The involved channel is locked.
|
||||
|
||||
3. The FreeTDM API attempts to acquire the channel lock and stalls because 3. The message processing results in a notification
|
||||
the signaling thread just acquired it. to be delivered to the user via the callback function
|
||||
provided for that purpose. The callback is then called.
|
||||
|
||||
4. The thread is now deadlocked because the signaling thread will never 4. The application callback attempts to acquire its application
|
||||
release the channel lock. lock but deadlocks because the user thread already has it.
|
||||
|
||||
To avoid this signaling modules should not deliver signals to the user while holding the channel lock. An easy way to avoid this is
|
||||
to not deliver signals while processing a state change, but rather defer them until the channel lock is released. Most new signaling modules
|
||||
accomplish this by setting the span flag FTDM_SPAN_USE_SIGNALS_QUEUE, this flag tells the core to enqueue signals (ie FTDM_SIGEVENT_START)
|
||||
when ftdm_span_send_signal() is called and not deliver them until ftdm_span_trigger_signals() is called, which is done by the signaling module
|
||||
in its signaling thread when no channel lock is being held.
|
||||
|
||||
== State changes while locking ==
|
||||
|
||||
Only 2 types of threads should be performing state changes.
|
||||
|
||||
User threads.
|
||||
The user thread is a random thread that was crated by the API user. We do not know what threading model users of FreeTDM will follow
|
||||
and therefore cannot make assumptions about it. The user should be free to call FreeTDM APIs from any thread, except threads that
|
||||
are under our control, like the signaling threads. Although it may work in most situations, is discouraged for users to try
|
||||
to use FreeTDM APIs from the signaling thread, that is, the thread where the signaling callback provided during configuration
|
||||
is called (the callback where FTDM_SIGEVENT_XXX signals are delivered).
|
||||
|
||||
A user thread may request state changes implicitly through calls to FreeTDM API's. The idea of state changes is internal to freetdm
|
||||
and should not be exposed to users of the API (except for debugging purposes, like the ftdm_channel_get_state, ftdm_channel_get_state_str etc)
|
||||
|
||||
This is an example of the API's that implicitly request a state change.
|
||||
|
||||
ftdm_channel_call_answer()
|
||||
|
||||
Signaling modules should guarantee that upon releasing a lock on a channel, any state changes will be already processed and
|
||||
not deferred to other threads, otherwise that leads to a situation where a state change requested by the signaling module is pending
|
||||
to be serviced by another signaling module thread but a user thread wins the channel lock and attempts to perform a state change which will
|
||||
fail because another state change is pending (and user threads are not meant to process signaling states).
|
||||
|
||||
ONLY one signaling thread per channel should try to perform state changes and processing of the states,
|
||||
otherwise complexity arises and is not worth it!
|
||||
|
||||
At some point before we stablished this policies we could have 3 different threads doing state changes.
|
||||
|
||||
1. A user random thread could implcitly try to change the state in response to a call API.
|
||||
2. The ftmod signaling thread could try to change the state in response to other state changes.
|
||||
3. The lower level signaling stack threads could try to change the state in response to stack events.
|
||||
|
||||
As a result, lower level signaling stack thread could set a state and then let the signaling thread to
|
||||
process it, but when unlocking the channel, the user thread may win the lock over the signaling thread and
|
||||
may try to set a state change of its own and fail (due to the unprocessed state change)!
|
||||
|
||||
The rule is, the signaling module should never unlock a channel with states pending to process this way the user,
|
||||
when acquiring a channel lock (inside ftdm_channel_call_answer for example) it will always find a consistent state
|
||||
for the channel and not in the middle of state processing.
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>FreeSwitch.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>FreeSwitchCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
@@ -127,7 +127,7 @@
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>FreeSwitch.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>FreeSwitchCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
|
||||
@@ -421,16 +421,18 @@ static switch_status_t channel_on_routing(switch_core_session_t *session)
|
||||
private_t *tech_pvt = NULL;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
switch_assert(channel != NULL);
|
||||
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
switch_assert(tech_pvt != NULL);
|
||||
|
||||
assert(tech_pvt->ftdmchan != NULL);
|
||||
switch_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);
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||
ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROCEED);
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -441,10 +443,10 @@ static switch_status_t channel_on_execute(switch_core_session_t *session)
|
||||
private_t *tech_pvt = NULL;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
switch_assert(channel != NULL);
|
||||
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
switch_assert(tech_pvt != NULL);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel));
|
||||
|
||||
@@ -802,7 +804,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 +851,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 +894,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 +926,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 +983,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 +1138,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 +1284,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);
|
||||
@@ -1363,7 +1373,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);
|
||||
@@ -1633,6 +1642,14 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
case FTDM_SIGEVENT_RELEASED:
|
||||
case FTDM_SIGEVENT_INDICATION_COMPLETED:
|
||||
{
|
||||
/* Swallow these events */
|
||||
return FTDM_BREAK;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FTDM_SUCCESS;
|
||||
break;
|
||||
@@ -1723,7 +1740,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
case FTDM_SIGEVENT_SIGSTATUS_CHANGED: { /* twiddle */ } break;
|
||||
|
||||
default:
|
||||
{
|
||||
@@ -1778,7 +1795,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
|
||||
case FTDM_SIGEVENT_STOP:
|
||||
{
|
||||
@@ -1811,7 +1827,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);
|
||||
@@ -1911,7 +1929,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);
|
||||
@@ -2003,8 +2021,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
|
||||
}
|
||||
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:
|
||||
{
|
||||
@@ -2077,13 +2093,14 @@ 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->ev_data.sigstatus.status;
|
||||
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:{} break;
|
||||
case FTDM_SIGEVENT_INDICATION_COMPLETED:{} break;
|
||||
|
||||
default:
|
||||
{
|
||||
@@ -2122,8 +2139,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
|
||||
case FTDM_SIGEVENT_STOP:
|
||||
case FTDM_SIGEVENT_RESTART:
|
||||
{
|
||||
@@ -2183,7 +2198,7 @@ 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->ev_data.sigstatus.status;
|
||||
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));
|
||||
}
|
||||
@@ -2707,6 +2722,9 @@ static switch_status_t load_config(void)
|
||||
char *hold_music = NULL;
|
||||
char *fail_dial_regex = NULL;
|
||||
const char *enable_callerid = "true";
|
||||
const char *answer_polarity = "false";
|
||||
const char *hangup_polarity = "false";
|
||||
int polarity_delay = 600;
|
||||
int callwaiting = 1;
|
||||
|
||||
uint32_t span_id = 0, to = 0, max = 0;
|
||||
@@ -2778,6 +2796,12 @@ static switch_status_t load_config(void)
|
||||
dial_regex = val;
|
||||
} else if (!strcasecmp(var, "enable-callerid")) {
|
||||
enable_callerid = val;
|
||||
} else if (!strcasecmp(var, "answer-polarity-reverse")) {
|
||||
answer_polarity = val;
|
||||
} else if (!strcasecmp(var, "hangup-polarity-reverse")) {
|
||||
hangup_polarity = val;
|
||||
} else if (!strcasecmp(var, "polarity-delay")) {
|
||||
polarity_delay = atoi(val);
|
||||
} else if (!strcasecmp(var, "fail-dial-regex")) {
|
||||
fail_dial_regex = val;
|
||||
} else if (!strcasecmp(var, "hold-music")) {
|
||||
@@ -2838,6 +2862,9 @@ static switch_status_t load_config(void)
|
||||
"max_dialstr", &max,
|
||||
"hotline", hotline ? hotline : "",
|
||||
"enable_callerid", enable_callerid,
|
||||
"answer_polarity_reverse", answer_polarity,
|
||||
"hangup_polarity_reverse", hangup_polarity,
|
||||
"polarity_delay", &polarity_delay,
|
||||
"callwaiting", &callwaiting,
|
||||
FTDM_TAG_END) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM analog span %s\n", ftdm_span_get_name(span));
|
||||
@@ -3526,7 +3553,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 };
|
||||
|
||||
@@ -94,78 +94,6 @@
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
BuildLogFile="$(IntDir)\BuildLog-freetdm.htm"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../src/include;../src/include/private;../src/isdn/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FREETDM_EXPORTS;TELETONE_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
DisableLanguageExtensions="false"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
@@ -243,6 +171,78 @@
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
BuildLogFile="$(IntDir)\BuildLog-freetdm.htm"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../src/include;../src/include/private;../src/isdn/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FREETDM_EXPORTS;TELETONE_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
DisableLanguageExtensions="false"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
@@ -366,6 +366,10 @@
|
||||
RelativePath="..\src\include\private\ftdm_sched.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\include\private\ftdm_state.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\include\ftdm_threadmutex.h"
|
||||
>
|
||||
@@ -452,6 +456,10 @@
|
||||
RelativePath="..\src\ftdm_sched.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\ftdm_state.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\ftdm_threadmutex.c"
|
||||
>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+491
-517
File diff suppressed because it is too large
Load Diff
@@ -1,692 +0,0 @@
|
||||
/*
|
||||
* ftdm_m3ua.c
|
||||
* freetdm
|
||||
*
|
||||
* Created by Shane Burrell on 4/3/08.
|
||||
* Copyright 2008 Shane Burrell. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II, Nenad Corbic *
|
||||
*
|
||||
* 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 "freetdm.h"
|
||||
#include "m3ua_client.h"
|
||||
#include "ftdm_m3ua.h"
|
||||
|
||||
#define MAX_REQ_ID MAX_PENDING_CALLS
|
||||
typedef uint16_t m3ua_request_id_t;
|
||||
|
||||
typedef enum {
|
||||
BST_FREE,
|
||||
BST_WAITING,
|
||||
BST_READY,
|
||||
BST_FAIL
|
||||
} m3ua_request_status_t;
|
||||
|
||||
typedef struct {
|
||||
m3ua_request_status_t status;
|
||||
m3uac_event_t event;
|
||||
ftdm_span_t *span;
|
||||
ftdm_channel_t *ftdmchan;
|
||||
} m3ua_request_t;
|
||||
|
||||
|
||||
struct general_config {
|
||||
uint32_t region;
|
||||
};
|
||||
typedef struct general_config general_config_t;
|
||||
|
||||
|
||||
struct m3ua_channel_profile {
|
||||
char name[80];
|
||||
int cust_span;
|
||||
unsigned char opc[3];
|
||||
unsigned char dpc[3];
|
||||
int local_ip[4];
|
||||
int local_port;
|
||||
int remote_ip[4];
|
||||
int remote_port;
|
||||
int m3ua_mode;
|
||||
};
|
||||
typedef struct m3ua_channel_profile m3ua_channel_profile_t;
|
||||
|
||||
static struct {
|
||||
ftdm_hash_t *profile_hash;
|
||||
general_config_t general_config;
|
||||
} globals;
|
||||
|
||||
struct m3ua_span_data {
|
||||
uint32_t boardno;
|
||||
uint32_t flags;
|
||||
};
|
||||
typedef struct m3ua_span_data m3ua_span_data_t;
|
||||
|
||||
struct m3ua_chan_data {
|
||||
ftdm_buffer_t *digit_buffer;
|
||||
ftdm_mutex_t *digit_mutex;
|
||||
ftdm_size_t dtmf_len;
|
||||
uint32_t flags;
|
||||
uint32_t hdlc_bytes;
|
||||
};
|
||||
typedef struct m3ua_chan_data m3ua_chan_data_t;
|
||||
|
||||
static ftdm_mutex_t *request_mutex = NULL;
|
||||
static ftdm_mutex_t *signal_mutex = NULL;
|
||||
|
||||
static uint8_t req_map[MAX_REQ_ID+1] = { 0 };
|
||||
|
||||
static void release_request_id(m3ua_request_id_t r)
|
||||
{
|
||||
ftdm_mutex_lock(request_mutex);
|
||||
req_map[r] = 0;
|
||||
ftdm_mutex_unlock(request_mutex);
|
||||
}
|
||||
|
||||
/*static m3ua_request_id_t next_request_id(void)
|
||||
{
|
||||
m3ua_request_id_t r = 0;
|
||||
int ok = 0;
|
||||
|
||||
while(!ok) {
|
||||
ftdm_mutex_lock(request_mutex);
|
||||
for (r = 1; r <= MAX_REQ_ID; r++) {
|
||||
if (!req_map[r]) {
|
||||
ok = 1;
|
||||
req_map[r] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ftdm_mutex_unlock(request_mutex);
|
||||
if (!ok) {
|
||||
ftdm_sleep(5);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
*/
|
||||
|
||||
static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
|
||||
m3ua_data_t *m3ua_data = ftdmchan->span->signal_data;
|
||||
m3uac_connection_t *mcon = &m3ua_data->mcon;
|
||||
ftdm_sigmsg_t sig;
|
||||
ftdm_status_t status;
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%d:%d STATE [%s]\n", ftdmchan->span_id, ftdmchan->chan_id, ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
memset(&sig, 0, sizeof(sig));
|
||||
sig.chan_id = ftdmchan->chan_id;
|
||||
sig.span_id = ftdmchan->span_id;
|
||||
sig.channel = ftdmchan;
|
||||
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
{
|
||||
if (ftdmchan->extra_id) {
|
||||
release_request_id((m3ua_request_id_t)ftdmchan->extra_id);
|
||||
ftdmchan->extra_id = 0;
|
||||
}
|
||||
ftdm_channel_close(&ftdmchan);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
{
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
sig.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
|
||||
if ((status = m3ua_data->signal_cb(&sig) != FTDM_SUCCESS)) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
}
|
||||
} else {
|
||||
m3uac_exec_command(mcon,
|
||||
ftdmchan->physical_span_id-1,
|
||||
ftdmchan->physical_chan_id-1,
|
||||
0,
|
||||
SIGBOOST_EVENT_CALL_START_ACK,
|
||||
0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
{
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
sig.event_id = FTDM_SIGEVENT_START;
|
||||
if ((status = m3ua_data->signal_cb(&sig) != FTDM_SUCCESS)) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESTART:
|
||||
{
|
||||
if (ftdmchan->last_state != FTDM_CHANNEL_STATE_HANGUP && ftdmchan->last_state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
} else {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
{
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
sig.event_id = FTDM_SIGEVENT_UP;
|
||||
if ((status = m3ua_data->signal_cb(&sig) != FTDM_SUCCESS)) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
}
|
||||
} else {
|
||||
if (!(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_PROGRESS) || ftdm_test_flag(ftdmchan, FTDM_CHANNEL_MEDIA))) {
|
||||
m3uac_exec_command(mcon,
|
||||
ftdmchan->physical_span_id-1,
|
||||
ftdmchan->physical_chan_id-1,
|
||||
0,
|
||||
SIGBOOST_EVENT_CALL_START_ACK,
|
||||
0);
|
||||
}
|
||||
|
||||
m3uac_exec_command(mcon,
|
||||
ftdmchan->physical_span_id-1,
|
||||
ftdmchan->physical_chan_id-1,
|
||||
0,
|
||||
SIGBOOST_EVENT_CALL_ANSWERED,
|
||||
0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
{
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
{
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP:
|
||||
{
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_ANSWERED) || ftdm_test_flag(ftdmchan, FTDM_CHANNEL_PROGRESS) || ftdm_test_flag(ftdmchan, FTDM_CHANNEL_MEDIA)) {
|
||||
m3uac_exec_command(mcon,
|
||||
ftdmchan->physical_span_id-1,
|
||||
ftdmchan->physical_chan_id-1,
|
||||
0,
|
||||
SIGBOOST_EVENT_CALL_STOPPED,
|
||||
ftdmchan->caller_data.hangup_cause);
|
||||
} else {
|
||||
m3uac_exec_command(mcon,
|
||||
ftdmchan->physical_span_id-1,
|
||||
ftdmchan->physical_chan_id-1,
|
||||
0,
|
||||
SIGBOOST_EVENT_CALL_START_NACK,
|
||||
ftdmchan->caller_data.hangup_cause);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_CANCEL:
|
||||
{
|
||||
sig.event_id = FTDM_SIGEVENT_STOP;
|
||||
status = m3ua_data->signal_cb(&sig);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
m3uac_exec_command(mcon,
|
||||
ftdmchan->physical_span_id-1,
|
||||
ftdmchan->physical_chan_id-1,
|
||||
0,
|
||||
SIGBOOST_EVENT_CALL_START_NACK_ACK,
|
||||
0);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_TERMINATING:
|
||||
{
|
||||
sig.event_id = FTDM_SIGEVENT_STOP;
|
||||
status = m3ua_data->signal_cb(&sig);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
m3uac_exec_command(mcon,
|
||||
ftdmchan->physical_span_id-1,
|
||||
ftdmchan->physical_chan_id-1,
|
||||
0,
|
||||
SIGBOOST_EVENT_CALL_STOPPED_ACK,
|
||||
0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static __inline__ void check_state(ftdm_span_t *span)
|
||||
{
|
||||
if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE)) {
|
||||
uint32_t j;
|
||||
ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE);
|
||||
for(j = 1; j <= span->chan_count; j++) {
|
||||
if (ftdm_test_flag((&span->channels[j]), FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_clear_flag_locked((&span->channels[j]), FTDM_CHANNEL_STATE_CHANGE);
|
||||
state_advance(&span->channels[j]);
|
||||
ftdm_channel_complete_state(&span->channels[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int parse_ss7_event(ftdm_span_t *span, m3uac_connection_t *mcon, m3uac_event_t *event)
|
||||
{
|
||||
ftdm_mutex_lock(signal_mutex);
|
||||
|
||||
if (!ftdm_running()) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "System is shutting down.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
if (ftdm_test_flag(span, FTDM_SPAN_SUSPENDED) &&
|
||||
event->event_id != SIGBOOST_EVENT_SYSTEM_RESTART_ACK && event->event_id != SIGBOOST_EVENT_HEARTBEAT) {
|
||||
|
||||
ftdm_log(FTDM_LOG_WARNING,
|
||||
"INVALID EVENT: %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i Cd=[%s] Ci=[%s]\n",
|
||||
m3uac_event_id_name(event->event_id),
|
||||
event->event_id,
|
||||
event->span+1,
|
||||
event->chan+1,
|
||||
event->release_cause,
|
||||
event->call_setup_id,
|
||||
event->fseqno,
|
||||
(event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"),
|
||||
(event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")
|
||||
);
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG,
|
||||
"RX EVENT: %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i Cd=[%s] Ci=[%s]\n",
|
||||
m3uac_event_id_name(event->event_id),
|
||||
event->event_id,
|
||||
event->span+1,
|
||||
event->chan+1,
|
||||
event->release_cause,
|
||||
event->call_setup_id,
|
||||
event->fseqno,
|
||||
(event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"),
|
||||
(event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")
|
||||
);
|
||||
|
||||
|
||||
|
||||
switch(event->event_id) {
|
||||
|
||||
case SIGBOOST_EVENT_CALL_START:
|
||||
//handle_call_start(span, mcon, event);
|
||||
break;
|
||||
case SIGBOOST_EVENT_CALL_STOPPED:
|
||||
//handle_call_stop(span, mcon, event);
|
||||
break;
|
||||
case SIGBOOST_EVENT_CALL_START_ACK:
|
||||
//handle_call_start_ack(mcon, event);
|
||||
break;
|
||||
case SIGBOOST_EVENT_CALL_START_NACK:
|
||||
//handle_call_start_nack(span, mcon, event);
|
||||
break;
|
||||
case SIGBOOST_EVENT_CALL_ANSWERED:
|
||||
//handle_call_answer(span, mcon, event);
|
||||
break;
|
||||
case SIGBOOST_EVENT_HEARTBEAT:
|
||||
//handle_heartbeat(mcon, event);
|
||||
break;
|
||||
case SIGBOOST_EVENT_CALL_STOPPED_ACK:
|
||||
case SIGBOOST_EVENT_CALL_START_NACK_ACK:
|
||||
//handle_call_done(span, mcon, event);
|
||||
break;
|
||||
case SIGBOOST_EVENT_INSERT_CHECK_LOOP:
|
||||
//handle_call_loop_start(event);
|
||||
break;
|
||||
case SIGBOOST_EVENT_REMOVE_CHECK_LOOP:
|
||||
//handle_call_stop(event);
|
||||
break;
|
||||
case SIGBOOST_EVENT_SYSTEM_RESTART_ACK:
|
||||
//handle_restart_ack(mcon, span, event);
|
||||
break;
|
||||
case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE:
|
||||
//handle_gap_abate(event);
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_WARNING, "No handler implemented for [%s]\n", m3uac_event_id_name(event->event_id));
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
ftdm_mutex_unlock(signal_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FIO_CONFIGURE_FUNCTION(m3ua_configure)
|
||||
{
|
||||
m3ua_channel_profile_t *profile = NULL;
|
||||
|
||||
int ok = 1;
|
||||
|
||||
if (!(profile = (m3ua_channel_profile_t *) hashtable_search(globals.profile_hash, (char *)category))) {
|
||||
profile = ftdm_malloc(sizeof(*profile));
|
||||
memset(profile, 0, sizeof(*profile));
|
||||
ftdm_set_string(profile->name, category);
|
||||
hashtable_insert(globals.profile_hash, (void *)profile->name, profile);
|
||||
ftdm_log(FTDM_LOG_INFO, "creating profile [%s]\n", category);
|
||||
}
|
||||
|
||||
// ftdm_set_string(m3ua_data->mcon. cfg.local_ip, local_ip);
|
||||
if (!strcasecmp(var, "local_sctp_port")) {
|
||||
profile->local_port = 30000 ;
|
||||
profile->remote_port = 30000;
|
||||
profile->cust_span++;
|
||||
}
|
||||
ok = 1;
|
||||
|
||||
|
||||
if (ok) {
|
||||
ftdm_log(FTDM_LOG_INFO, "setting param [%s]=[%s] for profile [%s]\n", var, val, category);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "unknown param [%s]\n", var);
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static FIO_CONFIGURE_SPAN_FUNCTION(m3ua_configure_span)
|
||||
{
|
||||
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
static FIO_OPEN_FUNCTION(m3ua_open)
|
||||
{
|
||||
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
static FIO_CLOSE_FUNCTION(m3ua_close)
|
||||
{
|
||||
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/*static FIO_SET_INTERVAL_FUNCTION(m3ua_set_interval)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
static FIO_WAIT_FUNCTION(m3ua_wait)
|
||||
{
|
||||
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
static FIO_READ_FUNCTION(m3ua_read)
|
||||
{
|
||||
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
static FIO_WRITE_FUNCTION(m3ua_write)
|
||||
{
|
||||
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
static FIO_COMMAND_FUNCTION(m3ua_command)
|
||||
{
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
static FIO_SPAN_POLL_EVENT_FUNCTION(m3ua_poll_event)
|
||||
{
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
static FIO_SPAN_NEXT_EVENT_FUNCTION(m3ua_next_event)
|
||||
{
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
|
||||
static FIO_SPAN_DESTROY_FUNCTION(m3ua_span_destroy)
|
||||
{
|
||||
m3ua_span_data_t *span_data = (m3ua_span_data_t *) span->io_data;
|
||||
|
||||
if (span_data) {
|
||||
ftdm_safe_free(span_data);
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
static FIO_CHANNEL_DESTROY_FUNCTION(m3ua_channel_destroy)
|
||||
{
|
||||
m3ua_chan_data_t *chan_data = (m3ua_chan_data_t *) ftdmchan->io_data;
|
||||
m3ua_span_data_t *span_data = (m3ua_span_data_t *) ftdmchan->span->io_data;
|
||||
|
||||
if (!chan_data) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ftdm_mutex_destroy(&chan_data->digit_mutex);
|
||||
ftdm_buffer_destroy(&chan_data->digit_buffer);
|
||||
|
||||
|
||||
ftdm_safe_free(chan_data);
|
||||
|
||||
if (span_data) {
|
||||
ftdm_safe_free(span_data);
|
||||
}
|
||||
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static FIO_GET_ALARMS_FUNCTION(m3ua_get_alarms)
|
||||
{
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
static ftdm_io_interface_t m3ua_interface;
|
||||
|
||||
ftdm_status_t m3ua_init(ftdm_io_interface_t **zint)
|
||||
{
|
||||
assert(zint != NULL);
|
||||
memset(&m3ua_interface, 0, sizeof(m3ua_interface));
|
||||
|
||||
m3ua_interface.name = "m3ua";
|
||||
m3ua_interface.configure = m3ua_configure;
|
||||
m3ua_interface.configure_span = m3ua_configure_span;
|
||||
m3ua_interface.open = m3ua_open;
|
||||
m3ua_interface.close = m3ua_close;
|
||||
m3ua_interface.wait = m3ua_wait;
|
||||
m3ua_interface.read = m3ua_read;
|
||||
m3ua_interface.write = m3ua_write;
|
||||
m3ua_interface.command = m3ua_command;
|
||||
m3ua_interface.poll_event = m3ua_poll_event;
|
||||
m3ua_interface.next_event = m3ua_next_event;
|
||||
m3ua_interface.channel_destroy = m3ua_channel_destroy;
|
||||
m3ua_interface.span_destroy = m3ua_span_destroy;
|
||||
m3ua_interface.get_alarms = m3ua_get_alarms;
|
||||
*zint = &m3ua_interface;
|
||||
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdm_status_t m3ua_destroy(void)
|
||||
{
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
|
||||
static void *m3ua_run(ftdm_thread_t *me, void *obj)
|
||||
{
|
||||
ftdm_span_t *span = (ftdm_span_t *) obj;
|
||||
m3ua_data_t *m3ua_data = span->signal_data;
|
||||
m3uac_connection_t *mcon, *pcon;
|
||||
uint32_t ms = 10, too_long = 60000;
|
||||
|
||||
|
||||
m3ua_data->pcon = m3ua_data->mcon;
|
||||
|
||||
if (m3uac_connection_open(&m3ua_data->mcon,
|
||||
m3ua_data->mcon.cfg.local_ip,
|
||||
m3ua_data->mcon.cfg.local_port,
|
||||
m3ua_data->mcon.cfg.remote_ip,
|
||||
m3ua_data->mcon.cfg.remote_port) < 0) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Error: Opening MCON Socket [%d] %s\n", m3ua_data->mcon.socket, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (m3uac_connection_open(&m3ua_data->pcon,
|
||||
m3ua_data->pcon.cfg.local_ip,
|
||||
++m3ua_data->pcon.cfg.local_port,
|
||||
m3ua_data->pcon.cfg.remote_ip,
|
||||
m3ua_data->pcon.cfg.remote_port) < 0) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Error: Opening PCON Socket [%d] %s\n", m3ua_data->pcon.socket, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
mcon = &m3ua_data->mcon;
|
||||
pcon = &m3ua_data->pcon;
|
||||
|
||||
top:
|
||||
|
||||
//init_outgoing_array();
|
||||
|
||||
m3uac_exec_command(mcon,
|
||||
0,
|
||||
0,
|
||||
-1,
|
||||
SIGBOOST_EVENT_SYSTEM_RESTART,
|
||||
0);
|
||||
|
||||
while (ftdm_test_flag(m3ua_data, FTDM_M3UA_RUNNING)) {
|
||||
fd_set rfds, efds;
|
||||
struct timeval tv = { 0, ms * 1000 };
|
||||
int max, activity, i = 0;
|
||||
m3uac_event_t *event = NULL;
|
||||
|
||||
if (!ftdm_running()) {
|
||||
m3uac_exec_command(mcon,
|
||||
0,
|
||||
0,
|
||||
-1,
|
||||
SIGBOOST_EVENT_SYSTEM_RESTART,
|
||||
0);
|
||||
break;
|
||||
}
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_ZERO(&efds);
|
||||
FD_SET(mcon->socket, &rfds);
|
||||
FD_SET(mcon->socket, &efds);
|
||||
FD_SET(pcon->socket, &rfds);
|
||||
FD_SET(pcon->socket, &efds);
|
||||
|
||||
max = ((pcon->socket > mcon->socket) ? pcon->socket : mcon->socket) + 1;
|
||||
|
||||
if ((activity = select(max, &rfds, NULL, &efds, &tv)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (activity) {
|
||||
if (FD_ISSET(pcon->socket, &efds) || FD_ISSET(mcon->socket, &efds)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (FD_ISSET(pcon->socket, &rfds)) {
|
||||
if ((event = m3uac_connection_readp(pcon, i))) {
|
||||
parse_ss7_event(span, mcon, event);
|
||||
} else goto top;
|
||||
}
|
||||
|
||||
if (FD_ISSET(mcon->socket, &rfds)) {
|
||||
if ((event = m3uac_connection_read(mcon, i))) {
|
||||
parse_ss7_event(span, mcon, event);
|
||||
} else goto top;
|
||||
}
|
||||
}
|
||||
|
||||
check_state(span);
|
||||
mcon->hb_elapsed += ms;
|
||||
|
||||
if (mcon->hb_elapsed >= too_long && (mcon->up || !ftdm_test_flag(span, FTDM_SPAN_SUSPENDED))) {
|
||||
ftdm_set_state_all(span, FTDM_CHANNEL_STATE_RESTART);
|
||||
ftdm_set_flag_locked(span, FTDM_SPAN_SUSPENDED);
|
||||
mcon->up = 0;
|
||||
ftdm_log(FTDM_LOG_CRIT, "Lost Heartbeat!\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
goto end;
|
||||
|
||||
error:
|
||||
ftdm_log(FTDM_LOG_CRIT, "Socket Error!\n");
|
||||
|
||||
end:
|
||||
|
||||
m3uac_connection_close(&m3ua_data->mcon);
|
||||
m3uac_connection_close(&m3ua_data->pcon);
|
||||
|
||||
ftdm_clear_flag(m3ua_data, FTDM_M3UA_RUNNING);
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "M3UA thread ended.\n");
|
||||
return NULL;
|
||||
}
|
||||
ftdm_status_t m3ua_start(ftdm_span_t *span)
|
||||
{
|
||||
m3ua_data_t *m3ua_data = span->signal_data;
|
||||
ftdm_set_flag(m3ua_data, FTDM_M3UA_RUNNING);
|
||||
return ftdm_thread_create_detached(m3ua_run, span);
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
*/
|
||||
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Sangoma Technologies
|
||||
* Moises Silva <moy@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "private/ftdm_core.h"
|
||||
|
||||
FTDM_ENUM_NAMES(CHANNEL_STATE_NAMES, CHANNEL_STATE_STRINGS)
|
||||
FTDM_STR2ENUM(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t, CHANNEL_STATE_NAMES, FTDM_CHANNEL_STATE_INVALID)
|
||||
|
||||
FTDM_ENUM_NAMES(CHANNEL_STATE_STATUS_NAMES, CHANNEL_STATE_STATUS_STRINGS)
|
||||
FTDM_STR2ENUM(ftdm_str2ftdm_state_status, ftdm_state_status2str, ftdm_state_status_t, CHANNEL_STATE_STATUS_NAMES, FTDM_STATE_STATUS_INVALID)
|
||||
|
||||
/* This function is only needed for boost and we should get rid of it at the next refactoring */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_init(ftdm_channel_t *fchan)
|
||||
{
|
||||
ftdm_channel_lock(fchan);
|
||||
|
||||
if (fchan->init_state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
ftdm_channel_set_state(__FILE__, __FUNCTION__, __LINE__, fchan, fchan->init_state, 1);
|
||||
fchan->init_state = FTDM_CHANNEL_STATE_DOWN;
|
||||
}
|
||||
|
||||
ftdm_channel_unlock(fchan);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const char *func, int line, ftdm_channel_t *fchan)
|
||||
{
|
||||
uint8_t hindex = 0;
|
||||
ftdm_time_t diff = 0;
|
||||
ftdm_channel_state_t state = fchan->state;
|
||||
|
||||
if (fchan->state_status == FTDM_STATE_STATUS_COMPLETED) {
|
||||
ftdm_assert_return(!ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE), FTDM_FAIL,
|
||||
"State change flag set but state is not completed\n");
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_clear_flag(fchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
|
||||
if (state == FTDM_CHANNEL_STATE_PROGRESS) {
|
||||
ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS);
|
||||
} else if (state == FTDM_CHANNEL_STATE_UP) {
|
||||
ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS);
|
||||
ftdm_set_flag(fchan, FTDM_CHANNEL_MEDIA);
|
||||
ftdm_set_flag(fchan, FTDM_CHANNEL_ANSWERED);
|
||||
} else if (state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
|
||||
ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS);
|
||||
ftdm_set_flag(fchan, FTDM_CHANNEL_MEDIA);
|
||||
}
|
||||
|
||||
/* if there is a pending ack for an indication
|
||||
* MAINTENANCE WARNING: we're assuming an indication performed
|
||||
* via state change will involve a single state change
|
||||
*/
|
||||
if (ftdm_test_flag(fchan, FTDM_CHANNEL_IND_ACK_PENDING)) {
|
||||
ftdm_ack_indication(fchan, fchan->indication, FTDM_SUCCESS);
|
||||
}
|
||||
|
||||
hindex = (fchan->hindex == 0) ? (ftdm_array_len(fchan->history) - 1) : (fchan->hindex - 1);
|
||||
|
||||
ftdm_assert(!fchan->history[hindex].end_time, "End time should be zero!\n");
|
||||
|
||||
fchan->history[hindex].end_time = ftdm_current_time_in_ms();
|
||||
|
||||
fchan->state_status = FTDM_STATE_STATUS_COMPLETED;
|
||||
|
||||
diff = fchan->history[hindex].end_time - fchan->history[hindex].time;
|
||||
|
||||
ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Completed state change from %s to %s in %llums\n",
|
||||
ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(state), diff);
|
||||
|
||||
|
||||
if (ftdm_test_flag(fchan, FTDM_CHANNEL_BLOCKING)) {
|
||||
ftdm_clear_flag(fchan, FTDM_CHANNEL_BLOCKING);
|
||||
ftdm_interrupt_signal(fchan->state_completed_interrupt);
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) _ftdm_set_state(const char *file, const char *func, int line,
|
||||
ftdm_channel_t *fchan, ftdm_channel_state_t state)
|
||||
{
|
||||
if (fchan->state_status != FTDM_STATE_STATUS_COMPLETED) {
|
||||
/* the current state is not completed, setting a new state from a signaling module
|
||||
when the current state is not completed is equivalent to implicitly acknowledging
|
||||
the current state */
|
||||
_ftdm_channel_complete_state(file, func, line, fchan);
|
||||
}
|
||||
return ftdm_channel_set_state(file, func, line, fchan, state, 0);
|
||||
}
|
||||
|
||||
static int ftdm_parse_state_map(ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, ftdm_state_map_t *state_map)
|
||||
{
|
||||
int x = 0, ok = 0;
|
||||
ftdm_state_direction_t direction = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? ZSD_OUTBOUND : ZSD_INBOUND;
|
||||
|
||||
for(x = 0; x < FTDM_MAP_NODE_SIZE; x++) {
|
||||
int i = 0, proceed = 0;
|
||||
if (!state_map->nodes[x].type) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (state_map->nodes[x].direction != direction) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (state_map->nodes[x].check_states[0] == FTDM_ANY_STATE) {
|
||||
proceed = 1;
|
||||
} else {
|
||||
for(i = 0; i < FTDM_MAP_MAX; i++) {
|
||||
if (state_map->nodes[x].check_states[i] == ftdmchan->state) {
|
||||
proceed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!proceed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for(i = 0; i < FTDM_MAP_MAX; i++) {
|
||||
ok = (state_map->nodes[x].type == ZSM_ACCEPTABLE);
|
||||
if (state_map->nodes[x].states[i] == FTDM_END) {
|
||||
break;
|
||||
}
|
||||
if (state_map->nodes[x].states[i] == state) {
|
||||
ok = !ok;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
end:
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* this function MUST be called with the channel lock held. If waitrq == 1, the channel will be unlocked/locked (never call it with waitrq == 1 with an lock recursivity > 1) */
|
||||
#define DEFAULT_WAIT_TIME 1000
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, int waitrq)
|
||||
{
|
||||
ftdm_status_t status;
|
||||
int ok = 1;
|
||||
int waitms = DEFAULT_WAIT_TIME;
|
||||
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_READY)) {
|
||||
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_ERROR, "Ignored state change request from %s to %s, the channel is not ready\n",
|
||||
ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (ftdmchan->state_status != FTDM_STATE_STATUS_COMPLETED) {
|
||||
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_ERROR,
|
||||
"Ignored state change request from %s to %s, the previous state change has not been processed yet (status = %s)\n",
|
||||
ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state),
|
||||
ftdm_state_status2str(ftdmchan->state_status));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (ftdmchan->state == state) {
|
||||
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "Why bother changing state from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (!ftdmchan->state_completed_interrupt) {
|
||||
status = ftdm_interrupt_create(&ftdmchan->state_completed_interrupt, FTDM_INVALID_SOCKET);
|
||||
if (status != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_CRIT,
|
||||
"Failed to create state change interrupt when moving from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ftdmchan->span->state_map) {
|
||||
ok = ftdm_parse_state_map(ftdmchan, state, ftdmchan->span->state_map);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* basic core state validation (by-passed if the signaling module provides a state_map) */
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_HANGUP:
|
||||
case FTDM_CHANNEL_STATE_TERMINATING:
|
||||
{
|
||||
ok = 0;
|
||||
switch(state) {
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
case FTDM_CHANNEL_STATE_BUSY:
|
||||
case FTDM_CHANNEL_STATE_RESTART:
|
||||
ok = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
{
|
||||
ok = 1;
|
||||
switch(state) {
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
ok = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
{
|
||||
ok = 0;
|
||||
|
||||
switch(state) {
|
||||
case FTDM_CHANNEL_STATE_DIALTONE:
|
||||
case FTDM_CHANNEL_STATE_COLLECT:
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_IDLE:
|
||||
case FTDM_CHANNEL_STATE_GET_CALLERID:
|
||||
case FTDM_CHANNEL_STATE_GENRING:
|
||||
ok = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_BUSY:
|
||||
{
|
||||
switch(state) {
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
ok = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
{
|
||||
switch(state) {
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
ok = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
if (!ok) {
|
||||
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "VETO state change from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
|
||||
goto done;
|
||||
}
|
||||
|
||||
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Changed state from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
|
||||
ftdmchan->last_state = ftdmchan->state;
|
||||
ftdmchan->state = state;
|
||||
ftdmchan->state_status = FTDM_STATE_STATUS_NEW;
|
||||
ftdmchan->history[ftdmchan->hindex].file = file;
|
||||
ftdmchan->history[ftdmchan->hindex].func = func;
|
||||
ftdmchan->history[ftdmchan->hindex].line = line;
|
||||
ftdmchan->history[ftdmchan->hindex].state = ftdmchan->state;
|
||||
ftdmchan->history[ftdmchan->hindex].last_state = ftdmchan->last_state;
|
||||
ftdmchan->history[ftdmchan->hindex].time = ftdm_current_time_in_ms();
|
||||
ftdmchan->history[ftdmchan->hindex].end_time = 0;
|
||||
ftdmchan->hindex++;
|
||||
if (ftdmchan->hindex == ftdm_array_len(ftdmchan->history)) {
|
||||
ftdmchan->hindex = 0;
|
||||
}
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->span->mutex);
|
||||
ftdm_set_flag(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
|
||||
if (ftdmchan->span->pendingchans) {
|
||||
ftdm_queue_enqueue(ftdmchan->span->pendingchans, ftdmchan);
|
||||
}
|
||||
ftdm_mutex_unlock(ftdmchan->span->mutex);
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NONBLOCK)) {
|
||||
/* the channel should not block waiting for state processing */
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!waitrq) {
|
||||
/* no waiting was requested */
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* let's wait for the state change to be completed by the signaling stack */
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_BLOCKING);
|
||||
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
|
||||
status = ftdm_interrupt_wait(ftdmchan->state_completed_interrupt, waitms);
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
if (status != FTDM_SUCCESS) {
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_BLOCKING);
|
||||
ftdm_log_chan_ex(ftdmchan, file, func, line,
|
||||
FTDM_LOG_LEVEL_WARNING, "state change from %s to %s was most likely not completed after aprox %dms\n",
|
||||
ftdm_channel_state2str(ftdmchan->last_state), ftdm_channel_state2str(state), DEFAULT_WAIT_TIME);
|
||||
ok = 0;
|
||||
goto done;
|
||||
}
|
||||
done:
|
||||
return ok ? FTDM_SUCCESS : FTDM_FAIL;
|
||||
}
|
||||
|
||||
FT_DECLARE(int) ftdm_channel_get_state(const ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
int state;
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
state = ftdmchan->state;
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
return state;
|
||||
}
|
||||
|
||||
FT_DECLARE(const char *) ftdm_channel_get_state_str(const ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
const char *state;
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
state = ftdm_channel_state2str(ftdmchan->state);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
return state;
|
||||
}
|
||||
|
||||
FT_DECLARE(int) ftdm_channel_get_last_state(const ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
int last_state;
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
last_state = ftdmchan->last_state;
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
return last_state;
|
||||
}
|
||||
|
||||
FT_DECLARE(const char *) ftdm_channel_get_last_state_str(const ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
const char *state;
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
state = ftdm_channel_state2str(ftdmchan->last_state);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
return state;
|
||||
}
|
||||
|
||||
static void write_history_entry(const ftdm_channel_t *fchan, ftdm_stream_handle_t *stream, int i, ftdm_time_t *prevtime)
|
||||
{
|
||||
char func[255];
|
||||
char line[255];
|
||||
char states[255];
|
||||
const char *filename = NULL;
|
||||
snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state));
|
||||
snprintf(func, sizeof(func), "[%s]", fchan->history[i].func);
|
||||
filename = strrchr(fchan->history[i].file, *FTDM_PATH_SEPARATOR);
|
||||
if (!filename) {
|
||||
filename = fchan->history[i].file;
|
||||
} else {
|
||||
filename++;
|
||||
}
|
||||
if (!(*prevtime)) {
|
||||
*prevtime = fchan->history[i].time;
|
||||
}
|
||||
snprintf(line, sizeof(func), "[%s:%d]", filename, fchan->history[i].line);
|
||||
stream->write_function(stream, "%-30.30s %-30.30s %-30.30s %lums\n", states, func, line, (fchan->history[i].time - *prevtime));
|
||||
*prevtime = fchan->history[i].time;
|
||||
}
|
||||
|
||||
FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
ftdm_time_t currtime = 0;
|
||||
ftdm_time_t prevtime = 0;
|
||||
|
||||
ftdm_stream_handle_t stream = { 0 };
|
||||
FTDM_STANDARD_STREAM(stream);
|
||||
if (!fchan->history[0].file) {
|
||||
stream.write_function(&stream, "-- No state history --\n");
|
||||
return stream.data;
|
||||
}
|
||||
|
||||
stream.write_function(&stream, "%-30.30s %-30.30s %-30.30s %s",
|
||||
"-- States --", "-- Function --", "-- Location --", "-- Time Offset --\n");
|
||||
|
||||
for (i = fchan->hindex; i < ftdm_array_len(fchan->history); i++) {
|
||||
if (!fchan->history[i].file) {
|
||||
break;
|
||||
}
|
||||
write_history_entry(fchan, &stream, i, &prevtime);
|
||||
}
|
||||
|
||||
for (i = 0; i < fchan->hindex; i++) {
|
||||
write_history_entry(fchan, &stream, i, &prevtime);
|
||||
}
|
||||
|
||||
currtime = ftdm_current_time_in_ms();
|
||||
|
||||
stream.write_function(&stream, "\nTime since last state change: %lums\n", (currtime - prevtime));
|
||||
|
||||
return stream.data;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_advance_states(ftdm_channel_t *fchan)
|
||||
{
|
||||
ftdm_channel_state_t state;
|
||||
|
||||
ftdm_assert_return(fchan->span->state_processor, FTDM_FAIL, "Cannot process states without a state processor!\n");
|
||||
|
||||
while (fchan->state_status == FTDM_STATE_STATUS_NEW) {
|
||||
state = fchan->state;
|
||||
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Executing state processor for %s\n", ftdm_channel_state2str(fchan->state));
|
||||
fchan->span->state_processor(fchan);
|
||||
if (state == fchan->state && fchan->state_status == FTDM_STATE_STATUS_NEW) {
|
||||
/* if the state did not change and is still NEW, the state status must go to PROCESSED
|
||||
* otherwise we don't touch it since is a new state and the old state was
|
||||
* already completed implicitly by the state_processor() function via some internal
|
||||
* call to ftdm_set_state() */
|
||||
fchan->state_status = FTDM_STATE_STATUS_PROCESSED;
|
||||
}
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(int) ftdm_check_state_all(ftdm_span_t *span, ftdm_channel_state_t state)
|
||||
{
|
||||
uint32_t j;
|
||||
for(j = 1; j <= span->chan_count; j++) {
|
||||
if (span->channels[j]->state != state || ftdm_test_flag(span->channels[j], FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 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:
|
||||
*/
|
||||
@@ -56,7 +56,11 @@ struct ftdm_interrupt {
|
||||
/* for generic interruption */
|
||||
HANDLE event;
|
||||
#else
|
||||
/* for generic interruption */
|
||||
/* In theory we could be using thread conditions for generic interruption,
|
||||
* however, Linux does not have a primitive like Windows WaitForMultipleObjects
|
||||
* to wait for both thread condition and file descriptors, therefore we decided
|
||||
* to use a dummy pipe for generic interruption/condition logic
|
||||
* */
|
||||
int readfd;
|
||||
int writefd;
|
||||
#endif
|
||||
@@ -243,6 +247,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_mutex_unlock(ftdm_mutex_t *mutex)
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **ininterrupt, ftdm_socket_t device)
|
||||
{
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
ftdm_interrupt_t *interrupt = NULL;
|
||||
#ifndef WIN32
|
||||
int fds[2];
|
||||
@@ -253,7 +258,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **ininterrupt,
|
||||
interrupt = ftdm_calloc(1, sizeof(*interrupt));
|
||||
if (!interrupt) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to allocate interrupt memory\n");
|
||||
return FTDM_FAIL;
|
||||
return FTDM_ENOMEM;
|
||||
}
|
||||
|
||||
interrupt->device = device;
|
||||
@@ -261,11 +266,13 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **ininterrupt,
|
||||
interrupt->event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (!interrupt->event) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to allocate interrupt event\n");
|
||||
status = FTDM_ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
#else
|
||||
if (pipe(fds)) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to allocate interrupt pipe: %s\n", strerror(errno));
|
||||
status = FTDM_FAIL;
|
||||
goto failed;
|
||||
}
|
||||
interrupt->readfd = fds[0];
|
||||
@@ -287,7 +294,7 @@ failed:
|
||||
#endif
|
||||
ftdm_safe_free(interrupt);
|
||||
}
|
||||
return FTDM_FAIL;
|
||||
return status;
|
||||
}
|
||||
|
||||
#define ONE_BILLION 1000000000
|
||||
|
||||
@@ -37,7 +37,9 @@
|
||||
|
||||
typedef enum {
|
||||
FTDM_ANALOG_RUNNING = (1 << 0),
|
||||
FTDM_ANALOG_CALLERID = (1 << 1)
|
||||
FTDM_ANALOG_CALLERID = (1 << 1),
|
||||
FTDM_ANALOG_ANSWER_POLARITY_REVERSE = (1 << 2),
|
||||
FTDM_ANALOG_HANGUP_POLARITY_REVERSE = (1 << 3)
|
||||
} ftdm_analog_flag_t;
|
||||
|
||||
#define FTDM_MAX_HOTLINE_STR 20
|
||||
@@ -47,11 +49,13 @@ struct ftdm_analog_data {
|
||||
uint32_t flags;
|
||||
uint32_t max_dialstr;
|
||||
uint32_t wait_dialtone_timeout;
|
||||
uint32_t polarity_delay;
|
||||
uint32_t digit_timeout;
|
||||
char hotline[FTDM_MAX_HOTLINE_STR];
|
||||
};
|
||||
|
||||
|
||||
/* Analog flags to be set in the sflags (signaling flags) channel memeber */
|
||||
#define AF_POLARITY_REVERSE (1 << 0)
|
||||
|
||||
static void *ftdm_analog_run(ftdm_thread_t *me, void *obj);
|
||||
typedef struct ftdm_analog_data ftdm_analog_data_t;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -162,6 +184,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
|
||||
uint32_t digit_timeout = 10;
|
||||
uint32_t wait_dialtone_timeout = 30000;
|
||||
uint32_t max_dialstr = MAX_DTMF;
|
||||
uint32_t polarity_delay = 600;
|
||||
const char *var, *val;
|
||||
int *intval;
|
||||
uint32_t flags = FTDM_ANALOG_CALLERID;
|
||||
@@ -214,6 +237,29 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
|
||||
} else {
|
||||
flags &= ~FTDM_ANALOG_CALLERID;
|
||||
}
|
||||
} else if (!strcasecmp(var, "answer_polarity_reverse")) {
|
||||
if (!(val = va_arg(ap, char *))) {
|
||||
break;
|
||||
}
|
||||
if (ftdm_true(val)) {
|
||||
flags |= FTDM_ANALOG_ANSWER_POLARITY_REVERSE;
|
||||
} else {
|
||||
flags &= ~FTDM_ANALOG_ANSWER_POLARITY_REVERSE;
|
||||
}
|
||||
} else if (!strcasecmp(var, "hangup_polarity_reverse")) {
|
||||
if (!(val = va_arg(ap, char *))) {
|
||||
break;
|
||||
}
|
||||
if (ftdm_true(val)) {
|
||||
flags |= FTDM_ANALOG_HANGUP_POLARITY_REVERSE;
|
||||
} else {
|
||||
flags &= ~FTDM_ANALOG_HANGUP_POLARITY_REVERSE;
|
||||
}
|
||||
} else if (!strcasecmp(var, "polarity_delay")) {
|
||||
if (!(intval = va_arg(ap, int *))) {
|
||||
break;
|
||||
}
|
||||
polarity_delay = *intval;
|
||||
} else if (!strcasecmp(var, "callwaiting")) {
|
||||
if (!(intval = va_arg(ap, int *))) {
|
||||
break;
|
||||
@@ -254,6 +300,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
|
||||
analog_data->flags = flags;
|
||||
analog_data->digit_timeout = digit_timeout;
|
||||
analog_data->wait_dialtone_timeout = wait_dialtone_timeout;
|
||||
analog_data->polarity_delay = polarity_delay;
|
||||
analog_data->max_dialstr = max_dialstr;
|
||||
span->signal_cb = sig_cb;
|
||||
strncpy(analog_data->hotline, hotline, sizeof(analog_data->hotline));
|
||||
@@ -377,6 +424,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
ftdm_analog_data_t *analog_data = ftdmchan->span->signal_data;
|
||||
ftdm_channel_t *closed_chan;
|
||||
uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = analog_data->wait_dialtone_timeout;
|
||||
uint32_t answer_on_polarity_counter = 0;
|
||||
ftdm_sigmsg_t sig;
|
||||
ftdm_status_t status;
|
||||
|
||||
@@ -448,7 +496,12 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
if (ftdmchan->needed_tones[FTDM_TONEMAP_DIAL]) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
|
||||
} else {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
/* do not go up if we're waiting for polarity reversal */
|
||||
if (ftdm_test_flag(analog_data, FTDM_ANALOG_ANSWER_POLARITY_REVERSE)) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
} else {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -493,8 +546,10 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
|
||||
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_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;
|
||||
@@ -530,15 +585,37 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
|
||||
if (done) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
ftdm_clear_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK] = 0;
|
||||
}
|
||||
}
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
{
|
||||
ftdm_sleep(interval);
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) &&
|
||||
ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA &&
|
||||
ftdm_test_sflag(ftdmchan, AF_POLARITY_REVERSE)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Answering on polarity reverse\n");
|
||||
ftdm_clear_sflag(ftdmchan, AF_POLARITY_REVERSE);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
answer_on_polarity_counter = state_counter;
|
||||
} else if (ftdmchan->state == FTDM_CHANNEL_STATE_UP
|
||||
&& ftdm_test_sflag(ftdmchan, AF_POLARITY_REVERSE)){
|
||||
/* if this polarity reverse is close to the answer polarity reverse, ignore it */
|
||||
if (answer_on_polarity_counter
|
||||
&& (state_counter - answer_on_polarity_counter) > analog_data->polarity_delay) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Hanging up on polarity reverse\n");
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING,
|
||||
"Not hanging up on polarity reverse, too close to Answer reverse\n");
|
||||
}
|
||||
ftdm_clear_sflag(ftdmchan, AF_POLARITY_REVERSE);
|
||||
} else {
|
||||
ftdm_sleep(interval);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@@ -551,7 +628,6 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
ftdm_clear_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
indicate = 0;
|
||||
@@ -591,6 +667,19 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
sig.event_id = FTDM_SIGEVENT_UP;
|
||||
}
|
||||
|
||||
if (ftdmchan->type == FTDM_CHAN_TYPE_FXS &&
|
||||
!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) &&
|
||||
ftdm_test_flag(analog_data, FTDM_ANALOG_ANSWER_POLARITY_REVERSE)) {
|
||||
ftdm_polarity_t polarity = FTDM_POLARITY_REVERSE;
|
||||
if (ftdmchan->polarity == FTDM_POLARITY_FORWARD) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Reversing polarity on answer\n");
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_POLARITY, &polarity);
|
||||
} else {
|
||||
/* the polarity may be already reversed if this is the second time we
|
||||
* answer (ie, due to 2 calls being on the same line) */
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_span_send_signal(ftdmchan->span, &sig);
|
||||
continue;
|
||||
}
|
||||
@@ -615,6 +704,22 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_CHANNEL_STATE_HANGUP:
|
||||
/* this state is only used when the user hangup, if the device hang up (onhook) we currently
|
||||
* go straight to DOWN. If we ever change this (as other signaling modules do) by using this
|
||||
* state for both user and device hangup, we should check here for the type of hangup since
|
||||
* some actions (polarity reverse) do not make sense if the device hung up */
|
||||
if (ftdmchan->type == FTDM_CHAN_TYPE_FXS &&
|
||||
ftdmchan->last_state == FTDM_CHANNEL_STATE_UP &&
|
||||
ftdm_test_flag(analog_data, FTDM_ANALOG_HANGUP_POLARITY_REVERSE)) {
|
||||
ftdm_polarity_t polarity = ftdmchan->polarity == FTDM_POLARITY_REVERSE
|
||||
? FTDM_POLARITY_FORWARD : FTDM_POLARITY_REVERSE;
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Reversing polarity on hangup\n");
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_POLARITY, &polarity);
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
{
|
||||
sig.event_id = FTDM_SIGEVENT_STOP;
|
||||
@@ -717,7 +822,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;
|
||||
}
|
||||
@@ -823,6 +928,9 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
|
||||
done:
|
||||
|
||||
closed_chan = ftdmchan;
|
||||
|
||||
ftdm_channel_lock(closed_chan);
|
||||
|
||||
if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) {
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_ONHOOK, NULL);
|
||||
@@ -833,7 +941,8 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
}
|
||||
|
||||
|
||||
closed_chan = ftdmchan;
|
||||
ftdm_clear_sflag(ftdmchan, AF_POLARITY_REVERSE);
|
||||
|
||||
ftdm_channel_close(&ftdmchan);
|
||||
|
||||
ftdm_channel_command(closed_chan, FTDM_COMMAND_SET_NATIVE_CODEC, NULL);
|
||||
@@ -851,8 +960,11 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
}
|
||||
|
||||
ftdm_log_chan(closed_chan, FTDM_LOG_DEBUG, "ANALOG CHANNEL %d:%d thread ended.\n", closed_chan->span_id, closed_chan->chan_id);
|
||||
|
||||
ftdm_clear_flag(closed_chan, FTDM_CHANNEL_INTHREAD);
|
||||
|
||||
ftdm_channel_unlock(closed_chan);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -879,19 +991,32 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
|
||||
ftdm_mutex_lock(event->channel->mutex);
|
||||
locked++;
|
||||
|
||||
/* MAINTENANCE WARNING:
|
||||
* 1. Be aware you are working on the locked channel
|
||||
* 2. We should not be calling ftdm_span_send_signal or ftdm_set_state when there is already a channel thread running
|
||||
* however, since this is old code I am not changing it now, but new code should adhere to that convention
|
||||
* otherwise, we have possible races where we compete with the user for state changes, ie, the user requests
|
||||
* a state change and then we process an event, the state change from the user is pending so our ftdm_set_state
|
||||
* operation will fail. In cases where we win the race, our state change will be accepted but if a user requests
|
||||
* a state change before the state change we requested here is processed by the channel thread, we'll end up
|
||||
* rejecting the user request.
|
||||
*
|
||||
* See docs/locking.txt for further information about what guarantees should signaling modules provide when
|
||||
* locking/unlocking a channel
|
||||
* */
|
||||
switch(event->enum_id) {
|
||||
case FTDM_OOB_RING_START:
|
||||
{
|
||||
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);
|
||||
@@ -909,24 +1034,33 @@ 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)) {
|
||||
/* we do not need to process HANGUP since the device also hangup already */
|
||||
ftdm_channel_complete_state(event->channel);
|
||||
}
|
||||
ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN);
|
||||
}
|
||||
if (event->channel->type == FTDM_CHAN_TYPE_FXS) {
|
||||
/* we always return to forward when the device goes onhook */
|
||||
ftdm_polarity_t forward_polarity = FTDM_POLARITY_FORWARD;
|
||||
ftdm_channel_command(event->channel, FTDM_COMMAND_SET_POLARITY, &forward_polarity);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
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->span, FTDM_SPAN_STATE_CHANGE);
|
||||
ftdm_channel_complete_state(event->channel);
|
||||
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);
|
||||
@@ -940,12 +1074,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;
|
||||
@@ -957,9 +1091,53 @@ 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;
|
||||
case FTDM_OOB_POLARITY_REVERSE:
|
||||
{
|
||||
if (event->channel->type != FTDM_CHAN_TYPE_FXO) {
|
||||
ftdm_log_chan_msg(event->channel, FTDM_LOG_WARNING,
|
||||
"Ignoring polarity reversal, this should not happen in non-FXO channels!\n");
|
||||
break;
|
||||
}
|
||||
if (!ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD) &&
|
||||
ftdm_test_flag(event->channel, FTDM_CHANNEL_OFFHOOK)) {
|
||||
ftdm_log_chan_msg(event->channel, FTDM_LOG_WARNING,
|
||||
"Forcing onhook in channel not in thread after polarity reversal\n");
|
||||
ftdm_channel_command(event->channel, FTDM_COMMAND_ONHOOK, NULL);
|
||||
break;
|
||||
}
|
||||
if (!ftdm_test_flag(analog_data, FTDM_ANALOG_ANSWER_POLARITY_REVERSE)
|
||||
&& !ftdm_test_flag(analog_data, FTDM_ANALOG_HANGUP_POLARITY_REVERSE)) {
|
||||
ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG,
|
||||
"Ignoring polarity reversal because this channel is not configured for it\n");
|
||||
break;
|
||||
}
|
||||
if (event->channel->state == FTDM_CHANNEL_STATE_DOWN) {
|
||||
ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG,
|
||||
"Ignoring polarity reversal because this channel is down\n");
|
||||
break;
|
||||
}
|
||||
/* we have a good channel, set the polarity flag and let the channel thread deal with it */
|
||||
ftdm_set_sflag(event->channel, AF_POLARITY_REVERSE);
|
||||
}
|
||||
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));
|
||||
|
||||
@@ -355,7 +355,6 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
ftdm_clear_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
indicate = 0;
|
||||
@@ -467,7 +466,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;
|
||||
}
|
||||
|
||||
@@ -497,7 +497,7 @@ static ftdm_state_map_t isdn_state_map = {
|
||||
* \param ftdmchan Channel to handle
|
||||
* \note This function MUST be called with the channel locked
|
||||
*/
|
||||
static __inline__ void state_advance(ftdm_channel_t *chan)
|
||||
static ftdm_status_t state_advance(ftdm_channel_t *chan)
|
||||
{
|
||||
ftdm_libpri_data_t *isdn_data = chan->span->signal_data;
|
||||
q931_call *call = (q931_call *)chan->call_data;
|
||||
@@ -511,27 +511,23 @@ static __inline__ void state_advance(ftdm_channel_t *chan)
|
||||
sig.chan_id = ftdm_channel_get_id(chan);
|
||||
sig.span_id = ftdm_channel_get_span_id(chan);
|
||||
sig.channel = chan;
|
||||
|
||||
ftdm_channel_complete_state(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;
|
||||
@@ -631,7 +627,7 @@ static __inline__ void state_advance(ftdm_channel_t *chan)
|
||||
ftdm_channel_get_span_id(chan), ftdm_channel_get_id(chan));
|
||||
/* TODO: set hangup cause? */
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
|
||||
return;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ton = caller_data->dnis.type;
|
||||
@@ -714,6 +710,7 @@ static __inline__ void state_advance(ftdm_channel_t *chan)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -729,13 +726,8 @@ static __inline__ void check_state(ftdm_span_t *span)
|
||||
|
||||
for (j = 1; j <= ftdm_span_get_chan_count(span); j++) {
|
||||
ftdm_channel_t *chan = ftdm_span_get_channel(span, j);
|
||||
|
||||
ftdm_channel_lock(chan);
|
||||
while (ftdm_test_flag(chan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_clear_flag(chan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
state_advance(chan);
|
||||
ftdm_channel_complete_state(chan);
|
||||
}
|
||||
ftdm_channel_advance_states(chan);
|
||||
ftdm_channel_unlock(chan);
|
||||
}
|
||||
}
|
||||
@@ -1403,8 +1395,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 +1431,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);
|
||||
}
|
||||
@@ -1917,6 +1908,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
|
||||
span->outgoing_call = isdn_outgoing_call;
|
||||
|
||||
span->state_map = &isdn_state_map;
|
||||
span->state_processor = state_advance;
|
||||
|
||||
span->get_channel_sig_status = isdn_get_channel_sig_status;
|
||||
span->get_span_sig_status = isdn_get_span_sig_status;
|
||||
|
||||
@@ -127,9 +127,8 @@ 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;
|
||||
@@ -156,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
|
||||
|
||||
@@ -265,7 +265,7 @@ static ftdm_state_map_t pritap_state_map = {
|
||||
}
|
||||
};
|
||||
|
||||
static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
||||
static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ftdm_status_t status;
|
||||
ftdm_sigmsg_t sig;
|
||||
@@ -278,6 +278,8 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
||||
sig.span_id = ftdmchan->span_id;
|
||||
sig.channel = ftdmchan;
|
||||
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
{
|
||||
@@ -321,24 +323,20 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static __inline__ void pritap_check_state(ftdm_span_t *span)
|
||||
{
|
||||
if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE)) {
|
||||
uint32_t j;
|
||||
ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE);
|
||||
for(j = 1; j <= span->chan_count; j++) {
|
||||
if (ftdm_test_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_mutex_lock(span->channels[j]->mutex);
|
||||
ftdm_clear_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE);
|
||||
state_advance(span->channels[j]);
|
||||
ftdm_channel_complete_state(span->channels[j]);
|
||||
ftdm_mutex_unlock(span->channels[j]->mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE)) {
|
||||
uint32_t j;
|
||||
ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE);
|
||||
for(j = 1; j <= span->chan_count; j++) {
|
||||
ftdm_mutex_lock(span->channels[j]->mutex);
|
||||
ftdm_channel_advance_states(span->channels[j]);
|
||||
ftdm_mutex_unlock(span->channels[j]->mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int pri_io_read(struct pri *pri, void *buf, int buflen)
|
||||
@@ -896,6 +894,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span)
|
||||
span->get_span_sig_status = pritap_get_span_sig_status;
|
||||
|
||||
span->state_map = &pritap_state_map;
|
||||
span->state_processor = state_advance;
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
* Contributors:
|
||||
*
|
||||
* Arnaldo Pereira <arnaldo@sangoma.com>
|
||||
* Ricardo Barroetaveña <rbarroetavena@anura.com.ar>
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -49,10 +50,6 @@
|
||||
#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 user stops a span, we clear FTDM_R2_SPAN_STARTED, so that the signaling thread
|
||||
@@ -76,7 +73,6 @@ typedef struct ftdm_r2_call_t {
|
||||
int disconnect_rcvd:1;
|
||||
int ftdm_call_started:1;
|
||||
int protocol_error:1;
|
||||
ftdm_channel_state_t chanstate;
|
||||
ftdm_size_t dnis_index;
|
||||
ftdm_size_t ani_index;
|
||||
char logname[255];
|
||||
@@ -171,8 +167,7 @@ static ftdm_hash_t *g_mod_data_hash;
|
||||
/* IO interface for the command API */
|
||||
static ftdm_io_interface_t g_ftdm_r2_interface;
|
||||
|
||||
static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan);
|
||||
static void ftdm_r2_state_advance_all(ftdm_channel_t *ftdmchan);
|
||||
static ftdm_status_t ftdm_r2_state_advance(ftdm_channel_t *ftdmchan);
|
||||
|
||||
/* whether R2 call accept process is pending */
|
||||
#define IS_ACCEPTING_PENDING(ftdmchan) \
|
||||
@@ -352,7 +347,6 @@ static void ft_r2_clean_call(ftdm_r2_call_t *call)
|
||||
call->disconnect_rcvd = 0;
|
||||
call->ftdm_call_started = 0;
|
||||
call->protocol_error = 0;
|
||||
call->chanstate = FTDM_CHANNEL_STATE_DOWN;
|
||||
call->dnis_index = 0;
|
||||
call->ani_index = 0;
|
||||
call->name[0] = 0;
|
||||
@@ -380,11 +374,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;
|
||||
|
||||
@@ -397,6 +452,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);
|
||||
@@ -404,9 +465,10 @@ 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.cid_num.digits,
|
||||
ftdmchan->caller_data.dnis.digits,
|
||||
r2data->category);
|
||||
category,
|
||||
ftdmchan->caller_data.pres == FTDM_PRES_ALLOWED ? 0 : 1);
|
||||
|
||||
if (callstatus) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to make call in R2 channel, openr2_chan_make_call failed\n");
|
||||
@@ -414,7 +476,6 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call)
|
||||
}
|
||||
|
||||
R2CALL(ftdmchan)->ftdm_call_started = 1;
|
||||
R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN;
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DIALING);
|
||||
|
||||
ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS);
|
||||
@@ -456,19 +517,40 @@ static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_channel_sig_status)
|
||||
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_DOWN:
|
||||
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;
|
||||
}
|
||||
ftdm_r2_set_chan_sig_status(ftdmchan, status);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -484,10 +566,13 @@ static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_span_sig_status)
|
||||
*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;
|
||||
@@ -497,21 +582,6 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status)
|
||||
{
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *citer = NULL;
|
||||
uint32_t span_opr = -1;
|
||||
|
||||
/* we either set the channels to BLOCK or IDLE */
|
||||
switch(status) {
|
||||
case FTDM_SIG_STATE_DOWN:
|
||||
case FTDM_SIG_STATE_SUSPENDED:
|
||||
span_opr = 0;
|
||||
break;
|
||||
case FTDM_SIG_STATE_UP:
|
||||
span_opr = 1;
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
if (!chaniter) {
|
||||
@@ -521,15 +591,13 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status)
|
||||
/* 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);
|
||||
openr2_chan_t *r2chan = R2CALL(fchan)->r2chan;
|
||||
if (span_opr == 0) {
|
||||
openr2_chan_set_blocked(r2chan);
|
||||
ftdm_log_chan_msg(fchan, FTDM_LOG_NOTICE, "Channel blocked\n");
|
||||
} else {
|
||||
openr2_chan_set_idle(r2chan);
|
||||
ftdm_log_chan_msg(fchan, FTDM_LOG_NOTICE, "Channel idle\n");
|
||||
/* 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_r2_set_chan_sig_status(fchan, status);
|
||||
ftdm_channel_unlock(fchan);
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
return FTDM_SUCCESS;
|
||||
@@ -552,7 +620,7 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan)
|
||||
ftdm_sched_cancel_timer(r2data->sched, r2call->protocol_error_recovery_timer);
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Cancelled protocol error recovery timer\n");
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
ftdm_r2_state_advance_all(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,7 +654,6 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan)
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_OUTPUT_DUMP, &r2data->mf_dump_size);
|
||||
}
|
||||
|
||||
R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN;
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
|
||||
ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS);
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_TX_BUFFERS, NULL);
|
||||
@@ -595,12 +662,14 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan)
|
||||
|
||||
static void dump_mf(openr2_chan_t *r2chan);
|
||||
/* only called for incoming calls when the ANI, DNIS etc is complete and the user has to decide either to accept or reject the call */
|
||||
static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis, openr2_calling_party_category_t category)
|
||||
static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis,
|
||||
openr2_calling_party_category_t category, int ani_restricted)
|
||||
{
|
||||
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
|
||||
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_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Call offered with ANI = %s, DNIS = %s, Category = %d, ANI restricted = %s\n",
|
||||
ani, dnis, category, ani_restricted ? "Yes" : "No");
|
||||
|
||||
/* nothing went wrong during call setup, MF has ended, we can and must disable the MF dump */
|
||||
if (r2data->mf_dump_size) {
|
||||
@@ -615,6 +684,8 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons
|
||||
} else {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
}
|
||||
ftdmchan->caller_data.cpc = ftdm_openr2_cpc_to_r2_ftdm_cpc(category);
|
||||
ftdmchan->caller_data.pres = ani_restricted ? FTDM_PRES_RESTRICTED : FTDM_PRES_ALLOWED;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -632,12 +703,10 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons
|
||||
static void clear_accept_pending(ftdm_channel_t *fchan)
|
||||
{
|
||||
if (IS_ACCEPTING_PENDING(fchan)) {
|
||||
ftdm_clear_flag(fchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
ftdm_channel_complete_state(fchan);
|
||||
} else if (ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_log_chan(fchan, FTDM_LOG_CRIT, "State change flag set in state %s, last state = %s\n",
|
||||
ftdm_channel_state2str(fchan->state), ftdm_channel_state2str(fchan->last_state));
|
||||
ftdm_clear_flag(fchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
ftdm_channel_complete_state(fchan);
|
||||
}
|
||||
}
|
||||
@@ -745,7 +814,7 @@ static void ftdm_r2_on_call_end(openr2_chan_t *r2chan)
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
|
||||
/* in some circumstances openr2 can call on_call_init right after this, so let's advance the state right here */
|
||||
ftdm_r2_state_advance_all(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
}
|
||||
|
||||
static void ftdm_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf, int buflen)
|
||||
@@ -777,7 +846,7 @@ static void ftdm_r2_recover_from_protocol_error(void *data)
|
||||
goto done;
|
||||
}
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
ftdm_r2_state_advance_all(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
done:
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
}
|
||||
@@ -1158,6 +1227,18 @@ static openr2_log_level_t ftdm_r2_loglevel_from_string(const char *level)
|
||||
|
||||
static ftdm_state_map_t r2_state_map = {
|
||||
{
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_ANY_STATE, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_RESET, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_RESET, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_DOWN, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
@@ -1209,6 +1290,20 @@ static ftdm_state_map_t r2_state_map = {
|
||||
|
||||
/* Outbound states */
|
||||
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_ANY_STATE, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_RESET, FTDM_END}
|
||||
},
|
||||
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_RESET, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_DOWN, FTDM_END}
|
||||
},
|
||||
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
@@ -1515,10 +1610,14 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling)
|
||||
span->set_channel_sig_status = ftdm_r2_set_channel_sig_status;
|
||||
|
||||
span->state_map = &r2_state_map;
|
||||
span->state_processor = ftdm_r2_state_advance;
|
||||
|
||||
/* use signals queue */
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE);
|
||||
|
||||
/* we can skip states (going straight from RING to UP) */
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_SKIP_STATES);
|
||||
|
||||
/* setup the scheduler */
|
||||
snprintf(schedname, sizeof(schedname), "ftmod_r2_%s", span->name);
|
||||
ftdm_assert(ftdm_sched_create(&r2data->sched, schedname) == FTDM_SUCCESS, "Failed to create schedule!\n");
|
||||
@@ -1541,10 +1640,10 @@ fail:
|
||||
}
|
||||
|
||||
/* the channel must be locked when calling this function */
|
||||
static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
|
||||
static ftdm_status_t ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ftdm_sigmsg_t sigev;
|
||||
int ret;
|
||||
ftdm_status_t ret;
|
||||
ftdm_r2_call_t *r2call = R2CALL(ftdmchan);
|
||||
openr2_chan_t *r2chan = r2call->r2chan;
|
||||
ftdm_r2_data_t *r2data = ftdmchan->span->signal_data;
|
||||
@@ -1554,172 +1653,173 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
|
||||
sigev.span_id = ftdmchan->span_id;
|
||||
sigev.channel = ftdmchan;
|
||||
|
||||
ret = 0;
|
||||
ret = FTDM_SUCCESS;
|
||||
|
||||
/* because we do not always acknowledge the state change (clearing the FTDM_CHANNEL_STATE_CHANGE flag) due to the accept
|
||||
* procedure described below, we need the chanstate member to NOT process some states twice, so is valid entering this
|
||||
* function with the FTDM_CHANNEL_STATE_CHANGE flag set but with a state that was already processed and is just waiting
|
||||
* to complete (the processing is media-bound)
|
||||
* */
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)
|
||||
&& (r2call->chanstate != ftdmchan->state)) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Executing state handler for %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Executing state handler for %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
r2call->chanstate = ftdmchan->state;
|
||||
|
||||
if (IS_ACCEPTING_PENDING(ftdmchan)) {
|
||||
/*
|
||||
Moving to PROGRESS, PROGRESS_MEDIA or UP means that we must accept the call first, and accepting
|
||||
the call in R2 means sending a tone, then waiting for the acknowledge from the other end,
|
||||
since all of that requires sending and detecting tones, it takes a few milliseconds (I'd say around 100)
|
||||
which means during that time the user should not try to perform any operations like answer, hangup or anything
|
||||
else, therefore we DO NOT clear the FTDM_CHANNEL_STATE_CHANGE flag here, we rely on ftdm_io.c to block
|
||||
the user thread until we're done with the accept (see on_call_accepted callback) and then we clear the state change flag,
|
||||
otherwise we have a race condition between freetdm calling openr2_chan_answer_call and openr2 accepting the call first,
|
||||
if freetdm calls openr2_chan_answer_call before the accept cycle completes, openr2 will fail to answer the call */
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "State ack for state %s will have to wait a bit\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
} else if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN){
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
}
|
||||
|
||||
switch (ftdmchan->state) {
|
||||
|
||||
/* starting an incoming call */
|
||||
case FTDM_CHANNEL_STATE_COLLECT:
|
||||
{
|
||||
uint32_t interval = 0;
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval);
|
||||
ftdm_assert(interval != 0, "Invalid interval!");
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Starting processing of incoming call with interval %d\n", interval);
|
||||
openr2_chan_enable_read(r2chan);
|
||||
}
|
||||
break;
|
||||
|
||||
/* starting an outgoing call */
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
{
|
||||
uint32_t interval = 0;
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval);
|
||||
ftdm_assert(interval != 0, "Invalid interval!");
|
||||
ftdm_log_chan(ftdmchan,
|
||||
FTDM_LOG_DEBUG, "Starting processing of outgoing call in channel with interval %d\n", interval);
|
||||
openr2_chan_enable_read(r2chan);
|
||||
}
|
||||
break;
|
||||
|
||||
/* incoming call was offered */
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
|
||||
/* notify the user about the new call */
|
||||
sigev.event_id = FTDM_SIGEVENT_START;
|
||||
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
r2call->ftdm_call_started = 1;
|
||||
|
||||
break;
|
||||
|
||||
/* the call is making progress */
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
{
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
if (!r2call->accepted) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Accepting call\n");
|
||||
ft_r2_accept_call(ftdmchan);
|
||||
}
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying progress\n");
|
||||
sigev.event_id = FTDM_SIGEVENT_PROCEED;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* the call was answered */
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
{
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call was answered\n");
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
if (!r2call->accepted) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call has not been accepted, need to accept first\n");
|
||||
// the answering will be done in the on_call_accepted handler
|
||||
ft_r2_accept_call(ftdmchan);
|
||||
r2call->answer_pending = 1;
|
||||
} else {
|
||||
ft_r2_answer_call(ftdmchan);
|
||||
}
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying of call answered\n");
|
||||
sigev.event_id = FTDM_SIGEVENT_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* just got hangup */
|
||||
case FTDM_CHANNEL_STATE_HANGUP:
|
||||
{
|
||||
if (!r2call->disconnect_rcvd) {
|
||||
openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause));
|
||||
/* this will disconnect the call, but need to wait for the call end before moving to DOWN */
|
||||
openr2_chan_disconnect_call(r2chan, disconnect_cause);
|
||||
} else if (!r2call->protocol_error) {
|
||||
/* just ack the hangup, on_call_end will be called by openr2 right after */
|
||||
openr2_chan_disconnect_call(r2chan, OR2_CAUSE_NORMAL_CLEARING);
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Clearing call due to protocol error\n");
|
||||
/* do not set to down yet, give some time for recovery */
|
||||
ftdm_sched_timer(r2data->sched, "protocolerr_recover", 100,
|
||||
ftdm_r2_recover_from_protocol_error, r2chan, &r2call->protocol_error_recovery_timer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_CHANNEL_STATE_TERMINATING:
|
||||
{
|
||||
/* if the call has not been started yet we must go to HANGUP right here */
|
||||
if (!r2call->ftdm_call_started) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
} else {
|
||||
openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause));
|
||||
/* notify the user of the call terminating and we wait for the user to move us to hangup */
|
||||
sigev.event_id = FTDM_SIGEVENT_STOP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* finished call for good */
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
{
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "R2 Call is down\n");
|
||||
ret = 1;
|
||||
}
|
||||
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));
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
if (IS_ACCEPTING_PENDING(ftdmchan)) {
|
||||
/*
|
||||
Moving to PROGRESS, PROGRESS_MEDIA or UP means that we must accept the call first, and accepting
|
||||
the call in R2 means sending a tone, then waiting for the acknowledge from the other end,
|
||||
since all of that requires sending and detecting tones, it takes a few milliseconds (I'd say around 100)
|
||||
which means during that time the user should not try to perform any operations like answer, hangup or anything
|
||||
else, therefore we DO NOT clear the FTDM_CHANNEL_STATE_CHANGE flag here, we rely on ftdm_io.c to block
|
||||
the user thread until we're done with the accept (see on_call_accepted callback) and then we clear the state change flag,
|
||||
otherwise we have a race condition between freetdm calling openr2_chan_answer_call and openr2 accepting the call first,
|
||||
if freetdm calls openr2_chan_answer_call before the accept cycle completes, openr2 will fail to answer the call */
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "State ack for state %s will have to wait a bit\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
} else if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN){
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
switch (ftdmchan->state) {
|
||||
|
||||
/* starting an incoming call */
|
||||
case FTDM_CHANNEL_STATE_COLLECT:
|
||||
{
|
||||
uint32_t interval = 0;
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval);
|
||||
ftdm_assert(interval != 0, "Invalid interval!");
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Starting processing of incoming call with interval %d\n", interval);
|
||||
openr2_chan_enable_read(r2chan);
|
||||
}
|
||||
break;
|
||||
|
||||
/* starting an outgoing call */
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
{
|
||||
uint32_t interval = 0;
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval);
|
||||
ftdm_assert(interval != 0, "Invalid interval!");
|
||||
ftdm_log_chan(ftdmchan,
|
||||
FTDM_LOG_DEBUG, "Starting processing of outgoing call in channel with interval %d\n", interval);
|
||||
openr2_chan_enable_read(r2chan);
|
||||
}
|
||||
break;
|
||||
|
||||
/* incoming call was offered */
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
|
||||
/* notify the user about the new call */
|
||||
sigev.event_id = FTDM_SIGEVENT_START;
|
||||
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
r2call->ftdm_call_started = 1;
|
||||
|
||||
break;
|
||||
|
||||
/* the call is making progress */
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
{
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
if (!r2call->accepted) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Accepting call\n");
|
||||
ft_r2_accept_call(ftdmchan);
|
||||
}
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying progress\n");
|
||||
sigev.event_id = FTDM_SIGEVENT_PROCEED;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* the call was answered */
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
{
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call was answered\n");
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
if (!r2call->accepted) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call has not been accepted, need to accept first\n");
|
||||
// the answering will be done in the on_call_accepted handler
|
||||
ft_r2_accept_call(ftdmchan);
|
||||
r2call->answer_pending = 1;
|
||||
} else {
|
||||
ft_r2_answer_call(ftdmchan);
|
||||
}
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying of call answered\n");
|
||||
sigev.event_id = FTDM_SIGEVENT_UP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* just got hangup */
|
||||
case FTDM_CHANNEL_STATE_HANGUP:
|
||||
{
|
||||
if (!r2call->disconnect_rcvd) {
|
||||
openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause));
|
||||
/* this will disconnect the call, but need to wait for the call end before moving to DOWN */
|
||||
openr2_chan_disconnect_call(r2chan, disconnect_cause);
|
||||
} else if (!r2call->protocol_error) {
|
||||
/* just ack the hangup, on_call_end will be called by openr2 right after */
|
||||
openr2_chan_disconnect_call(r2chan, OR2_CAUSE_NORMAL_CLEARING);
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Clearing call due to protocol error\n");
|
||||
/* do not set to down yet, give some time for recovery */
|
||||
ftdm_sched_timer(r2data->sched, "protocolerr_recover", 100,
|
||||
ftdm_r2_recover_from_protocol_error, r2chan, &r2call->protocol_error_recovery_timer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_CHANNEL_STATE_TERMINATING:
|
||||
{
|
||||
/* if the call has not been started yet we must go to HANGUP right here */
|
||||
if (!r2call->ftdm_call_started) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
} else {
|
||||
openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause));
|
||||
/* notify the user of the call terminating and we wait for the user to move us to hangup */
|
||||
sigev.event_id = FTDM_SIGEVENT_STOP;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* finished call for good */
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
{
|
||||
if (ftdmchan->last_state != FTDM_CHANNEL_STATE_RESET) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "R2 Call is down\n");
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "R2 Reset Complete\n");
|
||||
}
|
||||
ret = FTDM_BREAK;
|
||||
}
|
||||
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;
|
||||
|
||||
/* put the r2 channel back to IDLE, close ftdmchan and set it's state as DOWN */
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
{
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "RESET indicated, putting the R2 channel back to IDLE\n");
|
||||
openr2_chan_set_idle(r2chan);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Unhandled channel state change: %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == FTDM_BREAK) {
|
||||
ftdm_channel_t *closed_chan;
|
||||
closed_chan = ftdmchan;
|
||||
ftdm_channel_close(&closed_chan);
|
||||
@@ -1728,20 +1828,6 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* the channel must be locked when calling this function */
|
||||
static void ftdm_r2_state_advance_all(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
/* because we do not always acknowledge the state change (clearing the FTDM_CHANNEL_STATE_CHANGE flag) due to the accept
|
||||
* procedure described below, we need the chanstate member to NOT process some states twice, so is valid entering this
|
||||
* function with the FTDM_CHANNEL_STATE_CHANGE flag set but with a state that was already processed and is just waiting
|
||||
* to complete (the processing is media-bound)
|
||||
* */
|
||||
while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)
|
||||
&& (R2CALL(ftdmchan)->chanstate != ftdmchan->state)) {
|
||||
ftdm_r2_state_advance(ftdmchan);
|
||||
}
|
||||
}
|
||||
|
||||
static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
||||
{
|
||||
openr2_chan_t *r2chan = NULL;
|
||||
@@ -1776,10 +1862,12 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
||||
}
|
||||
for (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) {
|
||||
ftdmchan = ftdm_iterator_current(citer);
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
r2chan = R2CALL(ftdmchan)->r2chan;
|
||||
openr2_chan_set_span_id(r2chan, span->span_id);
|
||||
openr2_chan_set_idle(r2chan);
|
||||
openr2_chan_process_cas_signaling(r2chan);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &txqueue_size);
|
||||
}
|
||||
|
||||
@@ -1861,7 +1949,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
||||
for ( ; citer; citer = ftdm_iterator_next(citer)) {
|
||||
ftdmchan = ftdm_iterator_current(citer);
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
|
||||
call = R2CALL(ftdmchan);
|
||||
|
||||
@@ -1870,12 +1958,12 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED);
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TX_DISABLED);
|
||||
|
||||
ftdm_r2_state_advance_all(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
|
||||
r2chan = call->r2chan;
|
||||
openr2_chan_process_signaling(r2chan);
|
||||
|
||||
ftdm_r2_state_advance_all(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
|
||||
if (!call->accepted) {
|
||||
/* if the call is not accepted we do not want users reading */
|
||||
@@ -1883,7 +1971,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_TX_DISABLED);
|
||||
}
|
||||
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1891,8 +1979,10 @@ done:
|
||||
citer = ftdm_span_get_chan_iterator(span, chaniter);
|
||||
for ( ; citer; citer = ftdm_iterator_next(citer)) {
|
||||
ftdmchan = ftdm_iterator_current(citer);
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
r2chan = R2CALL(ftdmchan)->r2chan;
|
||||
openr2_chan_set_blocked(r2chan);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
}
|
||||
|
||||
ftdm_iterator_free(chaniter);
|
||||
@@ -1947,6 +2037,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;
|
||||
@@ -2130,14 +2228,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");
|
||||
@@ -2163,7 +2253,7 @@ static FIO_API_FUNCTION(ftdm_r2_api)
|
||||
}
|
||||
}
|
||||
|
||||
stream->write_function(stream, "-ERR invalid command.\n");
|
||||
stream->write_function(stream, "%s", FT_SYNTAX);
|
||||
|
||||
done:
|
||||
|
||||
@@ -2192,7 +2282,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;
|
||||
}
|
||||
|
||||
@@ -2212,7 +2301,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -951,7 +951,6 @@ static void handle_call_answer(ftdm_span_t *span, sangomabc_connection_t *mcon,
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ void advance_chan_states(ftdm_channel_t *ftdmchan);
|
||||
static __inline__ void stop_loop(ftdm_channel_t *ftdmchan);
|
||||
|
||||
/**
|
||||
@@ -1002,7 +1001,7 @@ tryagain:
|
||||
} else if (ftdmchan->state == FTDM_CHANNEL_STATE_IN_LOOP && retry) {
|
||||
retry = 0;
|
||||
stop_loop(ftdmchan);
|
||||
advance_chan_states(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
goto tryagain;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "s%dc%d: rejecting incoming call in channel state %s\n",
|
||||
@@ -1267,7 +1266,7 @@ static ftdm_channel_t* event_process_states(ftdm_span_t *span, sangomabc_short_e
|
||||
}
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
advance_chan_states(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
return ftdmchan;
|
||||
}
|
||||
|
||||
@@ -1354,11 +1353,11 @@ static int parse_sangoma_event(ftdm_span_t *span, sangomabc_connection_t *mcon,
|
||||
}
|
||||
|
||||
if(ftdmchan != NULL) {
|
||||
advance_chan_states(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -1366,7 +1365,7 @@ static int parse_sangoma_event(ftdm_span_t *span, sangomabc_connection_t *mcon,
|
||||
* \brief Handler for channel state change
|
||||
* \param ftdmchan Channel to handle
|
||||
*/
|
||||
static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
|
||||
static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data;
|
||||
sangomabc_connection_t *mcon = &sangoma_boost_data->mcon;
|
||||
@@ -1374,12 +1373,6 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
|
||||
ftdm_status_t status;
|
||||
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
} else {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_assert_return(ftdmchan->last_state != ftdmchan->state, FTDM_FAIL, "Channel state already processed\n");
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%d:%d PROCESSING STATE [%s]\n", ftdmchan->span_id, ftdmchan->chan_id, ftdm_channel_state2str(ftdmchan->state));
|
||||
@@ -1389,6 +1382,8 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
|
||||
sig.span_id = ftdmchan->span_id;
|
||||
sig.channel = ftdmchan;
|
||||
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
{
|
||||
@@ -1640,24 +1635,15 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static __inline__ void advance_chan_states(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
state_advance(ftdmchan);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialises outgoing requests array
|
||||
*/
|
||||
static __inline__ void init_outgoing_array(void)
|
||||
{
|
||||
memset(&OUTBOUND_REQUESTS, 0, sizeof(OUTBOUND_REQUESTS));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1685,7 +1671,7 @@ static __inline__ void check_state(ftdm_span_t *span)
|
||||
if (susp && span->channels[j]->state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
ftdm_set_state(span->channels[j], FTDM_CHANNEL_STATE_RESTART);
|
||||
}
|
||||
state_advance(span->channels[j]);
|
||||
ftdm_channel_advance_states(span->channels[j]);
|
||||
ftdm_mutex_unlock(span->channels[j]->mutex);
|
||||
}
|
||||
}
|
||||
@@ -1695,7 +1681,7 @@ static __inline__ void check_state(ftdm_span_t *span)
|
||||
* but without taking the chan out of the queue, so check th
|
||||
* flag before advancing the state */
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
state_advance(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
}
|
||||
}
|
||||
@@ -2478,7 +2464,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;
|
||||
}
|
||||
@@ -2687,6 +2673,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_boost_configure_span)
|
||||
span->get_span_sig_status = sangoma_boost_get_span_sig_status;
|
||||
span->set_span_sig_status = sangoma_boost_set_span_sig_status;
|
||||
span->state_map = &boost_state_map;
|
||||
span->state_processor = state_advance;
|
||||
sangoma_boost_data->mcon.debuglevel = FTDM_LOG_LEVEL_DEBUG;
|
||||
sangoma_boost_data->pcon.debuglevel = FTDM_LOG_LEVEL_DEBUG;
|
||||
ftdm_clear_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -40,11 +40,12 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""C:\Program Files\libsng_isdn\include";"C:\Program Files\libsng_isdn\include\sng_isdn";../../include;"C:\Program Files\Sangoma\include""
|
||||
AdditionalIncludeDirectories=""C:\Program Files\sangoma\sng_isdn\include";../../include;"C:\Program Files\Sangoma\include""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
|
||||
MinimalRebuild="true"
|
||||
ExceptionHandling="0"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
@@ -63,7 +64,7 @@
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="freetdm.lib libsng_isdn.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""$(OutDir)";"C:\Program Files\libsng_isdn\lib";"C:\Program Files\Sangoma\api\lib\x86""
|
||||
AdditionalLibraryDirectories=""$(OutDir)";"C:\Program Files\sangoma\sng_isdn\lib";"C:\Program Files\Sangoma\api\lib\x86""
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
RandomizedBaseAddress="1"
|
||||
@@ -116,10 +117,11 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""C:\Program Files\sangoma\sng_isdn\include";../../include;"C:\Program Files\Sangoma\include""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
@@ -136,7 +138,9 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="freetdm.lib libsng_isdn.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""$(OutDir)";"C:\Program Files\sangoma\sng_isdn\lib";"C:\Program Files\Sangoma\api\lib\x86""
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\libsng_isdn\include;C:\Program Files\libsng_isdn\include\sng_isdn;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<ExceptionHandling>
|
||||
@@ -95,10 +95,11 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\libsng_isdn\lib;C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\sangoma\sng_isdn\lib;C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
@@ -110,7 +111,7 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\libsng_isdn\include;C:\Program Files\libsng_isdn\include\sng_isdn;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>
|
||||
</ExceptionHandling>
|
||||
@@ -119,6 +120,7 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
@@ -135,11 +137,13 @@
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -147,23 +151,27 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<AdditionalDependencies>freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\sangoma\sng_isdn\lib;C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<AdditionalDependencies>freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -46,10 +46,9 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span);
|
||||
static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span);
|
||||
|
||||
ftdm_channel_t* ftdm_sangoma_isdn_process_event_states(ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event);
|
||||
static void ftdm_sangoma_isdn_advance_chan_states(ftdm_channel_t *ftdmchan);
|
||||
static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span);
|
||||
static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event);
|
||||
static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan);
|
||||
static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan);
|
||||
static void ftdm_sangoma_isdn_process_stack_event (ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event);
|
||||
static void ftdm_sangoma_isdn_wakeup_phy(ftdm_channel_t *dchan);
|
||||
static void ftdm_sangoma_isdn_dchan_set_queue_size(ftdm_channel_t *ftdmchan);
|
||||
@@ -270,13 +269,6 @@ ftdm_state_map_t sangoma_isdn_state_map = {
|
||||
}
|
||||
};
|
||||
|
||||
static __inline__ void ftdm_sangoma_isdn_advance_chan_states(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_sangoma_isdn_process_state_change(ftdmchan);
|
||||
}
|
||||
}
|
||||
|
||||
static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
|
||||
@@ -457,7 +449,7 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
|
||||
while ((ftdmchan = ftdm_queue_dequeue(span->pendingchans))) {
|
||||
/* double check that this channel has a state change pending */
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
ftdm_sangoma_isdn_advance_chan_states(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
}
|
||||
|
||||
@@ -470,11 +462,11 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
|
||||
/* twiddle */
|
||||
break;
|
||||
case FTDM_FAIL:
|
||||
ftdm_log(FTDM_LOG_ERROR,"%s:ftdm_interrupt_wait returned error!\n", span->name);
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s: ftdm_interrupt_wait returned error!\n", span->name);
|
||||
break;
|
||||
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR,"%s:ftdm_interrupt_wait returned with unknown code\n", span->name);
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s: ftdm_interrupt_wait returned with unknown code\n", span->name);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -536,7 +528,7 @@ ftdm_channel_t* ftdm_sangoma_isdn_process_event_states(ftdm_span_t *span, sngisd
|
||||
break;
|
||||
}
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
ftdm_sangoma_isdn_advance_chan_states(ftdmchan);
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
return ftdmchan;
|
||||
}
|
||||
|
||||
@@ -600,13 +592,14 @@ static void ftdm_sangoma_isdn_process_stack_event (ftdm_span_t *span, sngisdn_ev
|
||||
sngisdn_process_rst_ind(sngisdn_event);
|
||||
break;
|
||||
}
|
||||
if(ftdmchan != NULL) {
|
||||
ftdm_sangoma_isdn_advance_chan_states(ftdmchan);
|
||||
if (ftdmchan != NULL) {
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
}
|
||||
}
|
||||
|
||||
static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
||||
/* this function is called with the channel already locked by the core */
|
||||
static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ftdm_sigmsg_t sigev;
|
||||
ftdm_channel_state_t initial_state;
|
||||
@@ -618,13 +611,12 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
||||
sigev.span_id = ftdmchan->span_id;
|
||||
sigev.channel = ftdmchan;
|
||||
|
||||
/*first lock the channel*/
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
/*clear the state change flag...since we might be setting a new state*/
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
/* Acknowledge the state change */
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
|
||||
#ifdef FTDM_DEBUG_CHAN_MEMORY
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) {
|
||||
ftdm_assert(mprotect(ftdmchan, sizeof(*ftdmchan), PROT_READ)==0, "Failed to mprotect");
|
||||
ftdm_assert(mprotect(ftdmchan, sizeof(*ftdmchan), PROT_READ) == 0, "Failed to mprotect");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -879,11 +871,10 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
||||
}
|
||||
#ifdef FTDM_DEBUG_CHAN_MEMORY
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) {
|
||||
ftdm_assert(mprotect(ftdmchan, sizeof(*ftdmchan), PROT_READ|PROT_WRITE)==0, "Failed to mprotect");
|
||||
ftdm_assert(mprotect(ftdmchan, sizeof(*ftdmchan), PROT_READ|PROT_WRITE) == 0, "Failed to mprotect");
|
||||
}
|
||||
#endif
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
return;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static FIO_CHANNEL_SEND_MSG_FUNCTION(ftdm_sangoma_isdn_send_msg)
|
||||
@@ -1098,6 +1089,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
|
||||
span->get_span_sig_status = ftdm_sangoma_isdn_get_span_sig_status;
|
||||
span->set_span_sig_status = ftdm_sangoma_isdn_set_span_sig_status;
|
||||
span->state_map = &sangoma_isdn_state_map;
|
||||
span->state_processor = ftdm_sangoma_isdn_process_state_change;
|
||||
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);
|
||||
|
||||
@@ -137,8 +137,9 @@ void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t d
|
||||
ftdm_assert(raw_data, "Failed to malloc");
|
||||
|
||||
memcpy(raw_data, data, data_len);
|
||||
sigev.raw_data = raw_data;
|
||||
sigev.raw_data_len = 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);
|
||||
}
|
||||
|
||||
@@ -250,8 +251,9 @@ void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t d
|
||||
ftdm_assert(raw_data, "Failed to malloc");
|
||||
|
||||
memcpy(raw_data, data, data_len);
|
||||
sigev.raw_data = raw_data;
|
||||
sigev.raw_data_len = 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ ftdm_sngss7_data_t g_ftdm_sngss7_data;
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
static void *ftdm_sangoma_ss7_run (ftdm_thread_t * me, void *obj);
|
||||
void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan);
|
||||
static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event);
|
||||
|
||||
static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span);
|
||||
@@ -308,9 +307,7 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
/* process state changes for this channel until they are all done */
|
||||
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_sangoma_ss7_process_state_change (ftdmchan);
|
||||
}
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
|
||||
/* unlock the channel */
|
||||
ftdm_mutex_unlock (ftdmchan->mutex);
|
||||
@@ -403,9 +400,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
/* while there's a state change present on this channel process it */
|
||||
while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_sangoma_ss7_process_state_change(ftdmchan);
|
||||
}
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
|
||||
/* figure out the type of event and send it to the right handler */
|
||||
switch (sngss7_event->event_id) {
|
||||
@@ -468,9 +463,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
|
||||
} /* switch (sngss7_event->event_id) */
|
||||
|
||||
/* while there's a state change present on this channel process it */
|
||||
while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_sangoma_ss7_process_state_change(ftdmchan);
|
||||
}
|
||||
ftdm_channel_advance_states(ftdmchan);
|
||||
|
||||
/* unlock the channel */
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
@@ -479,7 +472,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
sng_isup_inf_t *isup_intf = NULL;
|
||||
@@ -495,7 +488,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
SS7_DEBUG_CHAN(ftdmchan, "ftmod_sangoma_ss7 processing state %s\n", ftdm_channel_state2str (ftdmchan->state));
|
||||
|
||||
/* clear the state change flag...since we might be setting a new state */
|
||||
ftdm_clear_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
|
||||
/*check what state we are supposed to be in */
|
||||
switch (ftdmchan->state) {
|
||||
@@ -1212,7 +1205,7 @@ suspend_goto_restart:
|
||||
/**************************************************************************/
|
||||
}/*switch (ftdmchan->state) */
|
||||
|
||||
return;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -1476,6 +1469,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config)
|
||||
span->get_channel_sig_status = ftdm_sangoma_ss7_get_sig_status;
|
||||
span->set_channel_sig_status = ftdm_sangoma_ss7_set_sig_status;
|
||||
span->state_map = &sangoma_ss7_state_map;
|
||||
span->state_processor = ftdm_sangoma_ss7_process_state_change;
|
||||
span->signal_data = ss7_span_info;
|
||||
|
||||
/* set the flag to indicate that this span uses channel state change queues */
|
||||
|
||||
@@ -452,7 +452,7 @@ extern int cmbLinkSetId;
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
/* in ftmod_sangoma_ss7_main.c */
|
||||
void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan);
|
||||
ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan);
|
||||
|
||||
/* in ftmod_sangoma_ss7_logger.c */
|
||||
void handle_sng_log(uint8_t level, char *fmt,...);
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>freetdm.lib;libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -127,7 +127,7 @@
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>freetdm.lib;libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\Sangoma\api\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -148,7 +148,7 @@
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>freetdm.lib;libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -174,7 +174,7 @@
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>freetdm.lib;libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>libsangoma.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\Sangoma\api\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
||||
@@ -784,17 +784,27 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
|
||||
err = sangoma_set_tx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size);
|
||||
}
|
||||
break;
|
||||
case FTDM_COMMAND_SET_POLARITY:
|
||||
{
|
||||
ftdm_polarity_t polarity = FTDM_COMMAND_OBJ_INT;
|
||||
err = sangoma_tdm_set_polarity(ftdmchan->sockfd, &tdm_api, polarity);
|
||||
if (!err) {
|
||||
ftdmchan->polarity = polarity;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
err = FTDM_NOTIMPL;
|
||||
break;
|
||||
};
|
||||
|
||||
if (err) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno));
|
||||
int myerrno = errno;
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Wanpipe failed to execute command %d: %s\n", command, strerror(myerrno));
|
||||
errno = myerrno;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1224,6 +1234,131 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms)
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Process an event in a channel and set it's OOB event id. The channel must be locked.
|
||||
* \param fchan Channel in which event occured
|
||||
* \param event_id Pointer where we save the OOB event id
|
||||
* \param tdm_api Wanpipe tdm struct that contain the event
|
||||
* \return FTDM_SUCCESS or FTDM_FAIL
|
||||
*/
|
||||
static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fchan, ftdm_oob_event_t *event_id, wanpipe_tdm_api_t *tdm_api)
|
||||
{
|
||||
switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type) {
|
||||
case WP_API_EVENT_LINK_STATUS:
|
||||
{
|
||||
switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
|
||||
case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
|
||||
*event_id = FTDM_OOB_ALARM_CLEAR;
|
||||
break;
|
||||
default:
|
||||
*event_id = FTDM_OOB_ALARM_TRAP;
|
||||
break;
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
||||
case WP_API_EVENT_RXHOOK:
|
||||
{
|
||||
if (fchan->type == FTDM_CHAN_TYPE_FXS) {
|
||||
*event_id = tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_OFFHOOK : FTDM_OOB_ONHOOK;
|
||||
if (*event_id == FTDM_OOB_OFFHOOK) {
|
||||
if (ftdm_test_flag(fchan, FTDM_CHANNEL_FLASH)) {
|
||||
ftdm_clear_flag(fchan, FTDM_CHANNEL_FLASH);
|
||||
ftdm_clear_flag(fchan, FTDM_CHANNEL_WINK);
|
||||
*event_id = FTDM_OOB_FLASH;
|
||||
goto event;
|
||||
} else {
|
||||
ftdm_set_flag(fchan, FTDM_CHANNEL_WINK);
|
||||
}
|
||||
} else {
|
||||
if (ftdm_test_flag(fchan, FTDM_CHANNEL_WINK)) {
|
||||
ftdm_clear_flag(fchan, FTDM_CHANNEL_WINK);
|
||||
ftdm_clear_flag(fchan, FTDM_CHANNEL_FLASH);
|
||||
*event_id = FTDM_OOB_WINK;
|
||||
goto event;
|
||||
} else {
|
||||
ftdm_set_flag(fchan, FTDM_CHANNEL_FLASH);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
ftdm_status_t status;
|
||||
wanpipe_tdm_api_t onhook_tdm_api;
|
||||
memset(&onhook_tdm_api, 0, sizeof(onhook_tdm_api));
|
||||
status = sangoma_tdm_txsig_onhook(fchan->sockfd, &onhook_tdm_api);
|
||||
if (status) {
|
||||
snprintf(fchan->last_error, sizeof(fchan->last_error), "ONHOOK Failed");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
*event_id = onhook_tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_ONHOOK : FTDM_OOB_NOOP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WP_API_EVENT_RING_DETECT:
|
||||
{
|
||||
*event_id = tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_RING_START : FTDM_OOB_RING_STOP;
|
||||
}
|
||||
break;
|
||||
/*
|
||||
disabled this ones when configuring, we don't need them, do we?
|
||||
case WP_API_EVENT_RING_TRIP_DETECT:
|
||||
{
|
||||
*event_id = tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_ONHOOK : FTDM_OOB_OFFHOOK;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case WP_API_EVENT_RBS:
|
||||
{
|
||||
*event_id = FTDM_OOB_CAS_BITS_CHANGE;
|
||||
fchan->rx_cas_bits = wanpipe_swap_bits(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits);
|
||||
}
|
||||
break;
|
||||
case WP_API_EVENT_DTMF:
|
||||
{
|
||||
char tmp_dtmf[2] = { tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_dtmf_digit, 0 };
|
||||
*event_id = FTDM_OOB_NOOP;
|
||||
|
||||
if (tmp_dtmf[0] == 'f') {
|
||||
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe DTMF: %c, fax tones will be passed through!\n", tmp_dtmf[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_PRESENT) {
|
||||
ftdm_set_flag(fchan, FTDM_CHANNEL_MUTE);
|
||||
}
|
||||
|
||||
if (tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_STOP) {
|
||||
ftdm_clear_flag(fchan, FTDM_CHANNEL_MUTE);
|
||||
if (ftdm_test_flag(fchan, FTDM_CHANNEL_INUSE)) {
|
||||
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c\n", tmp_dtmf[0]);
|
||||
ftdm_channel_queue_dtmf(fchan, tmp_dtmf);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WP_API_EVENT_ALARM:
|
||||
{
|
||||
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Got wanpipe alarms %d\n", tdm_api->wp_tdm_cmd.event.wp_api_event_alarm);
|
||||
*event_id = FTDM_OOB_ALARM_TRAP;
|
||||
}
|
||||
break;
|
||||
case WP_API_EVENT_POLARITY_REVERSE:
|
||||
{
|
||||
ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Got polarity reverse\n");
|
||||
*event_id = FTDM_OOB_POLARITY_REVERSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Unhandled wanpipe event %d\n", tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type);
|
||||
*event_id = FTDM_OOB_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
event:
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves an event from a wanpipe channel
|
||||
* \param channel Channel to retrieve event from
|
||||
@@ -1237,8 +1372,9 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event)
|
||||
wanpipe_tdm_api_t tdm_api;
|
||||
ftdm_span_t *span = ftdmchan->span;
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_EVENT))
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_EVENT)) {
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_EVENT);
|
||||
}
|
||||
|
||||
memset(&tdm_api, 0, sizeof(tdm_api));
|
||||
status = sangoma_tdm_read_event(ftdmchan->sockfd, &tdm_api);
|
||||
@@ -1249,115 +1385,11 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event)
|
||||
}
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "read wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
||||
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type) {
|
||||
|
||||
case WP_TDMAPI_EVENT_LINK_STATUS:
|
||||
{
|
||||
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
|
||||
case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
|
||||
event_id = FTDM_OOB_ALARM_CLEAR;
|
||||
break;
|
||||
default:
|
||||
event_id = FTDM_OOB_ALARM_TRAP;
|
||||
break;
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
||||
case WP_TDMAPI_EVENT_RXHOOK:
|
||||
{
|
||||
if (ftdmchan->type == FTDM_CHAN_TYPE_FXS) {
|
||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_OFFHOOK : FTDM_OOB_ONHOOK;
|
||||
if (event_id == FTDM_OOB_OFFHOOK) {
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_FLASH)) {
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_FLASH);
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_WINK);
|
||||
event_id = FTDM_OOB_FLASH;
|
||||
goto event;
|
||||
} else {
|
||||
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_WINK);
|
||||
}
|
||||
} else {
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_WINK)) {
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_WINK);
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_FLASH);
|
||||
event_id = FTDM_OOB_WINK;
|
||||
goto event;
|
||||
} else {
|
||||
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_FLASH);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
wanpipe_tdm_api_t onhook_tdm_api;
|
||||
memset(&onhook_tdm_api, 0, sizeof(onhook_tdm_api));
|
||||
status = sangoma_tdm_txsig_onhook(ftdmchan->sockfd, &onhook_tdm_api);
|
||||
if (status) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "ONHOOK Failed");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
event_id = onhook_tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_ONHOOK : FTDM_OOB_NOOP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WP_TDMAPI_EVENT_RING_DETECT:
|
||||
{
|
||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_RING_START : FTDM_OOB_RING_STOP;
|
||||
}
|
||||
break;
|
||||
/*
|
||||
disabled this ones when configuring, we don't need them, do we?
|
||||
case WP_TDMAPI_EVENT_RING_TRIP_DETECT:
|
||||
{
|
||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_ONHOOK : FTDM_OOB_OFFHOOK;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case WP_TDMAPI_EVENT_RBS:
|
||||
{
|
||||
event_id = FTDM_OOB_CAS_BITS_CHANGE;
|
||||
ftdmchan->rx_cas_bits = wanpipe_swap_bits(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits);
|
||||
}
|
||||
break;
|
||||
case WP_TDMAPI_EVENT_DTMF:
|
||||
{
|
||||
char tmp_dtmf[2] = { tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_digit, 0 };
|
||||
event_id = FTDM_OOB_NOOP;
|
||||
|
||||
if (tmp_dtmf[0] == 'f') {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Ignoring wanpipe DTMF: %c, fax tones will be passed through!\n", tmp_dtmf[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_PRESENT) {
|
||||
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_MUTE);
|
||||
}
|
||||
|
||||
if (tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_STOP) {
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_MUTE);
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c\n", tmp_dtmf[0]);
|
||||
ftdm_channel_queue_dtmf(ftdmchan, tmp_dtmf);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WP_TDMAPI_EVENT_ALARM:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Got wanpipe alarms %d\n", tdm_api.wp_tdm_cmd.event.wp_api_event_alarm);
|
||||
event_id = FTDM_OOB_ALARM_TRAP;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unhandled wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
||||
event_id = FTDM_OOB_INVALID;
|
||||
}
|
||||
break;
|
||||
if ((wanpipe_channel_process_event(ftdmchan, &event_id, &tdm_api)) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to process event from channel\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
event:
|
||||
|
||||
ftdmchan->last_event_time = 0;
|
||||
span->event_header.e_type = FTDM_EVENT_OOB;
|
||||
span->event_header.enum_id = event_id;
|
||||
@@ -1419,114 +1451,15 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event)
|
||||
snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "read wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
||||
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type) {
|
||||
|
||||
case WP_TDMAPI_EVENT_LINK_STATUS:
|
||||
{
|
||||
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
|
||||
case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
|
||||
event_id = FTDM_OOB_ALARM_CLEAR;
|
||||
break;
|
||||
default:
|
||||
event_id = FTDM_OOB_ALARM_TRAP;
|
||||
break;
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
||||
case WP_TDMAPI_EVENT_RXHOOK:
|
||||
{
|
||||
if (span->channels[i]->type == FTDM_CHAN_TYPE_FXS) {
|
||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_OFFHOOK : FTDM_OOB_ONHOOK;
|
||||
if (event_id == FTDM_OOB_OFFHOOK) {
|
||||
if (ftdm_test_flag(span->channels[i], FTDM_CHANNEL_FLASH)) {
|
||||
ftdm_clear_flag_locked(span->channels[i], FTDM_CHANNEL_FLASH);
|
||||
ftdm_clear_flag_locked(span->channels[i], FTDM_CHANNEL_WINK);
|
||||
event_id = FTDM_OOB_FLASH;
|
||||
goto event;
|
||||
} else {
|
||||
ftdm_set_flag_locked(span->channels[i], FTDM_CHANNEL_WINK);
|
||||
}
|
||||
} else {
|
||||
if (ftdm_test_flag(span->channels[i], FTDM_CHANNEL_WINK)) {
|
||||
ftdm_clear_flag_locked(span->channels[i], FTDM_CHANNEL_WINK);
|
||||
ftdm_clear_flag_locked(span->channels[i], FTDM_CHANNEL_FLASH);
|
||||
event_id = FTDM_OOB_WINK;
|
||||
goto event;
|
||||
} else {
|
||||
ftdm_set_flag_locked(span->channels[i], FTDM_CHANNEL_FLASH);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
int err;
|
||||
ftdm_channel_t *ftdmchan = span->channels[i];
|
||||
err=sangoma_tdm_txsig_onhook(ftdmchan->sockfd,&tdm_api);
|
||||
if (err) {
|
||||
snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "ONHOOK Failed");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_ONHOOK : FTDM_OOB_NOOP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WP_TDMAPI_EVENT_RING_DETECT:
|
||||
{
|
||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_RING_START : FTDM_OOB_RING_STOP;
|
||||
}
|
||||
break;
|
||||
/*
|
||||
disabled this ones when configuring, we don't need them, do we?
|
||||
case WP_TDMAPI_EVENT_RING_TRIP_DETECT:
|
||||
{
|
||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_ONHOOK : FTDM_OOB_OFFHOOK;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case WP_TDMAPI_EVENT_RBS:
|
||||
{
|
||||
event_id = FTDM_OOB_CAS_BITS_CHANGE;
|
||||
span->channels[i]->rx_cas_bits = wanpipe_swap_bits(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits);
|
||||
}
|
||||
break;
|
||||
case WP_TDMAPI_EVENT_DTMF:
|
||||
{
|
||||
char tmp_dtmf[2] = { tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_digit, 0 };
|
||||
event_id = FTDM_OOB_NOOP;
|
||||
|
||||
if (tmp_dtmf[0] == 'f') {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Ignoring wanpipe DTMF: %c, fax tones will be passed through!\n", tmp_dtmf[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_PRESENT) {
|
||||
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_MUTE);
|
||||
}
|
||||
|
||||
if (tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_STOP) {
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_MUTE);
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c\n", tmp_dtmf[0]);
|
||||
ftdm_channel_queue_dtmf(ftdmchan, tmp_dtmf);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WP_TDMAPI_EVENT_ALARM:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Got wanpipe alarms %d\n", tdm_api.wp_tdm_cmd.event.wp_api_event_alarm);
|
||||
event_id = FTDM_OOB_ALARM_TRAP;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unhandled wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
||||
event_id = FTDM_OOB_INVALID;
|
||||
}
|
||||
break;
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
if ((wanpipe_channel_process_event(ftdmchan, &event_id, &tdm_api)) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to process events from channel\n");
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
|
||||
event:
|
||||
|
||||
@@ -1538,9 +1471,7 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event)
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return FTDM_FAIL;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -52,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;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -181,6 +187,7 @@ static ftdm_socket_t CONTROL_FD = ZT_INVALID_SOCKET;
|
||||
|
||||
FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event);
|
||||
FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event);
|
||||
FIO_CHANNEL_NEXT_EVENT_FUNCTION(zt_channel_next_event);
|
||||
|
||||
/**
|
||||
* \brief Initialises codec, and rx/tx gains
|
||||
@@ -985,6 +992,124 @@ FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event)
|
||||
return k ? FTDM_SUCCESS : FTDM_FAIL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Process an event from a ftdmchan and set the proper OOB event_id. The channel must be locked.
|
||||
* \param fchan Channel to retrieve event from
|
||||
* \param event_id Pointer to OOB event id
|
||||
* \param zt_event_id Zaptel event id
|
||||
* \return FTDM_SUCCESS or FTDM_FAIL
|
||||
*/
|
||||
static __inline__ ftdm_status_t zt_channel_process_event(ftdm_channel_t *fchan, ftdm_oob_event_t *event_id, zt_event_t zt_event_id)
|
||||
{
|
||||
switch(zt_event_id) {
|
||||
case ZT_EVENT_RINGEROFF:
|
||||
{
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_RINGERON:
|
||||
{
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_RINGBEGIN:
|
||||
{
|
||||
*event_id = FTDM_OOB_RING_START;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_ONHOOK:
|
||||
{
|
||||
*event_id = FTDM_OOB_ONHOOK;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_WINKFLASH:
|
||||
{
|
||||
if (fchan->state == FTDM_CHANNEL_STATE_DOWN || fchan->state == FTDM_CHANNEL_STATE_DIALING) {
|
||||
*event_id = FTDM_OOB_WINK;
|
||||
} else {
|
||||
*event_id = FTDM_OOB_FLASH;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_RINGOFFHOOK:
|
||||
{
|
||||
if (fchan->type == FTDM_CHAN_TYPE_FXS || (fchan->type == FTDM_CHAN_TYPE_EM && fchan->state != FTDM_CHANNEL_STATE_UP)) {
|
||||
ftdm_set_flag_locked(fchan, FTDM_CHANNEL_OFFHOOK);
|
||||
*event_id = FTDM_OOB_OFFHOOK;
|
||||
} else if (fchan->type == FTDM_CHAN_TYPE_FXO) {
|
||||
*event_id = FTDM_OOB_RING_START;
|
||||
} else {
|
||||
*event_id = FTDM_OOB_NOOP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_ALARM:
|
||||
{
|
||||
*event_id = FTDM_OOB_ALARM_TRAP;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_NOALARM:
|
||||
{
|
||||
*event_id = FTDM_OOB_ALARM_CLEAR;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_BITSCHANGED:
|
||||
{
|
||||
*event_id = FTDM_OOB_CAS_BITS_CHANGE;
|
||||
int bits = 0;
|
||||
int err = ioctl(fchan->sockfd, codes.GETRXBITS, &bits);
|
||||
if (err) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
fchan->rx_cas_bits = bits;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Unhandled event %d\n", zt_event_id);
|
||||
*event_id = FTDM_OOB_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves an event from a ftdm channel
|
||||
* \param ftdmchan Channel to retrieve event from
|
||||
* \param event FreeTDM event to return
|
||||
* \return Success or failure
|
||||
*/
|
||||
FIO_CHANNEL_NEXT_EVENT_FUNCTION(zt_channel_next_event)
|
||||
{
|
||||
uint32_t event_id = FTDM_OOB_INVALID;
|
||||
zt_event_t zt_event_id = 0;
|
||||
ftdm_span_t *span = ftdmchan->span;
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_EVENT)) {
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_EVENT);
|
||||
}
|
||||
|
||||
if (ioctl(ftdmchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed retrieving event from channel: %s\n",
|
||||
strerror(errno));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* the core already locked the channel for us, so it's safe to call zt_channel_process_event() here */
|
||||
if ((zt_channel_process_event(ftdmchan, &event_id, zt_event_id)) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to process event from channel\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdmchan->last_event_time = 0;
|
||||
span->event_header.e_type = FTDM_EVENT_OOB;
|
||||
span->event_header.enum_id = event_id;
|
||||
span->event_header.channel = ftdmchan;
|
||||
*event = &span->event_header;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves an event from a ftdmtel span
|
||||
* \param span Span to retrieve event from
|
||||
@@ -997,91 +1122,29 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
|
||||
zt_event_t zt_event_id = 0;
|
||||
|
||||
for(i = 1; i <= span->chan_count; i++) {
|
||||
if (ftdm_test_flag(span->channels[i], FTDM_CHANNEL_EVENT)) {
|
||||
ftdm_clear_flag(span->channels[i], FTDM_CHANNEL_EVENT);
|
||||
if (ioctl(span->channels[i]->sockfd, codes.GETEVENT, &zt_event_id) == -1) {
|
||||
snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
switch(zt_event_id) {
|
||||
case ZT_EVENT_RINGEROFF:
|
||||
{
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_RINGERON:
|
||||
{
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_RINGBEGIN:
|
||||
{
|
||||
event_id = FTDM_OOB_RING_START;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_ONHOOK:
|
||||
{
|
||||
event_id = FTDM_OOB_ONHOOK;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_WINKFLASH:
|
||||
{
|
||||
if (span->channels[i]->state == FTDM_CHANNEL_STATE_DOWN || span->channels[i]->state == FTDM_CHANNEL_STATE_DIALING) {
|
||||
event_id = FTDM_OOB_WINK;
|
||||
} else {
|
||||
event_id = FTDM_OOB_FLASH;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_RINGOFFHOOK:
|
||||
{
|
||||
if (span->channels[i]->type == FTDM_CHAN_TYPE_FXS || (span->channels[i]->type == FTDM_CHAN_TYPE_EM && span->channels[i]->state != FTDM_CHANNEL_STATE_UP)) {
|
||||
ftdm_set_flag_locked(span->channels[i], FTDM_CHANNEL_OFFHOOK);
|
||||
event_id = FTDM_OOB_OFFHOOK;
|
||||
} else if (span->channels[i]->type == FTDM_CHAN_TYPE_FXO) {
|
||||
event_id = FTDM_OOB_RING_START;
|
||||
} else {
|
||||
event_id = FTDM_OOB_NOOP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_ALARM:
|
||||
{
|
||||
event_id = FTDM_OOB_ALARM_TRAP;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_NOALARM:
|
||||
{
|
||||
event_id = FTDM_OOB_ALARM_CLEAR;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_BITSCHANGED:
|
||||
{
|
||||
event_id = FTDM_OOB_CAS_BITS_CHANGE;
|
||||
int bits = 0;
|
||||
int err = ioctl(span->channels[i]->sockfd, codes.GETRXBITS, &bits);
|
||||
if (err) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
span->channels[i]->rx_cas_bits = bits;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_WARNING, "Unhandled event %d for %d:%d\n", zt_event_id, span->span_id, i);
|
||||
event_id = FTDM_OOB_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
span->channels[i]->last_event_time = 0;
|
||||
span->event_header.e_type = FTDM_EVENT_OOB;
|
||||
span->event_header.enum_id = event_id;
|
||||
span->event_header.channel = span->channels[i];
|
||||
*event = &span->event_header;
|
||||
return FTDM_SUCCESS;
|
||||
ftdm_channel_t *fchan = span->channels[i];
|
||||
if (ftdm_test_flag(fchan, FTDM_CHANNEL_EVENT)) {
|
||||
ftdm_clear_flag(fchan, FTDM_CHANNEL_EVENT);
|
||||
}
|
||||
if (ioctl(fchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) {
|
||||
snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdm_channel_lock(fchan);
|
||||
if ((zt_channel_process_event(fchan, &event_id, zt_event_id)) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(fchan, FTDM_LOG_ERROR, "Failed to process event from channel\n");
|
||||
ftdm_channel_unlock(fchan);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
ftdm_channel_unlock(fchan);
|
||||
|
||||
fchan->last_event_time = 0;
|
||||
span->event_header.e_type = FTDM_EVENT_OOB;
|
||||
span->event_header.enum_id = event_id;
|
||||
span->event_header.channel = fchan;
|
||||
*event = &span->event_header;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
return FTDM_FAIL;
|
||||
@@ -1146,6 +1209,7 @@ static FIO_WRITE_FUNCTION(zt_write)
|
||||
bytes += 2;
|
||||
}
|
||||
|
||||
tryagain:
|
||||
w = write(ftdmchan->sockfd, data, bytes);
|
||||
|
||||
if (w >= 0) {
|
||||
@@ -1153,6 +1217,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,15 +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 */
|
||||
@@ -282,10 +301,10 @@ 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 */
|
||||
@@ -294,12 +313,14 @@ typedef struct ftdm_caller_data {
|
||||
ftdm_bearer_cap_t bearer_capability;
|
||||
/* user information layer 1 protocol */
|
||||
ftdm_user_layer1_prot_t bearer_layer1;
|
||||
ftdm_variable_container_t variables; /*!<variables attached to this call */
|
||||
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_channel_t *fchan; /*!< FreeTDM channel associated (can be NULL) */
|
||||
} ftdm_caller_data_t;
|
||||
|
||||
/*! \brief Tone type */
|
||||
@@ -328,12 +349,13 @@ typedef enum {
|
||||
FTDM_SIGEVENT_FACILITY, /*!< In call facility event */
|
||||
FTDM_SIGEVENT_TRACE, /*!<Interpreted trace event */
|
||||
FTDM_SIGEVENT_TRACE_RAW, /*!<Raw trace event */
|
||||
FTDM_SIGEVENT_INDICATION_COMPLETED, /*!< Last requested indication was completed */
|
||||
FTDM_SIGEVENT_INVALID, /*!<Invalid */
|
||||
} ftdm_signal_event_t;
|
||||
#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", "FACILITY", "TRACE", "TRACE_RAW", "INVALID"
|
||||
|
||||
"COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "FACILITY", \
|
||||
"TRACE", "TRACE_RAW", "INDICATION_COMPLETED", "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)
|
||||
|
||||
@@ -418,19 +440,55 @@ typedef struct {
|
||||
ftdm_trace_type_t type;
|
||||
} ftdm_event_trace_t;
|
||||
|
||||
typedef struct {
|
||||
/* Digits collected */
|
||||
char digits[FTDM_DIGITS_LIMIT];
|
||||
} ftdm_event_collected_t;
|
||||
|
||||
/*! \brief FreeTDM supported indications.
|
||||
* This is used during incoming calls when you want to request the signaling stack
|
||||
* to notify about indications occurring locally. See ftdm_channel_call_indicate for more info */
|
||||
typedef enum {
|
||||
FTDM_CHANNEL_INDICATE_NONE,
|
||||
FTDM_CHANNEL_INDICATE_RINGING,
|
||||
FTDM_CHANNEL_INDICATE_PROCEED,
|
||||
FTDM_CHANNEL_INDICATE_PROGRESS,
|
||||
FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA,
|
||||
FTDM_CHANNEL_INDICATE_BUSY,
|
||||
/* Using this indication is equivalent to call ftdm_channel_call_answer API */
|
||||
FTDM_CHANNEL_INDICATE_ANSWER,
|
||||
FTDM_CHANNEL_INDICATE_INVALID,
|
||||
} ftdm_channel_indication_t;
|
||||
#define INDICATION_STRINGS "NONE", "RINGING", "PROCEED", "PROGRESS", "PROGRESS_MEDIA", "BUSY", "ANSWER", "INVALID"
|
||||
|
||||
/*! \brief Move from string to ftdm_channel_indication_t and viceversa */
|
||||
FTDM_STR2ENUM_P(ftdm_str2channel_indication, ftdm_channel_indication2str, ftdm_channel_indication_t)
|
||||
|
||||
typedef struct {
|
||||
/* The indication that was completed */
|
||||
ftdm_channel_indication_t indication;
|
||||
/* Completion status of the indication */
|
||||
ftdm_status_t status;
|
||||
} ftdm_event_indication_completed_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 */
|
||||
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 trace; /*!< valid if event_id is FTDM_SIGEVENT_TRACE or FTDM_SIGEVENT_TRACE_RAW */
|
||||
}ev_data;
|
||||
ftdm_event_collected_t collected; /*!< valid if event_id is FTDM_SIGEVENT_COLLECTED_DIGIT */
|
||||
ftdm_event_indication_completed_t indication_completed; /*!< valid if the event_id is FTDM_SIGEVENT_INDICATION_COMPLETED */
|
||||
} 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
|
||||
@@ -535,11 +593,17 @@ typedef enum {
|
||||
FTDM_COMMAND_GET_LINK_STATUS,
|
||||
FTDM_COMMAND_ENABLE_LOOP,
|
||||
FTDM_COMMAND_DISABLE_LOOP,
|
||||
FTDM_COMMAND_COUNT,
|
||||
FTDM_COMMAND_SET_RX_QUEUE_SIZE,
|
||||
FTDM_COMMAND_SET_TX_QUEUE_SIZE,
|
||||
FTDM_COMMAND_SET_POLARITY,
|
||||
FTDM_COMMAND_COUNT,
|
||||
} ftdm_command_t;
|
||||
|
||||
typedef enum {
|
||||
FTDM_POLARITY_FORWARD = 0,
|
||||
FTDM_POLARITY_REVERSE = 1
|
||||
} ftdm_polarity_t;
|
||||
|
||||
/*! \brief Custom memory handler hooks. Not recommended to use unless you need memory allocation customizations */
|
||||
typedef void *(*ftdm_malloc_func_t)(void *pool, ftdm_size_t len);
|
||||
typedef void *(*ftdm_calloc_func_t)(void *pool, ftdm_size_t elements, ftdm_size_t len);
|
||||
@@ -598,7 +662,20 @@ typedef ftdm_status_t (*fio_span_get_sig_status_t) FIO_SPAN_GET_SIG_STATUS_ARGS;
|
||||
typedef ftdm_status_t (*fio_span_poll_event_t) FIO_SPAN_POLL_EVENT_ARGS ;
|
||||
typedef ftdm_status_t (*fio_span_next_event_t) FIO_SPAN_NEXT_EVENT_ARGS ;
|
||||
typedef ftdm_status_t (*fio_channel_next_event_t) FIO_CHANNEL_NEXT_EVENT_ARGS ;
|
||||
|
||||
/*! \brief Callback for signal delivery (FTDM_SIGEVENT_START and friends)
|
||||
* \note This callback is provided by the user during ftdm_configure_span_signaling
|
||||
*
|
||||
* \note You must NOT do any blocking during this callback since this function is
|
||||
* most likely called in an internal signaling thread that can potentially be
|
||||
* shared for all the channels in a span and blocking will delay processing
|
||||
* (sometimes even audio processing) for other channels
|
||||
*
|
||||
* \note Although some simple FreeTDM APIs can work (ie: ftdm_span_get_id etc), the
|
||||
* use of any FreeTDM call API (ie ftdm_channel_call_answer) is discouraged
|
||||
*/
|
||||
typedef ftdm_status_t (*fio_signal_cb_t) FIO_SIGNAL_CB_ARGS ;
|
||||
|
||||
typedef ftdm_status_t (*fio_event_cb_t) FIO_EVENT_CB_ARGS ;
|
||||
typedef ftdm_status_t (*fio_configure_span_t) FIO_CONFIGURE_SPAN_ARGS ;
|
||||
typedef ftdm_status_t (*fio_configure_t) FIO_CONFIGURE_ARGS ;
|
||||
@@ -682,17 +759,6 @@ typedef enum {
|
||||
FTDM_CODEC_NONE = (1 << 30)
|
||||
} ftdm_codec_t;
|
||||
|
||||
/*! \brief FreeTDM supported indications.
|
||||
* This is used during incoming calls when you want to request the signaling stack
|
||||
* to notify about indications occurring locally */
|
||||
typedef enum {
|
||||
FTDM_CHANNEL_INDICATE_RINGING,
|
||||
FTDM_CHANNEL_INDICATE_PROCEED,
|
||||
FTDM_CHANNEL_INDICATE_PROGRESS,
|
||||
FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA,
|
||||
FTDM_CHANNEL_INDICATE_BUSY,
|
||||
} ftdm_channel_indication_t;
|
||||
|
||||
/*! \brief FreeTDM supported hardware alarms. */
|
||||
typedef enum {
|
||||
FTDM_ALARM_NONE = 0,
|
||||
@@ -715,7 +781,12 @@ FT_DECLARE(ftdm_status_t) ftdm_global_set_queue_handler(ftdm_queue_handler_t *ha
|
||||
*/
|
||||
FT_DECLARE(int) ftdm_channel_get_availability(ftdm_channel_t *ftdmchan);
|
||||
|
||||
/*! \brief Answer call */
|
||||
/*! \brief Answer call. This can also be accomplished by ftdm_channel_call_indicate with FTDM_CHANNEL_INDICATE_ANSWER, in both
|
||||
* cases you will get a FTDM_SIGEVENT_INDICATION_COMPLETED when the indication is sent (or an error occurs)
|
||||
* \note Although this API will result in FTDM_SIGEVENT_INDICATION_COMPLETED event being delivered,
|
||||
* there is no guarantee of whether the event will arrive after or before your execution thread returns
|
||||
* from ftdm_channel_call_answer
|
||||
*/
|
||||
#define ftdm_channel_call_answer(ftdmchan) _ftdm_channel_call_answer(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
|
||||
|
||||
/*! \brief Answer call recording the source code point where the it was called (see ftdm_channel_call_answer for an easy to use macro) */
|
||||
@@ -727,7 +798,19 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char
|
||||
/*! \brief Place an outgoing call recording the source code point where it was called (see ftdm_channel_call_place for an easy to use macro) */
|
||||
FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan);
|
||||
|
||||
/*! \brief Indicate a new condition in an incoming call */
|
||||
/*! \brief Indicate a new condition in an incoming call
|
||||
*
|
||||
* \note Every indication request will result in FTDM_SIGEVENT_INDICATION_COMPLETED event being delivered with
|
||||
* the proper status that will inform you if the request was successful or not. The exception is if this
|
||||
* function returns something different to FTDM_SUCCESS, in which case the request failed right away and no
|
||||
* further FTDM_SIGEVENT_INDICATION_COMPLETED will be delivered
|
||||
* Be aware there is no guarantee of whether the completion event will arrive after or before your execution
|
||||
* thread returns from ftdm_channel_call_indicate. This means you could get FTDM_SIGEVENT_INDICATION_COMPLETED
|
||||
* even before your execution thread returns from the ftdm_channel_call_indicate() API
|
||||
*
|
||||
* \note You cannot send more than one indication at the time. You must wait for the completed event before
|
||||
* calling this function again (unless the return code was different than FTDM_SUCCESS)
|
||||
*/
|
||||
#define ftdm_channel_call_indicate(ftdmchan, indication) _ftdm_channel_call_indicate(__FILE__, __FUNCTION__, __LINE__, (ftdmchan), (indication))
|
||||
|
||||
/*! \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) */
|
||||
@@ -1468,9 +1551,14 @@ FT_DECLARE(const char *) ftdm_channel_get_last_state_str(const ftdm_channel_t *c
|
||||
*/
|
||||
FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *channel);
|
||||
|
||||
/*! \brief Initialize channel state for an outgoing call */
|
||||
/*! \brief Initialize channel state for an outgoing call
|
||||
* \note This API will eventually be deprecated, is only needed if you use boost signaling
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_init(ftdm_channel_t *ftdmchan);
|
||||
|
||||
/*! \brief Enable/disable blocking mode in the channels for this span */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_blocking_mode(const ftdm_span_t *span, ftdm_bool_t enabled);
|
||||
|
||||
/*! \brief Initialize the library */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_global_init(void);
|
||||
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
|
||||
@@ -183,7 +183,16 @@ typedef enum {
|
||||
FTDM_TIMEOUT, /*!< Operation timed out (ie: polling on a device)*/
|
||||
FTDM_NOTIMPL, /*!< Operation not implemented */
|
||||
FTDM_BREAK, /*!< Request the caller to perform a break (context-dependant, ie: stop getting DNIS/ANI) */
|
||||
FTDM_EINVAL /*!< Invalid argument */
|
||||
|
||||
/*!< Any new return codes should try to mimc unix style error codes, no need to reinvent */
|
||||
/* Remapping some of the codes that were before */
|
||||
FTDM_ENOMEM = FTDM_MEMERR, /*!< Memory error */
|
||||
FTDM_ETIMEDOUT = FTDM_TIMEOUT, /*!< Operation timedout */
|
||||
FTDM_ENOSYS = FTDM_NOTIMPL, /*!< The function is not implemented */
|
||||
|
||||
FTDM_EINVAL, /*!< Invalid argument */
|
||||
FTDM_ECANCELED, /*!< Operation cancelled */
|
||||
FTDM_EBUSY, /*!< Device busy */
|
||||
} ftdm_status_t;
|
||||
|
||||
/*! \brief FreeTDM bool type. */
|
||||
|
||||
@@ -51,6 +51,9 @@ extern "C" {
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/*! \brief time data type */
|
||||
typedef uint64_t ftdm_time_t;
|
||||
|
||||
/*! \brief sleep x amount of milliseconds */
|
||||
#ifdef __WINDOWS__
|
||||
#define ftdm_sleep(x) Sleep(x)
|
||||
@@ -114,6 +117,8 @@ FT_DECLARE(char *) ftdm_strdup(const char *str);
|
||||
/*! \brief Duplicate string with limit */
|
||||
FT_DECLARE(char *) ftdm_strndup(const char *str, ftdm_size_t inlen);
|
||||
|
||||
/*! \brief Get the current time in milliseconds */
|
||||
FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern C */
|
||||
|
||||
@@ -143,7 +143,9 @@ extern "C" {
|
||||
\return true value if the object has the flags defined
|
||||
*/
|
||||
#define ftdm_test_flag(obj, flag) ((obj)->flags & flag)
|
||||
/*!< Physical (IO) module specific flags */
|
||||
#define ftdm_test_pflag(obj, flag) ((obj)->pflags & flag)
|
||||
/*!< signaling module specific flags */
|
||||
#define ftdm_test_sflag(obj, flag) ((obj)->sflags & flag)
|
||||
|
||||
#define ftdm_set_alarm_flag(obj, flag) (obj)->alarm_flags |= (flag)
|
||||
@@ -190,17 +192,6 @@ extern "C" {
|
||||
|
||||
#define ftdm_clear_sflag_locked(obj, flag) assert(obj->mutex != NULL); ftdm_mutex_lock(obj->mutex); (obj)->sflags &= ~(flag); ftdm_mutex_unlock(obj->mutex);
|
||||
|
||||
#define ftdm_set_state(obj, s) ftdm_channel_set_state(__FILE__, __FUNCTION__, __LINE__, obj, s, 0); \
|
||||
|
||||
#define ftdm_set_state_locked(obj, s) \
|
||||
do { \
|
||||
ftdm_channel_lock(obj); \
|
||||
ftdm_channel_set_state(__FILE__, __FUNCTION__, __LINE__, obj, s, 0); \
|
||||
ftdm_channel_unlock(obj); \
|
||||
} while(0);
|
||||
|
||||
#define ftdm_set_state_r(obj, s, r) r = ftdm_channel_set_state(__FILE__, __FUNCTION__, __LINE__, obj, s, 0);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* The while(0) below throws a conditional expression is constant warning */
|
||||
#pragma warning(disable:4127)
|
||||
@@ -361,15 +352,6 @@ typedef struct {
|
||||
ftdm_mutex_t *mutex;
|
||||
} ftdm_dtmf_debug_t;
|
||||
|
||||
typedef struct {
|
||||
const char *file;
|
||||
const char *func;
|
||||
int line;
|
||||
ftdm_channel_state_t state;
|
||||
ftdm_channel_state_t last_state;
|
||||
ftdm_time_t time;
|
||||
} ftdm_channel_history_entry_t;
|
||||
|
||||
typedef enum {
|
||||
FTDM_IOSTATS_ERROR_CRC = (1 << 0),
|
||||
FTDM_IOSTATS_ERROR_FRAME = (1 << 1),
|
||||
@@ -411,7 +393,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;
|
||||
@@ -422,9 +404,11 @@ struct ftdm_channel {
|
||||
uint32_t native_interval;
|
||||
uint32_t packet_len;
|
||||
ftdm_channel_state_t state;
|
||||
ftdm_state_status_t state_status;
|
||||
ftdm_channel_state_t last_state;
|
||||
ftdm_channel_state_t init_state;
|
||||
ftdm_channel_history_entry_t history[10];
|
||||
ftdm_channel_indication_t indication;
|
||||
ftdm_state_history_entry_t history[10];
|
||||
uint8_t hindex;
|
||||
ftdm_mutex_t *mutex;
|
||||
teletone_dtmf_detect_state_t dtmf_detect;
|
||||
@@ -456,6 +440,7 @@ struct ftdm_channel {
|
||||
ftdm_fsk_data_state_t fsk;
|
||||
uint8_t fsk_buf[80];
|
||||
uint32_t ring_count;
|
||||
ftdm_polarity_t polarity;
|
||||
/* Private I/O data. Do not touch unless you are an I/O module */
|
||||
void *io_data;
|
||||
/* Private signaling data. Do not touch unless you are a signaling module */
|
||||
@@ -477,6 +462,7 @@ struct ftdm_channel {
|
||||
ftdm_dtmf_debug_t dtmfdbg;
|
||||
ftdm_io_dump_t rxdump;
|
||||
ftdm_io_dump_t txdump;
|
||||
ftdm_interrupt_t *state_completed_interrupt; /*!< Notify when a state change is completed */
|
||||
int32_t txdrops;
|
||||
int32_t rxdrops;
|
||||
};
|
||||
@@ -493,6 +479,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;
|
||||
@@ -513,15 +500,15 @@ struct ftdm_span {
|
||||
ftdm_span_stop_t stop;
|
||||
ftdm_channel_sig_read_t sig_read;
|
||||
ftdm_channel_sig_write_t sig_write;
|
||||
/* Private I/O data per span. Do not touch unless you are an I/O module */
|
||||
void *io_data;
|
||||
ftdm_channel_state_processor_t state_processor; /*!< This guy is called whenever state processing is required */
|
||||
void *io_data; /*!< Private I/O data per span. Do not touch unless you are an I/O module */
|
||||
char *type;
|
||||
char *dtmf_hangup;
|
||||
size_t dtmf_hangup_len;
|
||||
ftdm_state_map_t *state_map;
|
||||
ftdm_caller_data_t default_caller_data;
|
||||
ftdm_queue_t *pendingchans;
|
||||
ftdm_queue_t *pendingsignals;
|
||||
ftdm_queue_t *pendingchans; /*!< Channels pending of state processing */
|
||||
ftdm_queue_t *pendingsignals; /*!< Signals pending from being delivered to the user */
|
||||
struct ftdm_span *next;
|
||||
};
|
||||
|
||||
@@ -568,11 +555,7 @@ FT_DECLARE(ftdm_status_t) ftdm_fsk_data_add_checksum(ftdm_fsk_data_state_t *stat
|
||||
FT_DECLARE(ftdm_status_t) ftdm_fsk_data_add_sdmf(ftdm_fsk_data_state_t *state, const char *date, char *number);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_send_fsk_data(ftdm_channel_t *ftdmchan, ftdm_fsk_data_state_t *fsk_data, float db_level);
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(const char *file, const char *func, int line,
|
||||
ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, int wait);
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_load_tones(ftdm_span_t *span, const char *mapname);
|
||||
FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void);
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_use(ftdm_channel_t *ftdmchan);
|
||||
|
||||
@@ -585,8 +568,6 @@ FT_DECLARE(void) print_hex_bytes(uint8_t *data, ftdm_size_t dlen, char *buf, ftd
|
||||
FT_DECLARE_NONSTD(int) ftdm_hash_equalkeys(void *k1, void *k2);
|
||||
FT_DECLARE_NONSTD(uint32_t) ftdm_hash_hashfromstring(void *ky);
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_complete_state(ftdm_channel_t *ftdmchan);
|
||||
|
||||
FT_DECLARE(int) ftdm_load_modules(void);
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_unload_modules(void);
|
||||
@@ -602,6 +583,7 @@ FT_DECLARE(int) ftdm_vasprintf(char **ret, const char *fmt, va_list ap);
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_close_all(void);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan);
|
||||
FT_DECLARE(void) ftdm_ack_indication(ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication, ftdm_status_t status);
|
||||
|
||||
/*!
|
||||
* \brief Retrieves an event from the span
|
||||
@@ -702,50 +684,6 @@ static __inline__ void ftdm_abort(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline__ void ftdm_set_state_all(ftdm_span_t *span, ftdm_channel_state_t state)
|
||||
{
|
||||
uint32_t j;
|
||||
ftdm_mutex_lock(span->mutex);
|
||||
for(j = 1; j <= span->chan_count; j++) {
|
||||
if (!FTDM_IS_DCHAN(span->channels[j])) {
|
||||
ftdm_set_state_locked((span->channels[j]), state);
|
||||
}
|
||||
}
|
||||
ftdm_mutex_unlock(span->mutex);
|
||||
}
|
||||
|
||||
static __inline__ int ftdm_check_state_all(ftdm_span_t *span, ftdm_channel_state_t state)
|
||||
{
|
||||
uint32_t j;
|
||||
for(j = 1; j <= span->chan_count; j++) {
|
||||
if (span->channels[j]->state != state || ftdm_test_flag(span->channels[j], FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __inline__ void ftdm_set_flag_all(ftdm_span_t *span, uint32_t flag)
|
||||
{
|
||||
uint32_t j;
|
||||
ftdm_mutex_lock(span->mutex);
|
||||
for(j = 1; j <= span->chan_count; j++) {
|
||||
ftdm_set_flag_locked((span->channels[j]), flag);
|
||||
}
|
||||
ftdm_mutex_unlock(span->mutex);
|
||||
}
|
||||
|
||||
static __inline__ void ftdm_clear_flag_all(ftdm_span_t *span, uint32_t flag)
|
||||
{
|
||||
uint32_t j;
|
||||
ftdm_mutex_lock(span->mutex);
|
||||
for(j = 1; j <= span->chan_count; j++) {
|
||||
ftdm_clear_flag_locked((span->channels[j]), flag);
|
||||
}
|
||||
ftdm_mutex_unlock(span->mutex);
|
||||
}
|
||||
|
||||
static __inline__ int16_t ftdm_saturated_add(int16_t sample1, int16_t sample2)
|
||||
{
|
||||
int addres;
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* ftdm_m3ua.h
|
||||
* freetdm
|
||||
*
|
||||
* Created by Shane Burrell on 4/3/08.
|
||||
* Copyright 2008 Shane Burrell. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II, Nenad Corbic
|
||||
*
|
||||
* 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 "m3ua_client.h"
|
||||
#include "freetdm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
enum e_sigboost_event_id_values
|
||||
{
|
||||
SIGBOOST_EVENT_CALL_START = 0x80, /*128*/
|
||||
SIGBOOST_EVENT_CALL_START_ACK = 0x81, /*129*/
|
||||
SIGBOOST_EVENT_CALL_START_NACK = 0x82, /*130*/
|
||||
SIGBOOST_EVENT_CALL_START_NACK_ACK = 0x83, /*131*/
|
||||
SIGBOOST_EVENT_CALL_ANSWERED = 0x84, /*132*/
|
||||
SIGBOOST_EVENT_CALL_STOPPED = 0x85, /*133*/
|
||||
SIGBOOST_EVENT_CALL_STOPPED_ACK = 0x86, /*134*/
|
||||
SIGBOOST_EVENT_SYSTEM_RESTART = 0x87, /*135*/
|
||||
SIGBOOST_EVENT_SYSTEM_RESTART_ACK = 0x88, /*136*/
|
||||
/* Following IDs are ss7boost to sangoma_mgd only. */
|
||||
SIGBOOST_EVENT_HEARTBEAT = 0x89, /*137*/
|
||||
SIGBOOST_EVENT_INSERT_CHECK_LOOP = 0x8a, /*138*/
|
||||
SIGBOOST_EVENT_REMOVE_CHECK_LOOP = 0x8b, /*139*/
|
||||
SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE = 0x8c, /*140*/
|
||||
};
|
||||
enum e_sigboost_release_cause_values
|
||||
{
|
||||
SIGBOOST_RELEASE_CAUSE_UNDEFINED = 0,
|
||||
SIGBOOST_RELEASE_CAUSE_NORMAL = 16,
|
||||
SIGBOOST_RELEASE_CAUSE_BUSY = 17,
|
||||
/* probable elimination */
|
||||
//SIGBOOST_RELEASE_CAUSE_BUSY = 0x91, /* 145 */
|
||||
//SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST = 0x92, /* 146 */
|
||||
//SIGBOOST_RELEASE_CAUSE_CIRCUIT_RESET = 0x93, /* 147 */
|
||||
//SIGBOOST_RELEASE_CAUSE_NOANSWER = 0x94, /* 148 */
|
||||
};
|
||||
|
||||
enum e_sigboost_call_setup_ack_nack_cause_values
|
||||
{
|
||||
SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY = 117, /* unused Q.850 value */
|
||||
SIGBOOST_CALL_SETUP_NACK_TEST_CKT_BUSY = 118, /* unused Q.850 value */
|
||||
SIGBOOST_CALL_SETUP_NACK_INVALID_NUMBER = 28,
|
||||
/* probable elimination */
|
||||
//SIGBOOST_CALL_SETUP_RESERVED = 0x00,
|
||||
//SIGBOOST_CALL_SETUP_CIRCUIT_RESET = 0x10,
|
||||
//SIGBOOST_CALL_SETUP_NACK_CKT_START_TIMEOUT = 0x11,
|
||||
//SIGBOOST_CALL_SETUP_NACK_AUTO_CALL_GAP = 0x17,
|
||||
};
|
||||
typedef enum {
|
||||
M3UA_SPAN_SIGNALING_M3UA,
|
||||
M3UA_SPAN_SIGNALING_SS7BOX,
|
||||
|
||||
} M3UA_TSpanSignaling;
|
||||
#define M3UA_SPAN_STRINGS "M3UA", "SS7BOX"
|
||||
FTDM_STR2ENUM_P(m3ua_str2span, m3ua_span2str, M3UA_TSpanSignaling)
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
FTDM_M3UA_RUNNING = (1 << 0)
|
||||
} ftdm_m3uat_flag_t;
|
||||
|
||||
/*typedef struct m3ua_data {
|
||||
m3uac_connection_t mcon;
|
||||
m3uac_connection_t pcon;
|
||||
fio_signal_cb_t signal_cb;
|
||||
uint32_t flags;
|
||||
} m3ua_data_t;
|
||||
|
||||
*/
|
||||
/*typedef struct mu3a_link {
|
||||
ss7bc_connection_t mcon;
|
||||
ss7bc_connection_t pcon;
|
||||
fio_signal_cb_t signal_cb;
|
||||
uint32_t flags;
|
||||
} ftdm_m3ua_data_t;
|
||||
*/
|
||||
|
||||
ftdm_status_t m3ua_init(ftdm_io_interface_t **zint);
|
||||
ftdm_status_t m3ua_destroy(void);
|
||||
ftdm_status_t m3ua_start(ftdm_span_t *span);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#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:
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Sangoma Technologies
|
||||
* Moises Silva <moy@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __FTDM_STATE_H__
|
||||
#define __FTDM_STATE_H__
|
||||
|
||||
/*! \file
|
||||
* \brief State handling definitions
|
||||
* \note Most, if not all of the state handling functions assume you have a lock acquired. Touching the channel
|
||||
* state is a sensitive matter that requires checks and careful thought and is typically a process that
|
||||
* is not encapsulated within a single function, therefore the lock must be explicitly acquired by the
|
||||
* caller (most of the time, signaling modules), process states, set a new state and process it, and
|
||||
* finally unlock the channel. See docs/locking.txt fore more info
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
FTDM_CHANNEL_STATE_DOWN,
|
||||
FTDM_CHANNEL_STATE_HOLD,
|
||||
FTDM_CHANNEL_STATE_SUSPENDED,
|
||||
FTDM_CHANNEL_STATE_DIALTONE,
|
||||
FTDM_CHANNEL_STATE_COLLECT,
|
||||
FTDM_CHANNEL_STATE_RING,
|
||||
FTDM_CHANNEL_STATE_RINGING,
|
||||
FTDM_CHANNEL_STATE_BUSY,
|
||||
FTDM_CHANNEL_STATE_ATTN,
|
||||
FTDM_CHANNEL_STATE_GENRING,
|
||||
FTDM_CHANNEL_STATE_DIALING,
|
||||
FTDM_CHANNEL_STATE_GET_CALLERID,
|
||||
FTDM_CHANNEL_STATE_CALLWAITING,
|
||||
FTDM_CHANNEL_STATE_RESTART,
|
||||
FTDM_CHANNEL_STATE_PROCEED,
|
||||
FTDM_CHANNEL_STATE_PROGRESS,
|
||||
FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
|
||||
FTDM_CHANNEL_STATE_UP,
|
||||
FTDM_CHANNEL_STATE_IDLE,
|
||||
FTDM_CHANNEL_STATE_TERMINATING,
|
||||
FTDM_CHANNEL_STATE_CANCEL,
|
||||
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", "RESET", "INVALID"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t)
|
||||
|
||||
typedef struct {
|
||||
const char *file;
|
||||
const char *func;
|
||||
int line;
|
||||
ftdm_channel_state_t state; /*!< Current state (processed or not) */
|
||||
ftdm_channel_state_t last_state; /*!< Previous state */
|
||||
ftdm_time_t time; /*!< Time the state was set */
|
||||
ftdm_time_t end_time; /*!< Time the state processing was completed */
|
||||
} ftdm_state_history_entry_t;
|
||||
|
||||
typedef ftdm_status_t (*ftdm_channel_state_processor_t)(ftdm_channel_t *fchan);
|
||||
|
||||
/*!
|
||||
* \brief Process channel states by invoking the channel state processing routine
|
||||
* it will keep calling the processing routine while the state status
|
||||
* is FTDM_STATE_STATUS_NEW, it will not do anything otherwise
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_advance_states(ftdm_channel_t *fchan);
|
||||
|
||||
FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const char *function, int line, ftdm_channel_t *fchan);
|
||||
#define ftdm_channel_complete_state(obj) _ftdm_channel_complete_state(__FILE__, __FUNCTION__, __LINE__, obj)
|
||||
FT_DECLARE(int) ftdm_check_state_all(ftdm_span_t *span, ftdm_channel_state_t state);
|
||||
|
||||
/*!
|
||||
* \brief Status of the current channel state
|
||||
* \note A given state goes thru several status (yes, states for the state!)
|
||||
* The order is always FTDM_STATE_STATUS_NEW -> FTDM_STATE_STATUS_PROCESSED -> FTDM_STATUS_COMPLETED
|
||||
* However, is possible to go from NEW -> COMPLETED directly when the signaling module explicitly changes
|
||||
* the state of the channel in the middle of processing the current state by calling the ftdm_set_state() API
|
||||
*
|
||||
* FTDM_STATE_STATUS_NEW -
|
||||
* Someone just set the state of the channel, either the signaling module or the user (implicitly through a call API).
|
||||
* This is accomplished by calling ftdm_channel_set_state() which changes the 'state' and 'last_state' memebers of
|
||||
* the ftdm_channel_t structure.
|
||||
*
|
||||
* FTDM_STATE_STATUS_PROCESSED -
|
||||
* The signaling module did something based on the new state.
|
||||
*
|
||||
* This is accomplished via ftdm_channel_advance_states()
|
||||
*
|
||||
* When ftdm_channel_advance_states(), at the very least, if the channel has its state in FTDM_STATE_STATUS_NEW, it
|
||||
* will move to FTDM_STATE_STATUS_PROCESSED, depending on what the signaling module does during the processing
|
||||
* the state may move to FTDM_STATE_STATUS_COMPLETED right after or wait for a signaling specific event to complete it.
|
||||
* It is also possible that more state transitions occur during the execution of ftdm_channel_advance_states() if one
|
||||
* state processing/completion leads to another state change, the function will not return until the chain of events
|
||||
* lead to a state that is not in FTDM_STATE_STATUS_NEW
|
||||
*
|
||||
* FTDM_STATE_STATUS_COMPLETED -
|
||||
* The signaling module completed the processing of the state and there is nothing further to be done for this state.
|
||||
*
|
||||
* This is accomplished either explicitly by the signaling module by calling ftdm_channel_complete_state() or by
|
||||
* the signaling module implicitly by trying to set the state of the channel to a new state via ftdm_set_state()
|
||||
*
|
||||
* When working with blocking channels (FTDM_CHANNEL_NONBLOCK flag not set), the user thread is signaled and unblocked
|
||||
* so it can continue.
|
||||
*
|
||||
* When a state moves to this status is also possible for a signal FTDM_SIGEVENT_INDICATION_COMPLETED to be delivered
|
||||
* by the core if the state change was associated to an indication requested by the user,
|
||||
*/
|
||||
typedef enum {
|
||||
FTDM_STATE_STATUS_NEW,
|
||||
FTDM_STATE_STATUS_PROCESSED,
|
||||
FTDM_STATE_STATUS_COMPLETED,
|
||||
FTDM_STATE_STATUS_INVALID
|
||||
} ftdm_state_status_t;
|
||||
#define CHANNEL_STATE_STATUS_STRINGS "NEW", "PROCESSED", "COMPLETED", "INVALID"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_state_status, ftdm_state_status2str, ftdm_state_status_t)
|
||||
|
||||
typedef enum {
|
||||
ZSM_NONE,
|
||||
ZSM_UNACCEPTABLE,
|
||||
ZSM_ACCEPTABLE
|
||||
} ftdm_state_map_type_t;
|
||||
|
||||
typedef enum {
|
||||
ZSD_INBOUND,
|
||||
ZSD_OUTBOUND,
|
||||
} ftdm_state_direction_t;
|
||||
|
||||
#define FTDM_MAP_NODE_SIZE 512
|
||||
#define FTDM_MAP_MAX FTDM_CHANNEL_STATE_INVALID+2
|
||||
|
||||
struct ftdm_state_map_node {
|
||||
ftdm_state_direction_t direction;
|
||||
ftdm_state_map_type_t type;
|
||||
ftdm_channel_state_t check_states[FTDM_MAP_MAX];
|
||||
ftdm_channel_state_t states[FTDM_MAP_MAX];
|
||||
};
|
||||
typedef struct ftdm_state_map_node ftdm_state_map_node_t;
|
||||
|
||||
struct ftdm_state_map {
|
||||
ftdm_state_map_node_t nodes[FTDM_MAP_NODE_SIZE];
|
||||
};
|
||||
typedef struct ftdm_state_map ftdm_state_map_t;
|
||||
|
||||
/*!\brief Set the state for a channel (the channel must be locked when calling this function)
|
||||
* \note Signaling modules should use ftdm_set_state macro instead
|
||||
* \note If this function is called with the wait parameter set to a non-zero value, the recursivity
|
||||
* of the channel lock must be == 1 because the channel will be unlocked/locked when waiting */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(const char *file, const char *func, int line,
|
||||
ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, int wait);
|
||||
|
||||
/*!\brief Set the state of a channel immediately and implicitly complete the previous state if needed
|
||||
* \note FTDM_SIGEVENT_INDICATION_COMPLETED will be sent if the state change
|
||||
* is associated to some indication (ie FTDM_CHANNEL_INDICATE_PROCEED)
|
||||
* \note The channel must be locked when calling this function
|
||||
* */
|
||||
FT_DECLARE(ftdm_status_t) _ftdm_set_state(const char *file, const char *func, int line,
|
||||
ftdm_channel_t *fchan, ftdm_channel_state_t state);
|
||||
#define ftdm_set_state(obj, s) _ftdm_set_state(__FILE__, __FUNCTION__, __LINE__, obj, s); \
|
||||
|
||||
/*!\brief This macro is deprecated, signaling modules should always lock the channel themselves anyways since they must
|
||||
* process first the user pending state changes then set a new state before releasing the lock
|
||||
* this macro is here for backwards compatibility, DO NOT USE IT in new code since it is *always* wrong to set
|
||||
* a state in a signaling module without checking and processing the current state first (and for that you must lock the channel)
|
||||
*/
|
||||
#define ftdm_set_state_locked(obj, s) \
|
||||
do { \
|
||||
ftdm_channel_lock(obj); \
|
||||
ftdm_channel_set_state(__FILE__, __FUNCTION__, __LINE__, obj, s, 0); \
|
||||
ftdm_channel_unlock(obj); \
|
||||
} while(0);
|
||||
|
||||
#define ftdm_set_state_r(obj, s, r) r = ftdm_channel_set_state(__FILE__, __FUNCTION__, __LINE__, obj, s, 0);
|
||||
|
||||
#define ftdm_set_state_all(span, state) \
|
||||
do { \
|
||||
uint32_t _j; \
|
||||
ftdm_mutex_lock((span)->mutex); \
|
||||
for(_j = 1; _j <= (span)->chan_count; _j++) { \
|
||||
if (!FTDM_IS_DCHAN(span->channels[_j])) { \
|
||||
ftdm_set_state_locked((span->channels[_j]), state); \
|
||||
} \
|
||||
} \
|
||||
ftdm_mutex_unlock((span)->mutex); \
|
||||
} while (0);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
||||
@@ -69,8 +69,6 @@ extern "C" {
|
||||
#define FTDM_END -1
|
||||
#define FTDM_ANY_STATE -1
|
||||
|
||||
typedef uint64_t ftdm_time_t;
|
||||
|
||||
typedef enum {
|
||||
FTDM_ENDIAN_BIG = 1,
|
||||
FTDM_ENDIAN_LITTLE = -1
|
||||
@@ -123,6 +121,7 @@ typedef enum {
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_analog_start_type, ftdm_analog_start_type2str, ftdm_analog_start_type_t)
|
||||
|
||||
typedef enum {
|
||||
FTDM_OOB_NOOP,
|
||||
FTDM_OOB_ONHOOK,
|
||||
FTDM_OOB_OFFHOOK,
|
||||
FTDM_OOB_WINK,
|
||||
@@ -131,11 +130,11 @@ typedef enum {
|
||||
FTDM_OOB_RING_STOP,
|
||||
FTDM_OOB_ALARM_TRAP,
|
||||
FTDM_OOB_ALARM_CLEAR,
|
||||
FTDM_OOB_NOOP,
|
||||
FTDM_OOB_CAS_BITS_CHANGE,
|
||||
FTDM_OOB_POLARITY_REVERSE,
|
||||
FTDM_OOB_INVALID
|
||||
} ftdm_oob_event_t;
|
||||
#define OOB_STRINGS "ONHOOK", "OFFHOOK", "WINK", "FLASH", "RING_START", "RING_STOP", "ALARM_TRAP", "ALARM_CLEAR", "NOOP", "CAS_BITS_CHANGE", "INVALID"
|
||||
#define OOB_STRINGS "NOOP", "ONHOOK", "OFFHOOK", "WINK", "FLASH", "RING_START", "RING_STOP", "ALARM_TRAP", "ALARM_CLEAR", "CAS_BITS_CHANGE", "POLARITY_REVERSE", "INVALID"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_oob_event, ftdm_oob_event2str, ftdm_oob_event_t)
|
||||
|
||||
/*! \brief Event types */
|
||||
@@ -169,7 +168,7 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
FTDM_SPAN_CONFIGURED = (1 << 0),
|
||||
FTDM_SPAN_READY = (1 << 1),
|
||||
FTDM_SPAN_STARTED = (1 << 1),
|
||||
FTDM_SPAN_STATE_CHANGE = (1 << 2),
|
||||
FTDM_SPAN_SUSPENDED = (1 << 3),
|
||||
FTDM_SPAN_IN_THREAD = (1 << 4),
|
||||
@@ -203,113 +202,56 @@ typedef enum {
|
||||
FTDM_CHANNEL_FEATURE_IO_STATS = (1<<9), /*!< Channel supports IO statistics (HDLC channels only) */
|
||||
} ftdm_channel_feature_t;
|
||||
|
||||
typedef enum {
|
||||
FTDM_CHANNEL_STATE_DOWN,
|
||||
FTDM_CHANNEL_STATE_HOLD,
|
||||
FTDM_CHANNEL_STATE_SUSPENDED,
|
||||
FTDM_CHANNEL_STATE_DIALTONE,
|
||||
FTDM_CHANNEL_STATE_COLLECT,
|
||||
FTDM_CHANNEL_STATE_RING,
|
||||
FTDM_CHANNEL_STATE_RINGING,
|
||||
FTDM_CHANNEL_STATE_BUSY,
|
||||
FTDM_CHANNEL_STATE_ATTN,
|
||||
FTDM_CHANNEL_STATE_GENRING,
|
||||
FTDM_CHANNEL_STATE_DIALING,
|
||||
FTDM_CHANNEL_STATE_GET_CALLERID,
|
||||
FTDM_CHANNEL_STATE_CALLWAITING,
|
||||
FTDM_CHANNEL_STATE_RESTART,
|
||||
FTDM_CHANNEL_STATE_PROCEED,
|
||||
FTDM_CHANNEL_STATE_PROGRESS,
|
||||
FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
|
||||
FTDM_CHANNEL_STATE_UP,
|
||||
FTDM_CHANNEL_STATE_IDLE,
|
||||
FTDM_CHANNEL_STATE_TERMINATING,
|
||||
FTDM_CHANNEL_STATE_CANCEL,
|
||||
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", "RESET", "INVALID"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t)
|
||||
/*!< 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)
|
||||
|
||||
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
|
||||
/* this 3 flags are really nonsense used by boost module only, as soon
|
||||
* as we deprecate/delete boost module we can get rid of them
|
||||
* ==================
|
||||
* */
|
||||
#define FTDM_CHANNEL_PROGRESS (1ULL << 21)
|
||||
#define FTDM_CHANNEL_MEDIA (1ULL << 22)
|
||||
#define FTDM_CHANNEL_ANSWERED (1ULL << 23)
|
||||
/* ================== */
|
||||
|
||||
typedef enum {
|
||||
ZSM_NONE,
|
||||
ZSM_UNACCEPTABLE,
|
||||
ZSM_ACCEPTABLE
|
||||
} ftdm_state_map_type_t;
|
||||
#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)
|
||||
/*!< The user wants non-blocking operations in the channel */
|
||||
#define FTDM_CHANNEL_NONBLOCK (1ULL << 33)
|
||||
/*!< There is a pending acknowledge for an indication */
|
||||
#define FTDM_CHANNEL_IND_ACK_PENDING (1ULL << 34)
|
||||
/*!< There is someone blocking in the channel waiting for state completion */
|
||||
#define FTDM_CHANNEL_BLOCKING (1ULL << 35)
|
||||
|
||||
typedef enum {
|
||||
ZSD_INBOUND,
|
||||
ZSD_OUTBOUND,
|
||||
} ftdm_state_direction_t;
|
||||
|
||||
#define FTDM_MAP_NODE_SIZE 512
|
||||
#define FTDM_MAP_MAX FTDM_CHANNEL_STATE_INVALID+2
|
||||
|
||||
struct ftdm_state_map_node {
|
||||
ftdm_state_direction_t direction;
|
||||
ftdm_state_map_type_t type;
|
||||
ftdm_channel_state_t check_states[FTDM_MAP_MAX];
|
||||
ftdm_channel_state_t states[FTDM_MAP_MAX];
|
||||
};
|
||||
typedef struct ftdm_state_map_node ftdm_state_map_node_t;
|
||||
|
||||
struct ftdm_state_map {
|
||||
ftdm_state_map_node_t nodes[FTDM_MAP_NODE_SIZE];
|
||||
};
|
||||
typedef struct ftdm_state_map ftdm_state_map_t;
|
||||
#include "ftdm_state.h"
|
||||
|
||||
typedef enum ftdm_channel_hw_link_status {
|
||||
FTDM_HW_LINK_DISCONNECTED = 0,
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/* WARNING WORK IN PROGRESS
|
||||
* mstm3ua.c
|
||||
* mstss7d port
|
||||
*
|
||||
* Created by Shane Burrell on 2/2/08.
|
||||
* Copyright 2008 Shane Burrell. 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 "mstm3ua.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int build_m3ua_hdr(unsigned char len,unsigned char *bytemsg)
|
||||
|
||||
{
|
||||
|
||||
*bytemsg++ = M_VERSION_REL1; // 1 Verison
|
||||
//bytemsg[1] = 0x00; // 2 RESERVED
|
||||
//bytemsg[2] = M_CLASS_XFER; // 3 Msg Class
|
||||
//SS7 BOX Kludge
|
||||
*bytemsg++ = 0x01; // 2 RESERVED
|
||||
*bytemsg++ = 0x00; // 2 RESERVED
|
||||
|
||||
*bytemsg++ = M_TYPE_DATA ; // 4 Msg Type
|
||||
|
||||
*bytemsg++ = len; // 5 Msg LENGTH 81 32bit field
|
||||
*bytemsg++ = 0x00; // 6
|
||||
*bytemsg++ = 0x00; // 7
|
||||
*bytemsg++ = 0x00; // 8
|
||||
return(0);
|
||||
|
||||
};
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* mstm3ua.h
|
||||
* mstss7d
|
||||
*
|
||||
* Created by Shane Burrell on 3/2/08.
|
||||
* Copyright 2008 Shane Burrell. 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.
|
||||
*/
|
||||
typedef unsigned long m3ua_ulong;
|
||||
typedef unsigned short m3ua_ushort;
|
||||
typedef unsigned char m3ua_uchar;
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16; /* Note: multi-byte values are little-endian */
|
||||
typedef unsigned long u32;
|
||||
|
||||
|
||||
|
||||
|
||||
#define M_TAG_NETWORK_APPEARANCE 1
|
||||
#define M_TAG_PROTOCOL_DATA 3
|
||||
#define M_TAG_INFO_STRING 4
|
||||
#define M_TAG_AFFECTED_DPC 5
|
||||
#define M_TAG_ROUTING_CONTEXT 6
|
||||
#define M_TAG_DIAGNOSTIC_INFORMATION 7
|
||||
#define M_TAG_HEARTBEAT_DATA 8
|
||||
#define M_TAG_UNAVAILABILITY_CAUSE 9
|
||||
#define M_TAG_REASON 10
|
||||
#define M_TAG_TRAFFIC_MODE_TYPE 11
|
||||
#define M_TAG_ERROR_CODE 12
|
||||
#define M_TAG_STATUS_TYPE 13
|
||||
#define M_TAG_CONGESTED_INDICATIONS 14
|
||||
|
||||
#define M_VERSION_REL1 1
|
||||
|
||||
#define M_CLASS_MGMT 0x00
|
||||
#define M_CLASS_XFER 0x01
|
||||
#define M_CLASS_SSNM 0x02
|
||||
#define M_CLASS_ASPSM 0x03
|
||||
#define M_CLASS_ASPTM 0x04
|
||||
#define M_CLASS_RKM 0x09
|
||||
|
||||
#define M_TYPE_ERR (0|M_CLASS_MGMT
|
||||
|
||||
#define M_TYPE_NTFY (1|M_CLASS_XFER)
|
||||
#define M_TYPE_DATA (1|M_CLASS_XFER)
|
||||
|
||||
#define M_TYPE_DUNA (1|M_CLASS_SSNM)
|
||||
#define M_TYPE_DAVA (2|M_CLASS_SSNM)
|
||||
#define M_TYPE_DUAD (3|M_CLASS_SSNM)
|
||||
#define M_TYPE_SCON (4|M_CLASS_SSNM)
|
||||
#define M_TYPE_DUPU (5|M_CLASS_SSNM)
|
||||
|
||||
#define M_TYPE_UP (1|M_CLASS_ASPSM)
|
||||
#define M_TYPE_DOWN (2|M_CLASS_ASPSM)
|
||||
#define M_TYPE_BEAT (3|M_CLASS_ASPSM)
|
||||
#define M_TYPE_UP_ACK (4|M_CLASS_ASPSM)
|
||||
#define M_TYPE_DOWN_ACK (5|M_CLASS_ASPSM)
|
||||
#define M_TYPE_BEAT_ACK (6|M_CLASS_ASPSM)
|
||||
|
||||
#define M_TYPE_ACTIVE (1|M_CLASS_ASPTM)
|
||||
#define M_TYPE_INACTIVE (2|M_CLASS_ASPTM)
|
||||
#define M_TYPE_ACTIVE_ACK (3|M_CLASS_ASPTM)
|
||||
#define M_TYPE_INACTIVE_ACK (4|M_CLASS_ASPTM)
|
||||
|
||||
#define M_CLASS_MASK 0xff00
|
||||
#define M_TYPE_MASK 0x00ff
|
||||
|
||||
@@ -1,333 +0,0 @@
|
||||
/*
|
||||
* m3ua_client.c
|
||||
* freetdm
|
||||
*
|
||||
* Created by Shane Burrell on 4/3/08.
|
||||
* Copyright 2008 Shane Burrell. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II, Nenad Corbic
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include "freetdm.h"
|
||||
#include <m3ua_client.h>
|
||||
|
||||
|
||||
#ifndef HAVE_GETHOSTBYNAME_R
|
||||
extern int gethostbyname_r (const char *__name,
|
||||
struct hostent *__result_buf,
|
||||
char *__buf, size_t __buflen,
|
||||
struct hostent **__result,
|
||||
int *__h_errnop);
|
||||
#endif
|
||||
|
||||
struct m3uac_map {
|
||||
uint32_t event_id;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static struct m3uac_map m3uac_table[] = {
|
||||
{M3UA_EVENT_CALL_START, "CALL_START"},
|
||||
{M3UA_EVENT_CALL_START_ACK, "CALL_START_ACK"},
|
||||
{M3UA_EVENT_CALL_START_NACK, "CALL_START_NACK"},
|
||||
{M3UA_EVENT_CALL_START_NACK_ACK, "CALL_START_NACK_ACK"},
|
||||
{M3UA_EVENT_CALL_ANSWERED, "CALL_ANSWERED"},
|
||||
{M3UA_EVENT_CALL_STOPPED, "CALL_STOPPED"},
|
||||
{M3UA_EVENT_CALL_STOPPED_ACK, "CALL_STOPPED_ACK"},
|
||||
{M3UA_EVENT_SYSTEM_RESTART, "SYSTEM_RESTART"},
|
||||
{M3UA_EVENT_SYSTEM_RESTART_ACK, "SYSTEM_RESTART_ACK"},
|
||||
{M3UA_EVENT_HEARTBEAT, "HEARTBEAT"},
|
||||
{M3UA_EVENT_INSERT_CHECK_LOOP, "LOOP START"},
|
||||
{M3UA_EVENT_REMOVE_CHECK_LOOP, "LOOP STOP"}
|
||||
};
|
||||
|
||||
|
||||
|
||||
static int create_conn_socket(m3uac_connection_t *mcon, char *local_ip, int local_port, char *ip, int port)
|
||||
{
|
||||
int rc;
|
||||
struct hostent *result, *local_result;
|
||||
char buf[512], local_buf[512];
|
||||
int err = 0;
|
||||
|
||||
memset(&mcon->remote_hp, 0, sizeof(mcon->remote_hp));
|
||||
memset(&mcon->local_hp, 0, sizeof(mcon->local_hp));
|
||||
mcon->socket = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Creating L=%s:%d R=%s:%d\n",
|
||||
local_ip,local_port,ip,port);
|
||||
|
||||
if (mcon->socket >= 0) {
|
||||
int flag;
|
||||
|
||||
flag = 1;
|
||||
gethostbyname_r(ip, &mcon->remote_hp, buf, sizeof(buf), &result, &err);
|
||||
gethostbyname_r(local_ip, &mcon->local_hp, local_buf, sizeof(local_buf), &local_result, &err);
|
||||
if (result && local_result) {
|
||||
mcon->remote_addr.sin_family = mcon->remote_hp.h_addrtype;
|
||||
memcpy((char *) &mcon->remote_addr.sin_addr.s_addr, mcon->remote_hp.h_addr_list[0], mcon->remote_hp.h_length);
|
||||
mcon->remote_addr.sin_port = htons(port);
|
||||
|
||||
mcon->local_addr.sin_family = mcon->local_hp.h_addrtype;
|
||||
memcpy((char *) &mcon->local_addr.sin_addr.s_addr, mcon->local_hp.h_addr_list[0], mcon->local_hp.h_length);
|
||||
mcon->local_addr.sin_port = htons(local_port);
|
||||
|
||||
|
||||
setsockopt(mcon->socket, IPPROTO_SCTP, SCTP_NODELAY, (char *)&flag, sizeof(int));
|
||||
|
||||
rc=listen(mcon->socket,100);
|
||||
if (rc) {
|
||||
close(mcon->socket);
|
||||
mcon->socket = -1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_mutex_create(&mcon->mutex);
|
||||
|
||||
return mcon->socket;
|
||||
}
|
||||
|
||||
int m3uac_connection_close(m3uac_connection_t *mcon)
|
||||
{
|
||||
if (mcon->socket > -1) {
|
||||
close(mcon->socket);
|
||||
}
|
||||
|
||||
ftdm_mutex_lock(mcon->mutex);
|
||||
ftdm_mutex_unlock(mcon->mutex);
|
||||
ftdm_mutex_destroy(&mcon->mutex);
|
||||
memset(mcon, 0, sizeof(*mcon));
|
||||
mcon->socket = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int m3uac_connection_open(m3uac_connection_t *mcon, char *local_ip, int local_port, char *ip, int port)
|
||||
{
|
||||
create_conn_socket(mcon, local_ip, local_port, ip, port);
|
||||
return mcon->socket;
|
||||
}
|
||||
|
||||
|
||||
int m3uac_exec_command(m3uac_connection_t *mcon, int span, int chan, int id, int cmd, int cause)
|
||||
{
|
||||
m3uac_event_t oevent;
|
||||
int retry = 5;
|
||||
|
||||
m3uac_event_init(&oevent, cmd, chan, span);
|
||||
oevent.release_cause = cause;
|
||||
|
||||
if (cmd == SIGBOOST_EVENT_SYSTEM_RESTART) {
|
||||
mcon->rxseq_reset = 1;
|
||||
mcon->txseq = 0;
|
||||
mcon->rxseq = 0;
|
||||
mcon->txwindow = 0;
|
||||
}
|
||||
|
||||
if (id >= 0) {
|
||||
oevent.call_setup_id = id;
|
||||
}
|
||||
|
||||
while (m3uac_connection_write(mcon, &oevent) <= 0) {
|
||||
if (--retry <= 0) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to tx on M3UA socket: %s\n", strerror(errno));
|
||||
return -1;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Failed to tx on M3UA socket: %s :retry %i\n", strerror(errno), retry);
|
||||
ftdm_sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
m3uac_event_t *m3uac_connection_read(m3uac_connection_t *mcon, int iteration)
|
||||
{
|
||||
unsigned int fromlen = sizeof(struct sockaddr_in);
|
||||
int bytes = 0;
|
||||
|
||||
bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT,
|
||||
(struct sockaddr *) &mcon->local_addr, &fromlen);
|
||||
|
||||
if (bytes == sizeof(mcon->event) || bytes == (sizeof(mcon->event)-sizeof(uint32_t))) {
|
||||
|
||||
if (mcon->rxseq_reset) {
|
||||
if (mcon->event.event_id == SIGBOOST_EVENT_SYSTEM_RESTART_ACK) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Rx sync ok\n");
|
||||
mcon->rxseq = mcon->event.fseqno;
|
||||
return &mcon->event;
|
||||
}
|
||||
errno=EAGAIN;
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Waiting for rx sync...\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mcon->txwindow = mcon->txseq - mcon->event.bseqno;
|
||||
mcon->rxseq++;
|
||||
|
||||
if (mcon->rxseq != mcon->event.fseqno) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Invalid Sequence Number Expect=%i Rx=%i\n", mcon->rxseq, mcon->event.fseqno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &mcon->event;
|
||||
} else {
|
||||
if (iteration == 0) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Invalid Event length from boost rxlen=%i evsz=%i\n", bytes, sizeof(mcon->event));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m3uac_event_t *m3uac_connection_readp(m3uac_connection_t *mcon, int iteration)
|
||||
{
|
||||
unsigned int fromlen = sizeof(struct sockaddr_in);
|
||||
int bytes = 0;
|
||||
|
||||
bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, (struct sockaddr *) &mcon->local_addr, &fromlen);
|
||||
|
||||
if (bytes == sizeof(mcon->event) || bytes == (sizeof(mcon->event)-sizeof(uint32_t))) {
|
||||
return &mcon->event;
|
||||
} else {
|
||||
if (iteration == 0) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Critical Error: PQ Invalid Event lenght from boost rxlen=%i evsz=%i\n", bytes, sizeof(mcon->event));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int m3uac_connection_write(m3uac_connection_t *mcon, ss7bc_event_t *event)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!event || mcon->socket < 0 || !mcon->mutex) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Critical Error: No Event Device\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (event->span > 16 || event->chan > 31) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Critical Error: TX Cmd=%s Invalid Span=%i Chan=%i\n", m3uac_event_id_name(event->event_id), event->span,event->chan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
gettimeofday(&event->tv,NULL);
|
||||
|
||||
ftdm_mutex_lock(mcon->mutex);
|
||||
event->fseqno = mcon->txseq++;
|
||||
event->bseqno = mcon->rxseq;
|
||||
err = sendto(mcon->socket, event, sizeof(m3uac_event_t), 0, (struct sockaddr *) &mcon->remote_addr, sizeof(mcon->remote_addr));
|
||||
ftdm_mutex_unlock(mcon->mutex);
|
||||
|
||||
if (err != sizeof(m3uac_event_t)) {
|
||||
err = -1;
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "TX EVENT: %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i Cd=[%s] Ci=[%s]\n",
|
||||
m3uac_event_id_name(event->event_id),
|
||||
event->event_id,
|
||||
event->span+1,
|
||||
event->chan+1,
|
||||
event->release_cause,
|
||||
event->call_setup_id,
|
||||
event->fseqno,
|
||||
(event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"),
|
||||
(event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")
|
||||
);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void m3uac_call_init(m3uac_event_t *event, const char *calling, const char *called, int setup_id)
|
||||
{
|
||||
memset(event, 0, sizeof(m3uac_event_t));
|
||||
event->event_id = M3UA_EVENT_CALL_START;
|
||||
|
||||
if (calling) {
|
||||
strncpy((char*)event->calling_number_digits, calling, sizeof(event->calling_number_digits)-1);
|
||||
event->calling_number_digits_count = strlen(calling);
|
||||
}
|
||||
|
||||
if (called) {
|
||||
strncpy((char*)event->called_number_digits, called, sizeof(event->called_number_digits)-1);
|
||||
event->called_number_digits_count = strlen(called);
|
||||
}
|
||||
|
||||
event->call_setup_id = setup_id;
|
||||
|
||||
}
|
||||
|
||||
void m3uac_event_init(m3uac_event_t *event, m3uac_event_id_t event_id, int chan, int span)
|
||||
{
|
||||
memset(event, 0, sizeof(ss7bc_event_t));
|
||||
event->event_id = event_id;
|
||||
event->chan = chan;
|
||||
event->span = span;
|
||||
}
|
||||
|
||||
const char *m3uac_event_id_name(uint32_t event_id)
|
||||
{
|
||||
unsigned int x;
|
||||
const char *ret = NULL;
|
||||
|
||||
for (x = 0 ; x < sizeof(m3uac_table)/sizeof(struct m3uac_map); x++) {
|
||||
if (m3uac_table[x].event_id == event_id) {
|
||||
ret = m3uac_table[x].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* m3ua_client.h
|
||||
* freetdm
|
||||
*
|
||||
* Created by Shane Burrell on 4/3/08.
|
||||
* Copyright 2008 Shane Burrell. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II, Nenad Corbic
|
||||
*
|
||||
* 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 <ctype.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
// Fix this for portability
|
||||
#include <sctp.h>
|
||||
//#include <netinet/sctp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdarg.h>
|
||||
#include <netdb.h>
|
||||
//#include <sigboost.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define MAX_DIALED_DIGITS 31
|
||||
#define MAX_CALLING_NAME 31
|
||||
|
||||
/* Next two defines are used to create the range of values for call_setup_id
|
||||
* in the t_sigboost structure.
|
||||
* 0..((CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN) - 1) */
|
||||
#define CORE_MAX_SPANS 200
|
||||
#define CORE_MAX_CHAN_PER_SPAN 30
|
||||
#define MAX_PENDING_CALLS CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN
|
||||
/* 0..(MAX_PENDING_CALLS-1) is range of call_setup_id below */
|
||||
#define SIZE_RDNIS 80
|
||||
|
||||
//#undef MSGWINDOW
|
||||
#define MSGWINDOW
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t event_id;
|
||||
uint32_t fseqno;
|
||||
#ifdef MSGWINDOW
|
||||
uint32_t bseqno;
|
||||
#endif
|
||||
uint16_t call_setup_id;
|
||||
uint32_t trunk_group;
|
||||
uint32_t span;
|
||||
uint32_t chan;
|
||||
uint8_t called_number_digits_count;
|
||||
char called_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */
|
||||
uint8_t calling_number_digits_count; /* it's an array */
|
||||
char calling_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */
|
||||
uint8_t release_cause;
|
||||
struct timeval tv;
|
||||
/* ref. Q.931 Table 4-11 and Q.951 Section 3 */
|
||||
uint8_t calling_number_screening_ind;
|
||||
uint8_t calling_number_presentation;
|
||||
char redirection_string [SIZE_RDNIS]; /* it's a null terminated string */
|
||||
|
||||
} t_m3ua;
|
||||
|
||||
typedef t_m3ua m3uac_event_t;
|
||||
typedef uint32_t m3uac_event_id_t;
|
||||
|
||||
|
||||
typedef struct m3uac_ip_cfg
|
||||
{
|
||||
char local_ip[25];
|
||||
int local_port;
|
||||
char remote_ip[25];
|
||||
int remote_port;
|
||||
}m3uac_ip_cfg_t;
|
||||
|
||||
struct m3uac_connection {
|
||||
ftdm_socket_t socket;
|
||||
struct sockaddr_in local_addr;
|
||||
struct sockaddr_in remote_addr;
|
||||
m3uac_event_t event;
|
||||
struct hostent remote_hp;
|
||||
struct hostent local_hp;
|
||||
unsigned int flags;
|
||||
ftdm_mutex_t *mutex;
|
||||
FILE *log;
|
||||
unsigned int txseq;
|
||||
unsigned int rxseq;
|
||||
unsigned int txwindow;
|
||||
unsigned int rxseq_reset;
|
||||
m3uac_ip_cfg_t cfg;
|
||||
uint32_t hb_elapsed;
|
||||
int up;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
MSU_FLAG_EVENT = (1 << 0)
|
||||
} m3uac_flag_t;
|
||||
|
||||
typedef struct m3uac_connection m3uac_connection_t;
|
||||
|
||||
static inline void sctp_no_nagle(int socket)
|
||||
{
|
||||
//int flag = 1;
|
||||
//setsockopt(socket, IPPROTO_SCTP, SCTP_NODELAY, (char *) &flag, sizeof(int));
|
||||
}
|
||||
|
||||
int m3uac_connection_close(m3uac_connection_t *mcon);
|
||||
int m3uac_connection_open(m3uac_connection_t *mcon, char *local_ip, int local_port, char *ip, int port);
|
||||
m3uac_event_t *m3uac_connection_read(m3uac_connection_t *mcon, int iteration);
|
||||
m3uac_event_t *m3uac_connection_readp(m3uac_connection_t *mcon, int iteration);
|
||||
int m3uac_connection_write(m3uac_connection_t *mcon, m3uac_event_t *event);
|
||||
void m3uac_event_init(m3uac_event_t *event, m3uac_event_id_t event_id, int chan, int span);
|
||||
void m3uac_call_init(m3uac_event_t *event, const char *calling, const char *called, int setup_id);
|
||||
const char *m3uac_event_id_name(uint32_t event_id);
|
||||
int m3uac_exec_command(m3uac_connection_t *mcon, int span, int chan, int id, int cmd, int cause);
|
||||
|
||||
|
||||
|
||||
|
||||
/* 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:
|
||||
*/
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* testm3ua.c
|
||||
* freetdm
|
||||
*
|
||||
* Created by Shane Burrell on 4/8/08.
|
||||
* Copyright 2008 __MyCompanyName__. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "testm3ua.h"
|
||||
#include "freetdm.h"
|
||||
#include "ftdm_m3ua.h"
|
||||
|
||||
static FIO_SIGNAL_CB_FUNCTION(on_signal)
|
||||
{
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
ftdm_span_t *span;
|
||||
//m3ua_data_t *data;
|
||||
|
||||
ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG);
|
||||
|
||||
if (argc < 5) {
|
||||
printf("more args needed\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (ftdm_global_init() != FTDM_SUCCESS) {
|
||||
fprintf(stderr, "Error loading FreeTDM\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
printf("FreeTDM loaded\n");
|
||||
|
||||
if (ftdm_span_find(atoi(argv[1]), &span) != FTDM_SUCCESS) {
|
||||
fprintf(stderr, "Error finding FreeTDM span\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
if (ftdm_m3ua_configure_span(span) == FTDM_SUCCESS) {
|
||||
//data = span->signal_data;
|
||||
ftdm_m3ua_start(span);
|
||||
} else {
|
||||
fprintf(stderr, "Error starting M3UA\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
//while(ftdm_test_flag(data, FTDM_M3UA_RUNNING)) {
|
||||
// ftdm_sleep(1 * 1000);
|
||||
//}
|
||||
|
||||
done:
|
||||
|
||||
ftdm_global_destroy();
|
||||
|
||||
}
|
||||
+112
-32
@@ -2,78 +2,158 @@
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int R = 0;
|
||||
static ftdm_mutex_t *mutex = NULL;
|
||||
static volatile int running = 0;
|
||||
static ftdm_mutex_t *the_mutex = NULL;
|
||||
static ftdm_channel_t *fchan = NULL;
|
||||
static ftdm_channel_indication_t indication = FTDM_CHANNEL_INDICATE_NONE;
|
||||
|
||||
static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
|
||||
{
|
||||
int chanid = ftdm_channel_get_ph_id(sigmsg->channel);
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Got R2 channel sig [%s] in channel\n", ftdm_signal_event2str(sigmsg->event_id), chanid);
|
||||
return FTDM_SUCCESS;
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Got R2 channel sig [%s] in channel\n", ftdm_signal_event2str(sigmsg->event_id), chanid);
|
||||
switch (sigmsg->event_id) {
|
||||
case FTDM_SIGEVENT_START:
|
||||
{
|
||||
ftdm_mutex_lock(the_mutex);
|
||||
if (!fchan) {
|
||||
fchan = sigmsg->channel;
|
||||
indication = FTDM_CHANNEL_INDICATE_PROCEED;
|
||||
}
|
||||
ftdm_mutex_unlock(the_mutex);
|
||||
}
|
||||
break;
|
||||
case FTDM_SIGEVENT_INDICATION_COMPLETED:
|
||||
{
|
||||
ftdm_channel_indication_t ind = FTDM_CHANNEL_INDICATE_NONE;
|
||||
if (sigmsg->ev_data.indication_completed.indication == FTDM_CHANNEL_INDICATE_PROCEED) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Proceed indication result = %d\n", sigmsg->ev_data.indication_completed.status);
|
||||
ind = FTDM_CHANNEL_INDICATE_PROGRESS;
|
||||
} else if (sigmsg->ev_data.indication_completed.indication == FTDM_CHANNEL_INDICATE_PROGRESS) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Progress indication result = %d\n", sigmsg->ev_data.indication_completed.status);
|
||||
ind = FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA;
|
||||
} else if (sigmsg->ev_data.indication_completed.indication == FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Progress media indication result = %d\n", sigmsg->ev_data.indication_completed.status);
|
||||
ind = FTDM_CHANNEL_INDICATE_ANSWER;
|
||||
} else if (sigmsg->ev_data.indication_completed.indication == FTDM_CHANNEL_INDICATE_ANSWER) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Answer indication result = %d\n", sigmsg->ev_data.indication_completed.status);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Unexpected indication, result = %d\n", sigmsg->ev_data.indication_completed.status);
|
||||
exit(1);
|
||||
}
|
||||
ftdm_mutex_lock(the_mutex);
|
||||
if (fchan) {
|
||||
indication = ind;
|
||||
}
|
||||
ftdm_mutex_unlock(the_mutex);
|
||||
}
|
||||
break;
|
||||
case FTDM_SIGEVENT_STOP:
|
||||
{
|
||||
ftdm_channel_call_hangup(sigmsg->channel);
|
||||
}
|
||||
break;
|
||||
case FTDM_SIGEVENT_RELEASED:
|
||||
{
|
||||
ftdm_mutex_lock(the_mutex);
|
||||
if (fchan && fchan == sigmsg->channel) {
|
||||
fchan = NULL;
|
||||
}
|
||||
ftdm_mutex_unlock(the_mutex);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static void handle_SIGINT(int sig)
|
||||
static void stop_test(int sig)
|
||||
{
|
||||
ftdm_mutex_lock(mutex);
|
||||
R = 0;
|
||||
ftdm_mutex_unlock(mutex);
|
||||
return;
|
||||
running = 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
ftdm_span_t *span;
|
||||
ftdm_mutex_create(&mutex);
|
||||
|
||||
ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG);
|
||||
ftdm_conf_parameter_t parameters[20];
|
||||
|
||||
ftdm_mutex_create(&the_mutex);
|
||||
|
||||
if (argc < 2) {
|
||||
printf("umm no\n");
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG);
|
||||
|
||||
if (ftdm_global_init() != FTDM_SUCCESS) {
|
||||
fprintf(stderr, "Error loading FreeTDM\n");
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ftdm_global_configuration();
|
||||
|
||||
printf("FreeTDM loaded\n");
|
||||
|
||||
if (ftdm_span_find(atoi(argv[1]), &span) != FTDM_SUCCESS) {
|
||||
fprintf(stderr, "Error finding FreeTDM span\n");
|
||||
if (ftdm_span_find_by_name(argv[1], &span) != FTDM_SUCCESS) {
|
||||
fprintf(stderr, "Error finding FreeTDM span %s\n", argv[1]);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* testing non-blocking operation */
|
||||
//ftdm_span_set_blocking_mode(span, FTDM_FALSE);
|
||||
|
||||
parameters[0].var = "variant";
|
||||
parameters[0].val = "br";
|
||||
|
||||
if (ftdm_configure_span(span, "r2", on_r2_signal,
|
||||
"variant", "mx",
|
||||
"max_ani", 10,
|
||||
"max_dnis", 4,
|
||||
"logging", "all",
|
||||
FTDM_TAG_END) == FTDM_SUCCESS) {
|
||||
|
||||
parameters[1].var = "max_ani";
|
||||
parameters[1].val = "4";
|
||||
|
||||
parameters[2].var = "max_dnis";
|
||||
parameters[2].val = "4";
|
||||
|
||||
parameters[3].var = "logging";
|
||||
parameters[3].val = "all";
|
||||
|
||||
parameters[4].var = NULL;
|
||||
parameters[4].val = NULL;
|
||||
|
||||
if (ftdm_configure_span_signaling(span, "r2", on_r2_signal, parameters) == FTDM_SUCCESS) {
|
||||
ftdm_span_start(span);
|
||||
} else {
|
||||
fprintf(stderr, "Error starting R2 span\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
signal(SIGINT, handle_SIGINT);
|
||||
ftdm_mutex_lock(mutex);
|
||||
R = 1;
|
||||
ftdm_mutex_unlock(mutex);
|
||||
while(R) {
|
||||
ftdm_sleep(1 * 1000);
|
||||
running = 1;
|
||||
signal(SIGINT, stop_test);
|
||||
while(running) {
|
||||
ftdm_sleep(20);
|
||||
if (fchan && indication != FTDM_CHANNEL_INDICATE_NONE) {
|
||||
ftdm_channel_t *lchan = NULL;
|
||||
ftdm_channel_indication_t ind = FTDM_CHANNEL_INDICATE_NONE;
|
||||
ftdm_time_t start, stop, diff;
|
||||
|
||||
ftdm_mutex_lock(the_mutex);
|
||||
ind = indication;
|
||||
indication = FTDM_CHANNEL_INDICATE_NONE;
|
||||
lchan = fchan;
|
||||
ftdm_mutex_unlock(the_mutex);
|
||||
|
||||
start = ftdm_current_time_in_ms();
|
||||
ftdm_channel_call_indicate(lchan, ind);
|
||||
stop = ftdm_current_time_in_ms();
|
||||
diff = stop - start;
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Setting indication %s took %llums\n",
|
||||
ftdm_channel_indication2str(ind), diff);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
done:
|
||||
|
||||
ftdm_global_destroy();
|
||||
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
|
||||
@@ -84,7 +84,7 @@ AC_ARG_ENABLE(64,
|
||||
if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then
|
||||
if test "${enable_64}" = "yes"; then
|
||||
CFLAGS="$CFLAGS -m64"
|
||||
CXXFLAGS="$CXXFLAGS -m64"
|
||||
CXXFLAGS="$CXXFLAGS -m64 -lgpg-error"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program; if not, write to the Free Software
|
||||
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
##
|
||||
## $Id: Makefile.am,v 1.6 2008/09/30 14:06:39 steveu Exp $
|
||||
|
||||
AM_CFLAGS = $(COMP_VENDOR_CFLAGS)
|
||||
AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)
|
||||
@@ -26,6 +24,7 @@ noinst_SCRIPTS = g722_1.spec
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
EXTRA_DIST = autogen.sh \
|
||||
g722_1.pc \
|
||||
g722_1.spec \
|
||||
unpack_g722_1_data.sh \
|
||||
wrapper.xsl \
|
||||
@@ -50,6 +49,9 @@ SUBDIRS = src $(MAYBE_DOC) $(MAYBE_TESTS)
|
||||
|
||||
DIST_SUBDIRS = src doc tests test-data
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = g722_1.pc
|
||||
|
||||
faq: faq.xml
|
||||
cd faq ; xsltproc ../wrapper.xsl ../faq.xml
|
||||
|
||||
|
||||
@@ -16,11 +16,6 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id: autogen.sh,v 1.1.1.1 2008/09/20 09:47:17 steveu Exp $
|
||||
#
|
||||
|
||||
UNAME=`uname`
|
||||
|
||||
if [ "x$UNAME" = "xFreeBSD" ]; then
|
||||
echo ""
|
||||
|
||||
+21
-15
@@ -15,17 +15,11 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id: configure.ac,v 1.9 2008/10/09 14:17:12 steveu Exp $
|
||||
|
||||
# @start 1
|
||||
|
||||
AC_INIT
|
||||
|
||||
CFLAGS="$CFLAGS $CONFIGURE_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $CONFIGURE_CXXFLAGS"
|
||||
LDFLAGS="$LDFLAGS $CONFIGURE_LDFLAGS"
|
||||
|
||||
m4_include(config/ax_compiler_vendor.m4)
|
||||
m4_include(config/ax_check_real_file.m4)
|
||||
m4_include(config/ax_fixed_point_machine.m4)
|
||||
@@ -111,6 +105,22 @@ else
|
||||
CXXFLAGS=${CXXFLAGS-"-g -O2"}
|
||||
fi
|
||||
|
||||
AC_DEFUN([REMOVE_FROM_VAR],[
|
||||
new_val=""
|
||||
removed=0
|
||||
for i in $$1; do
|
||||
if test "x$i" != "x$2"; then
|
||||
new_val="$new_val $i"
|
||||
else
|
||||
removed=1
|
||||
fi
|
||||
done
|
||||
if test $removed = "1"; then
|
||||
echo " removed \"$2\" from $1"
|
||||
$1=$new_val
|
||||
fi
|
||||
])
|
||||
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
AC_C_VOLATILE
|
||||
@@ -190,7 +200,7 @@ AC_CHECK_HEADERS([audiofile.h])
|
||||
|
||||
AC_LANG([C])
|
||||
|
||||
if test "${build}" = "${host}"
|
||||
if test "${build}" == "${host}"
|
||||
then
|
||||
case "${host}" in
|
||||
x86_64-*)
|
||||
@@ -270,6 +280,7 @@ sun)
|
||||
COMP_VENDOR_CFLAGS="-native -fast $COMP_VENDOR_CFLAGS"
|
||||
fi
|
||||
COMP_VENDOR_LDFLAGS=
|
||||
REMOVE_FROM_VAR(CFLAGS, -Xc)
|
||||
;;
|
||||
*)
|
||||
COMP_VENDOR_CFLAGS="-std=c99 -Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes"
|
||||
@@ -293,20 +304,14 @@ AM_CONDITIONAL([COND_SSE5], [test "$enable_sse5" = yes])
|
||||
if test "$enable_fixed_point" = "yes" ; then
|
||||
AC_DEFINE([G722_1_USE_FIXED_POINT], [1], [Enable fixed point processing, where possible, instead of floating point])
|
||||
G722_1_USE_FIXED_POINT="#define G722_1_USE_FIXED_POINT 1"
|
||||
fixed = "yes"
|
||||
G722_1_VECTORS_FOR_TESTS="fixed"
|
||||
else
|
||||
AX_FIXED_POINT_MACHINE([$host],
|
||||
[
|
||||
AC_DEFINE([G722_1_USE_FIXED_POINT], [1], [Enable fixed point processing, where possible, instead of floating point])
|
||||
G722_1_USE_FIXED_POINT="#define G722_1_USE_FIXED_POINT 1"
|
||||
fixed = "yes"
|
||||
],
|
||||
[AC_DEFINE([G722_1_USE_FIXED_POINT], [1], [Enable fixed point processing, where possible, instead of floating point])
|
||||
G722_1_USE_FIXED_POINT="#define G722_1_USE_FIXED_POINT 1"],
|
||||
[G722_1_USE_FIXED_POINT="#undef G722_1_USE_FIXED_POINT"])
|
||||
G722_1_VECTORS_FOR_TESTS="floating"
|
||||
fi
|
||||
AM_CONDITIONAL([COND_FIXED], [test "$fixed" = "yes"])
|
||||
|
||||
AX_MISALIGNED_ACCESS_FAILS([$host],
|
||||
[AC_DEFINE([G722_1_MISALIGNED_ACCESS_FAILS], [1], [Do not expect a misaligned memory access to work correctly])
|
||||
G722_1_MISALIGNED_ACCESS_FAILS="#define G722_1_MISALIGNED_ACCESS_FAILS 1"],
|
||||
@@ -363,6 +368,7 @@ AC_CONFIG_FILES([Makefile
|
||||
src/Makefile
|
||||
src/g722_1.h
|
||||
tests/Makefile
|
||||
g722_1.pc
|
||||
g722_1.spec])
|
||||
|
||||
AC_CONFIG_FILES([tests/regression_tests.sh], [chmod +x tests/regression_tests.sh])
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program; if not, write to the Free Software
|
||||
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
##
|
||||
## $Id: Makefile.am,v 1.1.1.1 2008/09/20 09:47:17 steveu Exp $
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: spandsp
|
||||
Description: A library for the ITU G.722.1 and G.722.1C audio codecs.
|
||||
Requires:
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lg722_1 -lm
|
||||
Cflags: -I${includedir}
|
||||
@@ -47,14 +47,13 @@ rm -rf %{buildroot}
|
||||
|
||||
%{_libdir}/libg722_1.so.*
|
||||
|
||||
%{_datadir}/libg722_1
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root,-)
|
||||
%doc doc/api
|
||||
%{_includedir}/g722_1.h
|
||||
%{_includedir}/g722_1
|
||||
%{_libdir}/libg722_1.so
|
||||
%{_libdir}/pkgconfig/g722_1.pc
|
||||
|
||||
%post -p /sbin/ldconfig
|
||||
|
||||
|
||||
@@ -15,18 +15,19 @@
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program; if not, write to the Free Software
|
||||
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
##
|
||||
## $Id: Makefile.am,v 1.10 2008/10/16 15:46:12 steveu Exp $
|
||||
|
||||
AM_CFLAGS = $(COMP_VENDOR_CFLAGS)
|
||||
AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
EXTRA_DIST = g722_1/version.h.in \
|
||||
EXTRA_DIST = make_tables.c \
|
||||
g722_1/version.h.in \
|
||||
libg722_1.dsp \
|
||||
libg722_1.sln \
|
||||
libg722_1.vcproj \
|
||||
libg722_1.2005.sln \
|
||||
libg722_1.2008.sln \
|
||||
libg722_1.2005.vcproj \
|
||||
libg722_1.2008.vcproj \
|
||||
msvc/gettimeofday.c \
|
||||
msvc/inttypes.h \
|
||||
msvc/tgmath.h \
|
||||
@@ -36,13 +37,16 @@ EXTRA_DIST = g722_1/version.h.in \
|
||||
msvc/msvcproj.head \
|
||||
msvc/msvcproj.foot \
|
||||
msvc/vc8proj.head \
|
||||
msvc/vc8proj.foot
|
||||
msvc/vc8proj.foot \
|
||||
msvc/vc9proj.head \
|
||||
msvc/vc9proj.foot
|
||||
|
||||
INCLUDES = -I$(top_builddir)
|
||||
|
||||
lib_LTLIBRARIES = libg722_1.la
|
||||
|
||||
libg722_1_la_SOURCES = bitstream.c \
|
||||
libg722_1_la_SOURCES = basop32.c \
|
||||
bitstream.c \
|
||||
coef2sam.c \
|
||||
common.c \
|
||||
commonf.c \
|
||||
@@ -55,11 +59,9 @@ libg722_1_la_SOURCES = bitstream.c \
|
||||
encoderf.c \
|
||||
huff_tab.c \
|
||||
sam2coef.c \
|
||||
tables.c
|
||||
tables.c \
|
||||
utilities.c
|
||||
|
||||
if COND_FIXED
|
||||
libg722_1_la_SOURCES += basop32.c
|
||||
endif
|
||||
libg722_1_la_LDFLAGS = -version-info @G722_1_LT_CURRENT@:@G722_1_LT_REVISION@:@G722_1_LT_AGE@ $(COMP_VENDOR_LDFLAGS)
|
||||
|
||||
nobase_include_HEADERS = g722_1/g722_1.h \
|
||||
@@ -76,10 +78,10 @@ noinst_HEADERS = basop32.h \
|
||||
defs.h \
|
||||
huff_tab.h \
|
||||
sam2coef.h \
|
||||
tables.h
|
||||
tables.h \
|
||||
utilities.h
|
||||
|
||||
noinst_PROGRAMS = make_dct4_tables \
|
||||
make_tables
|
||||
noinst_PROGRAMS = make_dct4_tables
|
||||
|
||||
dct4.$(OBJEXT): dct4.h
|
||||
|
||||
@@ -88,6 +90,9 @@ dct4.lo: dct4.h
|
||||
dct4.h: make_dct4_tables$(EXEEXT)
|
||||
./make_dct4_tables$(EXEEXT) >dct4.h
|
||||
|
||||
make_dct4_tables$(EXEEXT): $(top_srcdir)/src/make_dct4_tables.c
|
||||
$(CC_FOR_BUILD) -o make_dct4_tables$(EXEEXT) $(top_srcdir)/src/make_dct4_tables.c -DHAVE_CONFIG_H -I$(top_builddir)/src -lm
|
||||
|
||||
#coef2sam.h: make_tables$(EXEEXT)
|
||||
# ./make_tables$(EXEEXT) coef2sam >coef2samx.h
|
||||
|
||||
@@ -95,13 +100,15 @@ dct4.h: make_dct4_tables$(EXEEXT)
|
||||
# ./make_tables$(EXEEXT) sam2coef >sam2coefx.h
|
||||
|
||||
DSP = libg722_1.dsp
|
||||
VCPROJ = libg722_1.vcproj
|
||||
VCPROJ8 = libg722_1.2005.vcproj
|
||||
VCPROJ9 = libg722_1.2008.vcproj
|
||||
|
||||
WIN32SOURCES = $(libg722_1_la_SOURCES) msvc/gettimeofday.c
|
||||
WIN32HEADERS = $(nobase_include_HEADERS) g722_1.h
|
||||
|
||||
DSPOUT = | awk '{printf("%s\r\n", $$0)}' >> $(DSP)
|
||||
VCPROJOUT = | awk '{printf("%s\r\n", $$0)}' >> $(VCPROJ)
|
||||
VCPROJOUT8 = | awk '{printf("%s\r\n", $$0)}' >> $(VCPROJ8)
|
||||
VCPROJOUT9 = | awk '{printf("%s\r\n", $$0)}' >> $(VCPROJ9)
|
||||
|
||||
$(DSP): msvc/msvcproj.head msvc/msvcproj.foot Makefile.am
|
||||
echo "creating $(DSP)"
|
||||
@@ -124,26 +131,38 @@ $(DSP): msvc/msvcproj.head msvc/msvcproj.foot Makefile.am
|
||||
echo "# End Group" $(DSPOUT); \
|
||||
cat $(srcdir)/msvc/msvcproj.foot $(DSPOUT) )
|
||||
|
||||
$(VCPROJ): msvc/vc8proj.head msvc/vc8proj.foot Makefile.am
|
||||
echo "creating $(VCPROJ)"
|
||||
@(cp $(srcdir)/msvc/vc8proj.head $(VCPROJ); \
|
||||
$(VCPROJ8): msvc/vc8proj.head msvc/vc8proj.foot Makefile.am
|
||||
echo "creating $(VCPROJ8)"
|
||||
@(cp $(srcdir)/msvc/vc8proj.head $(VCPROJ8); \
|
||||
for file in $(WIN32SOURCES); do \
|
||||
echo "<File RelativePath=\""$$file"\"></File>" $(VCPROJOUT); \
|
||||
myfile=`echo $$file | sed -e 's|/|\\\\|g'`; \
|
||||
echo "<File RelativePath=\""$$myfile"\"></File>" $(VCPROJOUT8); \
|
||||
done; \
|
||||
echo "</Filter><Filter Name=\"Header Files\">" $(VCPROJOUT); \
|
||||
echo "</Filter><Filter Name=\"Header Files\">" $(VCPROJOUT8); \
|
||||
for file in $(WIN32HEADERS); do \
|
||||
echo "<File RelativePath=\""$$file"\"></File>" $(VCPROJOUT); \
|
||||
myfile=`echo $$file | sed -e 's|/|\\\\|g'`; \
|
||||
echo "<File RelativePath=\""$$myfile"\"></File>" $(VCPROJOUT8); \
|
||||
done; \
|
||||
cat $(srcdir)/msvc/vc8proj.foot $(VCPROJOUT) )
|
||||
cat $(srcdir)/msvc/vc8proj.foot $(VCPROJOUT8) )
|
||||
|
||||
$(VCPROJ9): msvc/vc9proj.head msvc/vc9proj.foot Makefile.am
|
||||
echo "creating $(VCPROJ9)"
|
||||
@(cp $(srcdir)/msvc/vc9proj.head $(VCPROJ9); \
|
||||
for file in $(WIN32SOURCES); do \
|
||||
myfile=`echo $$file | sed -e 's|/|\\\\|g'`; \
|
||||
echo "<File RelativePath=\""$$myfile"\"></File>" $(VCPROJOUT9); \
|
||||
done; \
|
||||
echo "</Filter><Filter Name=\"Header Files\">" $(VCPROJOUT9); \
|
||||
for file in $(WIN32HEADERS); do \
|
||||
myfile=`echo $$file | sed -e 's|/|\\\\|g'`; \
|
||||
echo "<File RelativePath=\""$$myfile"\"></File>" $(VCPROJOUT9); \
|
||||
done; \
|
||||
cat $(srcdir)/msvc/vc9proj.foot $(VCPROJOUT9) )
|
||||
|
||||
dist-hook: g722_1/version.h
|
||||
|
||||
g722_1/version.h:
|
||||
NOWDATE=`date --utc +"%Y%m%d"` ; \
|
||||
NOWTIME=`date --utc +"%H%M%S"` ; \
|
||||
sed 's/$$G722_1_RELEASE_DATE/'$$NOWDATE'/;s/$$G722_1_RELEASE_TIME/'$$NOWTIME'/' \
|
||||
<g722_1/version.h.in >g722_1/version.h
|
||||
|
||||
dist-hook:
|
||||
NOWDATE=`date --utc +"%Y%m%d"` ; \
|
||||
NOWTIME=`date --utc +"%H%M%S"` ; \
|
||||
sed 's/$$G722_1_RELEASE_DATE/'$$NOWDATE'/;s/$$G722_1_RELEASE_TIME/'$$NOWTIME'/' \
|
||||
<g722_1/version.h.in >g722_1/version.h
|
||||
<$(srcdir)/g722_1/version.h.in >$@
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: basop32.c,v 1.5 2008/09/22 13:08:31 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -19,9 +17,10 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#if defined(G722_1_USE_FIXED_POINT)
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
@@ -6,14 +6,12 @@
|
||||
* Adapted by Steve Underwood <steveu@coppice.org> from the reference
|
||||
* code supplied with ITU G.722.1, which is:
|
||||
*
|
||||
* © 2004 Polycom, Inc.
|
||||
* (C) 2004 Polycom, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: basop32.h,v 1.3 2008/09/22 13:08:31 steveu Exp $
|
||||
*/
|
||||
|
||||
#if !defined(BASOP32_H_DEFINED)
|
||||
@@ -104,14 +102,14 @@ static __inline__ int32_t L_mac(int32_t L_var3, int16_t var1, int16_t var2)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
int16_t shl(int16_t var1, int16_t var2); /* Short shift left, 1 */
|
||||
int16_t shr(int16_t var1, int16_t var2); /* Short shift right, 1 */
|
||||
int32_t L_sub(int32_t L_var1, int32_t L_var2); /* Long sub, 2 */
|
||||
int32_t L_shl(int32_t L_var1, int16_t var2); /* Long shift left, 2 */
|
||||
int32_t L_shr(int32_t L_var1, int16_t var2); /* Long shift right, 2*/
|
||||
int16_t norm_s(int16_t var1); /* Short norm, 15 */
|
||||
int16_t div_s(int16_t var1, int16_t var2); /* Short division, 18 */
|
||||
int16_t norm_l(int32_t L_var1); /* Long norm, 30 */
|
||||
int16_t shl(int16_t var1, int16_t var2); /* Short shift left, 1 */
|
||||
int16_t shr(int16_t var1, int16_t var2); /* Short shift right, 1 */
|
||||
int32_t L_sub(int32_t L_var1, int32_t L_var2); /* Long sub, 2 */
|
||||
int32_t L_shl(int32_t L_var1, int16_t var2); /* Long shift left, 2 */
|
||||
int32_t L_shr(int32_t L_var1, int16_t var2); /* Long shift right, 2 */
|
||||
int16_t norm_s(int16_t var1); /* Short norm, 15 */
|
||||
int16_t div_s(int16_t var1, int16_t var2); /* Short division, 18 */
|
||||
int16_t norm_l(int32_t L_var1); /* Long norm, 30 */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: bitstream.c,v 1.2 2008/10/17 13:18:21 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: bitstream.h,v 1.2 2008/10/17 13:18:21 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -6,14 +6,12 @@
|
||||
* Adapted by Steve Underwood <steveu@coppice.org> from the reference
|
||||
* code supplied with ITU G.722.1, which is:
|
||||
*
|
||||
* © 2004 Polycom, Inc.
|
||||
* (C) 2004 Polycom, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: coef2sam.c,v 1.10 2008/10/02 11:43:54 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -29,18 +27,16 @@
|
||||
|
||||
#include "defs.h"
|
||||
#include "coef2sam.h"
|
||||
#include "utilities.h"
|
||||
|
||||
/*************************************************************************************
|
||||
/* Convert Reversed MLT (Modulated Lapped Transform) Coefficients to Samples
|
||||
|
||||
Purpose: Convert Reversed MLT (Modulated Lapped Transform) Coefficients to Samples
|
||||
|
||||
The "Reversed MLT" is an overlapped block transform which uses even symmetry
|
||||
on the left, odd symmetry on the right and a Type IV DCT as the block transform.
|
||||
It is thus similar to a MLT which uses odd symmetry on the left, even symmetry
|
||||
on the right and a Type IV DST as the block transform. In fact, it is equivalent
|
||||
to reversing the order of the samples, performing an MLT and then negating all
|
||||
the even-numbered coefficients.
|
||||
***************************************************************************/
|
||||
The "Reversed MLT" is an overlapped block transform which uses even symmetry
|
||||
on the left, odd symmetry on the right and a Type IV DCT as the block transform.
|
||||
It is thus similar to a MLT which uses odd symmetry on the left, even symmetry
|
||||
on the right and a Type IV DST as the block transform. In fact, it is equivalent
|
||||
to reversing the order of the samples, performing an MLT and then negating all
|
||||
the even-numbered coefficients. */
|
||||
|
||||
#if defined(G722_1_USE_FIXED_POINT)
|
||||
void rmlt_coefs_to_samples(int16_t coefs[],
|
||||
@@ -73,29 +69,23 @@ void rmlt_coefs_to_samples(int16_t coefs[],
|
||||
new_samples[i] = shl(new_samples[i], mag_shift);
|
||||
}
|
||||
|
||||
if (dct_length == DCT_LENGTH)
|
||||
win = rmlt_to_samples_window;
|
||||
else
|
||||
win = max_rmlt_to_samples_window;
|
||||
win = (dct_length == DCT_LENGTH) ? rmlt_to_samples_window : max_rmlt_to_samples_window;
|
||||
last = half_dct_length - 1;
|
||||
for (i = 0; i < half_dct_length; i++)
|
||||
{
|
||||
/* Get the first half of the windowed samples */
|
||||
sum = 0L;
|
||||
sum = L_mac(sum, win[i], new_samples[last - i]);
|
||||
sum = L_mult(win[i], new_samples[last - i]);
|
||||
sum = L_mac(sum, win[dct_length - i - 1], old_samples[i]);
|
||||
out_samples[i] = xround(L_shl(sum, 2));
|
||||
/* Get the second half of the windowed samples */
|
||||
sum = 0L;
|
||||
sum = L_mac(sum, win[half_dct_length + i], new_samples[i]);
|
||||
sum = L_mult(win[half_dct_length + i], new_samples[i]);
|
||||
sum = L_mac(sum, negate(win[last - i]), old_samples[last - i]);
|
||||
out_samples[half_dct_length + i] = xround(L_shl(sum, 2));
|
||||
}
|
||||
|
||||
/* Save the second half of the new samples for
|
||||
next time, when they will be the old samples. */
|
||||
for (i = 0; i < half_dct_length; i++)
|
||||
old_samples[i] = new_samples[half_dct_length + i];
|
||||
vec_copyi16(old_samples, &new_samples[half_dct_length], half_dct_length);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#else
|
||||
@@ -116,10 +106,7 @@ void rmlt_coefs_to_samples(float coefs[],
|
||||
/* Perform a Type IV (inverse) DCT on the coefficients */
|
||||
dct_type_iv(coefs, new_samples, dct_length);
|
||||
|
||||
if (dct_length == DCT_LENGTH)
|
||||
win = rmlt_to_samples_window;
|
||||
else
|
||||
win = max_rmlt_to_samples_window;
|
||||
win = (dct_length == DCT_LENGTH) ? rmlt_to_samples_window : max_rmlt_to_samples_window;
|
||||
last = half_dct_length - 1;
|
||||
for (i = 0; i < half_dct_length; i++)
|
||||
{
|
||||
@@ -135,8 +122,7 @@ void rmlt_coefs_to_samples(float coefs[],
|
||||
|
||||
/* Save the second half of the new samples for next time, when they will
|
||||
be the old samples. */
|
||||
for (i = 0; i < half_dct_length; i++)
|
||||
old_samples[i] = new_samples[half_dct_length + i];
|
||||
vec_copyf(old_samples, &new_samples[half_dct_length], half_dct_length);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user