diff --git a/build/Makefile.am b/build/Makefile.am
index 4b426ef6e3..1d57dad528 100644
--- a/build/Makefile.am
+++ b/build/Makefile.am
@@ -6,8 +6,13 @@ all:
@echo " + Install by running: +"
@echo " + +"
@echo " + $(MK) install +"
+ @echo " + +"
+ @echo " + While you're waiting, register for ClueCon! +"
+ @echo " + http://www.cluecon.com +"
+ @echo " + +"
@echo " +-----------------------------------------------+"
+
install:
@echo " +---------- FreeSWITCH install Complete ----------+"
@echo " + FreeSWITCH has been successfully installed. +"
diff --git a/build/modules.conf.in b/build/modules.conf.in
index 37244a188a..13e655672c 100644
--- a/build/modules.conf.in
+++ b/build/modules.conf.in
@@ -62,6 +62,7 @@ endpoints/mod_loopback
#endpoints/mod_skinny
#endpoints/mod_skypopen
#endpoints/mod_h323
+#endpoints/mod_khomp
#../../libs/openzap/mod_openzap
#../../libs/freetdm/mod_freetdm
#asr_tts/mod_unimrcp
@@ -105,5 +106,4 @@ say/mod_say_ru
#say/mod_say_th
## Experimental Modules (don't cry if they're broken)
-#endpoints/mod_khomp
#../../contrib/mod/xml_int/mod_xml_odbc
diff --git a/conf/autoload_configs/modules.conf.xml b/conf/autoload_configs/modules.conf.xml
index f5627fe965..118d7c4d81 100644
--- a/conf/autoload_configs/modules.conf.xml
+++ b/conf/autoload_configs/modules.conf.xml
@@ -38,6 +38,7 @@
+
diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c
index 91836b7aec..569e2cd169 100644
--- a/libs/esl/fs_cli.c
+++ b/libs/esl/fs_cli.c
@@ -1005,7 +1005,7 @@ int main(int argc, char *argv[])
int temp_log = -1;
int argv_error = 0;
int argv_exec = 0;
- char argv_command[256] = "";
+ char argv_command[1024] = "";
char argv_loglevel[128] = "";
int argv_quiet = 0;
int loops = 2, reconnect = 0;
diff --git a/libs/freetdm/cyginstall.sh b/libs/freetdm/cyginstall.sh
index 9d486b7dce..e2d5885c4e 100644
--- a/libs/freetdm/cyginstall.sh
+++ b/libs/freetdm/cyginstall.sh
@@ -5,8 +5,9 @@ fsdir=../..
set -x
cp Debug/mod/*.dll $fsdir/Debug/mod/
cp mod_freetdm/Debug/*.pdb $fsdir/Debug/mod/
-cp Debug/*.dll $fsdir/Debug/
-cp Debug/*.pdb $fsdir/Debug/
+cp Debug/freetdm.dll $fsdir/Debug/
+cp Debug/ftmod_*.dll $fsdir/Debug/mod/
+cp Debug/*.pdb $fsdir/Debug/mod/
#cp Debug/testsangomaboost.exe $fsdir/Debug/
echo "FRIENDLY REMINDER: RECOMPILE ftmod_wanpipe WHENEVER YOU INSTALL NEW DRIVERS"
set +x
diff --git a/libs/freetdm/freetdm.2008.sln b/libs/freetdm/freetdm.2008.sln
index f059d941d3..2e8c7c4adb 100644
--- a/libs/freetdm/freetdm.2008.sln
+++ b/libs/freetdm/freetdm.2008.sln
@@ -161,10 +161,8 @@ Global
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.Build.0 = Release|Win32
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|Win32
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.ActiveCfg = Debug|Win32
- {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.Build.0 = Debug|Win32
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|Win32
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|Win32.ActiveCfg = Release|Win32
- {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|Win32.Build.0 = Release|Win32
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
diff --git a/libs/freetdm/freetdm.2010.sln b/libs/freetdm/freetdm.2010.sln
index 1806e9ea23..f4bd907a6d 100644
--- a/libs/freetdm/freetdm.2010.sln
+++ b/libs/freetdm/freetdm.2010.sln
@@ -120,16 +120,14 @@ Global
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.Build.0 = Release|x64
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.ActiveCfg = Debug|Win32
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.Build.0 = Debug|Win32
- {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|Win32
+ {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|x64
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.ActiveCfg = Release|Win32
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.Build.0 = Release|Win32
- {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|Win32
+ {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|x64
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.ActiveCfg = Debug|Win32
- {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.Build.0 = Debug|Win32
- {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|Win32
+ {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|x64
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|Win32.ActiveCfg = Release|Win32
- {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|Win32.Build.0 = Release|Win32
- {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|x64.ActiveCfg = Release|Win32
+ {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|x64.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c
index a410e4eac6..b5c8b84c0c 100755
--- a/libs/freetdm/mod_freetdm/mod_freetdm.c
+++ b/libs/freetdm/mod_freetdm/mod_freetdm.c
@@ -149,6 +149,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
+static const char* channel_get_variable(switch_core_session_t *session, switch_event_t *var_event, const char *variable_name);
ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session_t **sp);
void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream);
void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream);
@@ -425,8 +426,11 @@ static switch_status_t channel_on_routing(switch_core_session_t *session)
tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel));
+ assert(tech_pvt->ftdmchan != NULL);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel));
+
+ ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROCEED);
return SWITCH_STATUS_SUCCESS;
}
@@ -837,9 +841,9 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
assert(tech_pvt != NULL);
if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
- switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
- return SWITCH_STATUS_FALSE;
- }
+ switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
+ return SWITCH_STATUS_FALSE;
+ }
if (ftdm_channel_call_check_hangup(tech_pvt->ftdmchan)) {
return SWITCH_STATUS_SUCCESS;
@@ -852,7 +856,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
switch (msg->message_id) {
case SWITCH_MESSAGE_INDICATE_RINGING:
{
- ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS);
+ ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_RINGING);
}
break;
case SWITCH_MESSAGE_INDICATE_PROGRESS:
@@ -884,9 +888,9 @@ static switch_status_t channel_receive_message_fxo(switch_core_session_t *sessio
assert(tech_pvt != NULL);
if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
- switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
- return SWITCH_STATUS_FALSE;
- }
+ switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
+ return SWITCH_STATUS_FALSE;
+ }
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
return SWITCH_STATUS_SUCCESS;
@@ -935,7 +939,7 @@ static switch_status_t channel_receive_message_fxs(switch_core_session_t *sessio
!switch_channel_test_flag(channel, CF_EARLY_MEDIA) &&
!switch_channel_test_flag(channel, CF_RING_READY)
) {
- ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_RING);
+ ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_RINGING);
switch_channel_mark_ring_ready(channel);
}
break;
@@ -1046,6 +1050,27 @@ switch_io_routines_t freetdm_io_routines = {
/*.receive_message*/ channel_receive_message
};
+static const char* channel_get_variable(switch_core_session_t *session, switch_event_t *var_event, const char *variable_name)
+{
+ const char *variable = NULL;
+
+ if (var_event) {
+ if ((variable = switch_event_get_header(var_event, variable_name))) {
+ return variable;
+ }
+ }
+ if (session) {
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ if ((variable = switch_channel_get_variable(channel, variable_name))) {
+ return variable;
+ }
+ }
+ if ((variable = switch_core_get_variable(variable_name))) {
+ return variable;
+ }
+ return NULL;
+}
+
/* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines
that allocate memory or you will have 1 channel with memory allocated from another channel's pool!
*/
@@ -1223,20 +1248,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
}
}
- if (session) {
- /* take out some other values from the session if they're present */
- switch_channel_t *channel = switch_core_session_get_channel(session);
- const char *freetdmvar;
- freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_capability");
- if (freetdmvar) {
- caller_data.bearer_capability = (uint8_t)atoi(freetdmvar);
- }
- freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_layer1");
- if (freetdmvar) {
- caller_data.bearer_layer1 = (uint8_t)atoi(freetdmvar);
- }
- }
-
if (switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN)) {
caller_data.screen = 1;
}
@@ -1245,29 +1256,37 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
caller_data.pres = 1;
}
- if (!zstr(dest)) {
- ftdm_set_string(caller_data.dnis.digits, dest);
+ if ((var = channel_get_variable(session, var_event, "freetdm_bearer_capability"))) {
+ caller_data.bearer_capability = (uint8_t)atoi(var);
}
- if ((var = switch_event_get_header(var_event, "freetdm_outbound_ton")) || (var = switch_core_get_variable("freetdm_outbound_ton"))) {
- if (!strcasecmp(var, "national")) {
- caller_data.dnis.type = FTDM_TON_NATIONAL;
- } else if (!strcasecmp(var, "international")) {
- caller_data.dnis.type = FTDM_TON_INTERNATIONAL;
- } else if (!strcasecmp(var, "local")) {
- caller_data.dnis.type = FTDM_TON_SUBSCRIBER_NUMBER;
- } else if (!strcasecmp(var, "unknown")) {
- caller_data.dnis.type = FTDM_TON_UNKNOWN;
- }
+ if ((var = channel_get_variable(session, var_event, "freetdm_bearer_layer1"))) {
+ caller_data.bearer_layer1 = (uint8_t)atoi(var);
+ }
+
+ if ((var = channel_get_variable(session, var_event, "freetdm_screening_ind"))) {
+ ftdm_set_screening_ind(var, &caller_data.screen);
+ }
+
+ if ((var = channel_get_variable(session, var_event, "freetdm_presentation_ind"))) {
+ ftdm_set_presentation_ind(var, &caller_data.pres);
+ }
+
+ if ((var = channel_get_variable(session, var_event, "freetdm_outbound_ton"))) {
+ ftdm_set_ton(var, &caller_data.dnis.type);
} else {
caller_data.dnis.type = outbound_profile->destination_number_ton;
}
- if ((var = switch_event_get_header(var_event, "freetdm_custom_call_data")) || (var = switch_core_get_variable("freetdm_custom_call_data"))) {
+ 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);
}
+ if (!zstr(dest)) {
+ ftdm_set_string(caller_data.dnis.digits, dest);
+ }
+
caller_data.dnis.plan = outbound_profile->destination_number_numplan;
/* blindly copy data from outbound_profile. They will be overwritten
@@ -1690,6 +1709,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
}
}
break;
+ case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
default:
{
@@ -1744,6 +1764,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
}
}
break;
+ case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
case FTDM_SIGEVENT_STOP:
{
private_t *tech_pvt = NULL;
@@ -1966,6 +1987,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
status = ftdm_channel_from_event(sigmsg, &session);
}
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:
@@ -2028,6 +2051,14 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
}
break;
+ case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
+ {
+ ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to: %s\n",
+ spanid, chanid, ftdm_signaling_status2str(sigstatus));
+ }
+ break;
+
default:
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled event %d from R2 for channel %d:%d\n",
@@ -2059,10 +2090,16 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
switch(sigmsg->event_id) {
case FTDM_SIGEVENT_START:
{
+ ftdm_channel_add_var(sigmsg->channel, "screening_ind", ftdm_screening2str(caller_data->screen));
+ ftdm_channel_add_var(sigmsg->channel, "presentation_ind", ftdm_presentation2str(caller_data->pres));
+
ftdm_enable_channel_dtmf(sigmsg->channel, NULL);
return ftdm_channel_from_event(sigmsg, &session);
}
break;
+
+ case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
+
case FTDM_SIGEVENT_STOP:
case FTDM_SIGEVENT_RESTART:
{
@@ -2118,7 +2155,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
spanid, chanid, (uuid) ? uuid : "N/A");
}
}
- break;
+ break;
case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
{
ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus;
@@ -2126,6 +2163,10 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
spanid, chanid, ftdm_signaling_status2str(sigstatus));
}
break;
+ case FTDM_SIGEVENT_PROCEED:
+ case FTDM_SIGEVENT_MSG:
+ /* FS does not have handlers for these messages, so ignore them for now */
+ break;
default:
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n",
diff --git a/libs/freetdm/msvc/testboost/testboost.2008.vcproj b/libs/freetdm/msvc/testboost/testboost.2008.vcproj
index afb44b6469..5707033f33 100644
--- a/libs/freetdm/msvc/testboost/testboost.2008.vcproj
+++ b/libs/freetdm/msvc/testboost/testboost.2008.vcproj
@@ -22,7 +22,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj b/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj
index b6c0518883..5994da6f1a 100644
--- a/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj
+++ b/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj
@@ -186,7 +186,7 @@
Level4
- true
+ false
ProgramDatabase
4100;%(DisableSpecificWarnings)
diff --git a/libs/freetdm/openzap.2005.sln b/libs/freetdm/openzap.2005.sln
deleted file mode 100644
index c9f666b381..0000000000
--- a/libs/freetdm/openzap.2005.sln
+++ /dev/null
@@ -1,82 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openzap", "msvc\openzap.2005.vcproj", "{93B8812C-3EC4-4F78-8970-FFBFC99E167D}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testanalog", "msvc\testanalog\testanalog.2005.vcproj", "{BB833648-BAFF-4BE2-94DB-F8BB043C588C}"
- ProjectSection(ProjectDependencies) = postProject
- {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testisdn", "msvc\testisdn\testisdn.2005.vcproj", "{6DA6FD42-641D-4147-92F5-3BC4AAA6589B}"
- ProjectSection(ProjectDependencies) = postProject
- {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_openzap", "mod_openzap\mod_openzap.2005.vcproj", "{FE3540C5-3303-46E0-A69E-D92F775687F1}"
- ProjectSection(ProjectDependencies) = postProject
- {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ozmod_analog", "src\ozmod\ozmod_analog\ozmod_analog.2005.vcproj", "{37C94798-6E33-4B4F-8EE0-C72A7DC91157}"
- ProjectSection(ProjectDependencies) = postProject
- {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ozmod_analog_em", "src\ozmod\ozmod_analog_em\ozmod_analog_em.2005.vcproj", "{C539D7C8-26A8-4A94-B938-77672165C130}"
- ProjectSection(ProjectDependencies) = postProject
- {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ozmod_isdn", "src\ozmod\ozmod_isdn\ozmod_isdn.2005.vcproj", "{729344A5-D5E9-434D-8EE8-AF8C6C795D15}"
- ProjectSection(ProjectDependencies) = postProject
- {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ozmod_wanpipe", "src\ozmod\ozmod_wanpipe\ozmod_wanpipe.2005.vcproj", "{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ozmod_pika", "src\ozmod\ozmod_pika\ozmod_pika.2005.vcproj", "{E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|Win32.ActiveCfg = Debug|Win32
- {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|Win32.Build.0 = Debug|Win32
- {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|Win32.ActiveCfg = Release|Win32
- {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|Win32.Build.0 = Release|Win32
- {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|Win32.ActiveCfg = Debug|Win32
- {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|Win32.Build.0 = Debug|Win32
- {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|Win32.ActiveCfg = Release|Win32
- {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|Win32.Build.0 = Release|Win32
- {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Debug|Win32.ActiveCfg = Debug|Win32
- {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Debug|Win32.Build.0 = Debug|Win32
- {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Release|Win32.ActiveCfg = Release|Win32
- {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Release|Win32.Build.0 = Release|Win32
- {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|Win32.ActiveCfg = Debug|Win32
- {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|Win32.Build.0 = Debug|Win32
- {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|Win32.ActiveCfg = Release|Win32
- {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|Win32.Build.0 = Release|Win32
- {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|Win32.ActiveCfg = Debug|Win32
- {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|Win32.Build.0 = Debug|Win32
- {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|Win32.ActiveCfg = Release|Win32
- {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|Win32.Build.0 = Release|Win32
- {C539D7C8-26A8-4A94-B938-77672165C130}.Debug|Win32.ActiveCfg = Debug|Win32
- {C539D7C8-26A8-4A94-B938-77672165C130}.Debug|Win32.Build.0 = Debug|Win32
- {C539D7C8-26A8-4A94-B938-77672165C130}.Release|Win32.ActiveCfg = Release|Win32
- {C539D7C8-26A8-4A94-B938-77672165C130}.Release|Win32.Build.0 = Release|Win32
- {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Debug|Win32.ActiveCfg = Debug|Win32
- {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Debug|Win32.Build.0 = Debug|Win32
- {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Release|Win32.ActiveCfg = Release|Win32
- {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Release|Win32.Build.0 = Release|Win32
- {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|Win32.ActiveCfg = Debug|Win32
- {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|Win32.ActiveCfg = Release|Win32
- {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Debug|Win32.ActiveCfg = Debug|Win32
- {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Release|Win32.ActiveCfg = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/libs/freetdm/src/ftdm_call_utils.c b/libs/freetdm/src/ftdm_call_utils.c
index d91b3bc9e2..69f2fb4fff 100644
--- a/libs/freetdm/src/ftdm_call_utils.c
+++ b/libs/freetdm/src/ftdm_call_utils.c
@@ -36,80 +36,101 @@
#include
-FT_DECLARE(ftdm_status_t) ftdm_span_set_npi(const char *npi_string, uint8_t *target)
+FT_DECLARE(ftdm_status_t) ftdm_set_npi(const char *string, uint8_t *target)
{
- if (!strcasecmp(npi_string, "isdn") || !strcasecmp(npi_string, "e164")) {
- *target = FTDM_NPI_ISDN;
- } else if (!strcasecmp(npi_string, "data")) {
- *target = FTDM_NPI_DATA;
- } else if (!strcasecmp(npi_string, "telex")) {
- *target = FTDM_NPI_TELEX;
- } else if (!strcasecmp(npi_string, "national")) {
- *target = FTDM_NPI_NATIONAL;
- } else if (!strcasecmp(npi_string, "private")) {
- *target = FTDM_NPI_PRIVATE;
- } else if (!strcasecmp(npi_string, "reserved")) {
- *target = FTDM_NPI_RESERVED;
- } else if (!strcasecmp(npi_string, "unknown")) {
- *target = FTDM_NPI_UNKNOWN;
- } else {
- ftdm_log(FTDM_LOG_WARNING, "Invalid NPI value (%s)\n", npi_string);
- *target = FTDM_NPI_UNKNOWN;
- return FTDM_FAIL;
+ uint8_t val;
+ ftdm_status_t status = FTDM_SUCCESS;
+
+ val = ftdm_str2ftdm_npi(string);
+ if (val == FTDM_NPI_INVALID) {
+ ftdm_log(FTDM_LOG_WARNING, "Invalid NPI string (%s)\n", string);
+ status = FTDM_FAIL;
+ val = FTDM_NPI_UNKNOWN;
}
- return FTDM_SUCCESS;
+ *target = val;
+ return status;
}
-FT_DECLARE(ftdm_status_t) ftdm_span_set_ton(const char *ton_string, uint8_t *target)
+FT_DECLARE(ftdm_status_t) ftdm_set_ton(const char *string, uint8_t *target)
{
- if (!strcasecmp(ton_string, "national")) {
- *target = FTDM_TON_NATIONAL;
- } else if (!strcasecmp(ton_string, "international")) {
- *target = FTDM_TON_INTERNATIONAL;
- } else if (!strcasecmp(ton_string, "local")) {
- *target = FTDM_TON_SUBSCRIBER_NUMBER;
- } else if (!strcasecmp(ton_string, "unknown")) {
- *target = FTDM_TON_UNKNOWN;
- } else {
- ftdm_log(FTDM_LOG_WARNING, "Invalid TON value (%s)\n", ton_string);
- *target = FTDM_TON_UNKNOWN;
- return FTDM_FAIL;
+ uint8_t val;
+ ftdm_status_t status = FTDM_SUCCESS;
+
+ val = ftdm_str2ftdm_ton(string);
+ if (val == FTDM_TON_INVALID) {
+ ftdm_log(FTDM_LOG_WARNING, "Invalid TON string (%s)\n", string);
+ status = FTDM_FAIL;
+ val = FTDM_TON_UNKNOWN;
}
- return FTDM_SUCCESS;
+ *target = val;
+ return status;
}
-FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_capability(const char *bc_string, ftdm_bearer_cap_t *target)
+FT_DECLARE(ftdm_status_t) ftdm_set_bearer_capability(const char *string, uint8_t *target)
{
- if (!strcasecmp(bc_string, "speech")) {
- *target = FTDM_BEARER_CAP_SPEECH;
- } else if (!strcasecmp(bc_string, "unrestricted-digital")) {
- *target = FTDM_BEARER_CAP_64K_UNRESTRICTED;
- } else if (!strcasecmp(bc_string, "3.1Khz")) {
- *target = FTDM_BEARER_CAP_3_1KHZ_AUDIO;
- } else {
- ftdm_log(FTDM_LOG_WARNING, "Unsupported Bearer Capability value (%s)\n", bc_string);
- return FTDM_FAIL;
+ uint8_t val;
+ ftdm_status_t status = FTDM_SUCCESS;
+
+ val = ftdm_str2ftdm_bearer_cap(string);
+ if (val == FTDM_NPI_INVALID) {
+ ftdm_log(FTDM_LOG_WARNING, "Invalid Bearer-Capability string (%s)\n", string);
+ status = FTDM_FAIL;
+ val = FTDM_BEARER_CAP_SPEECH;
}
- return FTDM_SUCCESS;
+
+ *target = val;
+ return status;
}
-FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_layer1(const char *bc_string, ftdm_user_layer1_prot_t *target)
+FT_DECLARE(ftdm_status_t) ftdm_set_bearer_layer1(const char *string, uint8_t *target)
{
- if (!strcasecmp(bc_string, "v110")) {
- *target = FTDM_USER_LAYER1_PROT_V110;
- } else if (!strcasecmp(bc_string, "ulaw")) {
- *target = FTDM_USER_LAYER1_PROT_ULAW;
- } else if (!strcasecmp(bc_string, "alaw")) {
- *target =FTDM_USER_LAYER1_PROT_ALAW ;
- } else {
- ftdm_log(FTDM_LOG_WARNING, "Unsupported Bearer Layer1 Prot value (%s)\n", bc_string);
- return FTDM_FAIL;
+ uint8_t val;
+ ftdm_status_t status = FTDM_SUCCESS;
+
+ val = ftdm_str2ftdm_usr_layer1_prot(string);
+ if (val == FTDM_USER_LAYER1_PROT_INVALID) {
+ ftdm_log(FTDM_LOG_WARNING, "Invalid Bearer Layer 1 Protocol string (%s)\n", string);
+ status = FTDM_FAIL;
+ val = FTDM_USER_LAYER1_PROT_ULAW;
}
- return FTDM_SUCCESS;
+
+ *target = val;
+ return status;
}
+FT_DECLARE(ftdm_status_t) ftdm_set_screening_ind(const char *string, uint8_t *target)
+{
+ uint8_t val;
+ ftdm_status_t status = FTDM_SUCCESS;
-FT_DECLARE(ftdm_status_t) ftdm_is_number(char *number)
+ val = ftdm_str2ftdm_screening(string);
+ if (val == FTDM_SCREENING_INVALID) {
+ ftdm_log(FTDM_LOG_WARNING, "Invalid screening indicator string (%s)\n", string);
+ status = FTDM_FAIL;
+ val = FTDM_SCREENING_NOT_SCREENED;
+ }
+
+ *target = val;
+ return status;
+}
+
+FT_DECLARE(ftdm_status_t) ftdm_set_presentation_ind(const char *string, uint8_t *target)
+{
+ uint8_t val;
+ ftdm_status_t status = FTDM_SUCCESS;
+
+ val = ftdm_str2ftdm_presentation(string);
+ if (val == FTDM_PRES_INVALID) {
+ ftdm_log(FTDM_LOG_WARNING, "Invalid presentation string (%s)\n", string);
+ status = FTDM_FAIL;
+ val = FTDM_PRES_ALLOWED;
+ }
+
+ *target = val;
+ return status;
+}
+
+FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number)
{
if (!number) {
return FTDM_FAIL;
diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c
index bcceba58ca..3dd1aa9ece 100644
--- a/libs/freetdm/src/ftdm_io.c
+++ b/libs/freetdm/src/ftdm_io.c
@@ -38,8 +38,6 @@
*/
#define _GNU_SOURCE
-#ifndef WIN32
-#endif
#include "private/ftdm_core.h"
#include
#ifdef WIN32
@@ -56,6 +54,9 @@
#define FTDM_READ_TRACE_INDEX 0
#define FTDM_WRITE_TRACE_INDEX 1
+ftdm_time_t time_last_throttle_log = 0;
+ftdm_time_t time_current_throttle_log = 0;
+
static int time_is_init = 0;
static void time_init(void)
@@ -147,6 +148,24 @@ FTDM_STR2ENUM(ftdm_str2ftdm_chan_type, ftdm_chan_type2str, ftdm_chan_type_t, CHA
FTDM_ENUM_NAMES(SIGNALING_STATUS_NAMES, SIGSTATUS_STRINGS)
FTDM_STR2ENUM(ftdm_str2ftdm_signaling_status, ftdm_signaling_status2str, ftdm_signaling_status_t, SIGNALING_STATUS_NAMES, FTDM_SIG_STATE_INVALID)
+FTDM_ENUM_NAMES(TON_NAMES, TON_STRINGS)
+FTDM_STR2ENUM(ftdm_str2ftdm_ton, ftdm_ton2str, ftdm_ton_t, TON_NAMES, FTDM_TON_INVALID)
+
+FTDM_ENUM_NAMES(NPI_NAMES, NPI_STRINGS)
+FTDM_STR2ENUM(ftdm_str2ftdm_npi, ftdm_npi2str, ftdm_npi_t, NPI_NAMES, FTDM_NPI_INVALID)
+
+FTDM_ENUM_NAMES(PRESENTATION_NAMES, PRESENTATION_STRINGS)
+FTDM_STR2ENUM(ftdm_str2ftdm_presentation, ftdm_presentation2str, ftdm_presentation_t, PRESENTATION_NAMES, FTDM_PRES_INVALID)
+
+FTDM_ENUM_NAMES(SCREENING_NAMES, SCREENING_STRINGS)
+FTDM_STR2ENUM(ftdm_str2ftdm_screening, ftdm_screening2str, ftdm_screening_t, SCREENING_NAMES, FTDM_SCREENING_INVALID)
+
+FTDM_ENUM_NAMES(BEARER_CAP_NAMES, BEARER_CAP_STRINGS)
+FTDM_STR2ENUM(ftdm_str2ftdm_bearer_cap, ftdm_bearer_cap2str, ftdm_bearer_cap_t, BEARER_CAP_NAMES, FTDM_BEARER_CAP_INVALID)
+
+FTDM_ENUM_NAMES(USER_LAYER1_PROT_NAMES, USER_LAYER1_PROT_STRINGS)
+FTDM_STR2ENUM(ftdm_str2ftdm_usr_layer1_prot, ftdm_user_layer1_prot2str, ftdm_user_layer1_prot_t, USER_LAYER1_PROT_NAMES, FTDM_USER_LAYER1_PROT_INVALID)
+
static ftdm_status_t ftdm_group_add_channels(ftdm_span_t* span, int currindex, const char* name);
static const char *cut_path(const char *in)
@@ -1745,16 +1764,26 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan)
ftdm_mutex_lock(ftdmchan->mutex);
- if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED)) {
- snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "Channel is suspended\n");
- ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Cannot open channel when is suspended\n");
- goto done;
- }
-
- if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM) && !ftdm_test_flag(ftdmchan->span, FTDM_SPAN_PWR_SAVING)) {
- snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "Channel is alarmed\n");
- ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Cannot open channel when is alarmed\n");
- goto done;
+ if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
+ if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED)) {
+ snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "Channel is suspended\n");
+ ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Cannot open channel when is suspended\n");
+ goto done;
+ }
+
+ if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM) && !ftdm_test_flag(ftdmchan->span, FTDM_SPAN_PWR_SAVING)) {
+ snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "Channel is alarmed\n");
+ ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Cannot open channel when is alarmed\n");
+ goto done;
+ }
+
+ if (globals.cpu_monitor.alarm &&
+ globals.cpu_monitor.alarm_action_flags & FTDM_CPU_ALARM_ACTION_REJECT) {
+ snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "CPU usage alarm is on - refusing to open channel\n");
+ ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "CPU usage alarm is on - refusing to open channel\n");
+ ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_SWITCH_CONGESTION;
+ goto done;
+ }
}
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_READY)) {
@@ -1763,15 +1792,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan)
goto done;
}
- if (globals.cpu_monitor.alarm &&
- globals.cpu_monitor.alarm_action_flags & FTDM_CPU_ALARM_ACTION_REJECT) {
- snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "CPU usage alarm is on - refusing to open channel\n");
- ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "CPU usage alarm is on - refusing to open channel\n");
- ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_SWITCH_CONGESTION;
- goto done;
- }
-
-
status = ftdmchan->fio->open(ftdmchan);
if (status == FTDM_SUCCESS) {
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OPEN | FTDM_CHANNEL_INUSE);
@@ -2030,6 +2050,10 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char
goto done;
}
+#ifndef FREETDM_SKIP_SIG_STATES
+ /* We will fail RFC's if we not skip states, but some modules apart from ftmod_sangoma_isdn
+ * expect the call to always to go PROGRESS and PROGRESS MEDIA state before going to UP, so
+ * remove this only in netborder branch for now while we update the sig modules */
if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
@@ -2050,7 +2074,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to UP\n");
goto done;
}
-
+#endif
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 1);
done:
@@ -2199,14 +2223,19 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
switch (indication) {
/* FIXME: ring and busy cannot be used with all signaling stacks
* (particularly isdn stacks I think, we should emulate or just move to hangup with busy cause) */
- case FTDM_CHANNEL_INDICATE_RING:
- ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RING, 1);
+ case FTDM_CHANNEL_INDICATE_RINGING:
+ ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RINGING, 1);
break;
-
case FTDM_CHANNEL_INDICATE_BUSY:
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_BUSY, 1);
break;
-
+ case FTDM_CHANNEL_INDICATE_PROCEED:
+ if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_PROCEED_STATE)) {
+ if (ftdmchan->state == FTDM_CHANNEL_STATE_RING) {
+ ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROCEED, 1);
+ }
+ }
+ break;
case FTDM_CHANNEL_INDICATE_PROGRESS:
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
@@ -2214,7 +2243,6 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
}
break;
-
case FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA:
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
@@ -2233,7 +2261,6 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1);
}
break;
-
default:
ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "Do not know how to indicate %d\n", indication);
status = FTDM_FAIL;
@@ -2386,6 +2413,16 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
ftdm_log(FTDM_LOG_DEBUG, "channel done %u:%u\n", ftdmchan->span_id, ftdmchan->chan_id);
+ if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
+ ftdm_sigmsg_t sigmsg;
+ memset(&sigmsg, 0, sizeof(sigmsg));
+ sigmsg.span_id = ftdmchan->span_id;
+ sigmsg.chan_id = ftdmchan->chan_id;
+ sigmsg.channel = ftdmchan;
+ sigmsg.event_id = FTDM_SIGEVENT_RELEASED;
+ ftdm_span_send_signal(ftdmchan->span, &sigmsg);
+ }
+
ftdm_mutex_unlock(ftdmchan->mutex);
return FTDM_SUCCESS;
@@ -2810,21 +2847,17 @@ done:
FT_DECLARE(ftdm_status_t) ftdm_channel_wait(ftdm_channel_t *ftdmchan, ftdm_wait_flag_t *flags, int32_t to)
{
- assert(ftdmchan != NULL);
- assert(ftdmchan->fio != NULL);
+ ftdm_status_t status = FTDM_FAIL;
+ ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel\n");
+ ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "Null io interface\n");
+ ftdm_assert_return(ftdmchan->fio->wait != NULL, FTDM_NOTIMPL, "wait method not implemented\n");
- if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
- snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "channel not open");
- return FTDM_FAIL;
- }
-
- if (!ftdmchan->fio->wait) {
- snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "method not implemented");
- return FTDM_FAIL;
+ status = ftdmchan->fio->wait(ftdmchan, flags, to);
+ if (status == FTDM_TIMEOUT) {
+ /* make sure the flags are cleared on timeout */
+ *flags = 0;
}
-
- return ftdmchan->fio->wait(ftdmchan, flags, to);
-
+ return status;
}
/*******************************/
@@ -4809,7 +4842,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
if (sigmsg->channel) {
ftdm_mutex_lock(sigmsg->channel->mutex);
}
-
+
/* some core things to do on special events */
switch (sigmsg->event_id) {
diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2008.vcproj
index 448f03a545..09349fc05f 100644
--- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2008.vcproj
+++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2008.vcproj
@@ -1,353 +1,353 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2010.vcxproj b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2010.vcxproj
index 81cb93fa44..301d821af6 100644
--- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2010.vcxproj
+++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2010.vcxproj
@@ -168,7 +168,7 @@
Level4
- true
+ false
ProgramDatabase
4100;%(DisableSpecificWarnings)
diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c
index fc9bea6ef0..99d256655a 100644
--- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c
+++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c
@@ -438,7 +438,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
{
if (state_counter > 5000 || !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT)) {
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_CALLERID_DETECT, NULL);
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
}
}
break;
@@ -492,8 +492,8 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
}
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) &&
- (ftdmchan->last_state == FTDM_CHANNEL_STATE_RING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE
- || ftdmchan->last_state >= FTDM_CHANNEL_STATE_IDLE)) {
+ (ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE
+ || ftdmchan->last_state >= FTDM_CHANNEL_STATE_RING)) {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
} else {
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING;
@@ -535,7 +535,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
}
}
case FTDM_CHANNEL_STATE_UP:
- case FTDM_CHANNEL_STATE_IDLE:
+ case FTDM_CHANNEL_STATE_RING:
{
ftdm_sleep(interval);
continue;
@@ -599,7 +599,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
ftdm_channel_use(ftdmchan);
}
break;
- case FTDM_CHANNEL_STATE_IDLE:
+ case FTDM_CHANNEL_STATE_RING:
{
ftdm_channel_use(ftdmchan);
sig.event_id = FTDM_SIGEVENT_START;
@@ -669,7 +669,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
continue;
}
break;
- case FTDM_CHANNEL_STATE_RING:
+ case FTDM_CHANNEL_STATE_RINGING:
{
ftdm_buffer_zero(dt_buffer);
teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]);
@@ -732,7 +732,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) >= analog_data->max_dialstr))) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Number obtained [%s]\n", dtmf);
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
last_digit = 0;
collecting = 0;
}
@@ -890,7 +890,7 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
if (ftdm_test_flag(analog_data, FTDM_ANALOG_CALLERID)) {
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID);
} else {
- ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_IDLE);
+ ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_RING);
}
event->channel->ring_count = 1;
ftdm_mutex_unlock(event->channel->mutex);
diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ozmod_analog.2005.vcproj b/libs/freetdm/src/ftmod/ftmod_analog/ozmod_analog.2005.vcproj
deleted file mode 100644
index 7a1cf53b20..0000000000
--- a/libs/freetdm/src/ftmod/ftmod_analog/ozmod_analog.2005.vcproj
+++ /dev/null
@@ -1,202 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2008.vcproj
index 8ad183797a..837ba7de0f 100644
--- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2008.vcproj
+++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2008.vcproj
@@ -1,353 +1,353 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2010.vcxproj b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2010.vcxproj
index 44792df89f..3643e271ef 100644
--- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2010.vcxproj
+++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2010.vcxproj
@@ -168,7 +168,7 @@
Level4
- true
+ false
ProgramDatabase
4100;%(DisableSpecificWarnings)
diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ozmod_analog_em.2005.vcproj b/libs/freetdm/src/ftmod/ftmod_analog_em/ozmod_analog_em.2005.vcproj
deleted file mode 100644
index 9ecbadc232..0000000000
--- a/libs/freetdm/src/ftmod/ftmod_analog_em/ozmod_analog_em.2005.vcproj
+++ /dev/null
@@ -1,202 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c
index c8e865214c..68f0e9e5a4 100644
--- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c
+++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c
@@ -462,7 +462,7 @@ static ftdm_state_map_t isdn_state_map = {
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_RING, FTDM_END},
- {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}
+ {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}
},
{
ZSD_INBOUND,
@@ -479,7 +479,7 @@ static ftdm_state_map_t isdn_state_map = {
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
- {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
+ {FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_UP, FTDM_END},
},
@@ -537,6 +537,8 @@ static __inline__ void state_advance(ftdm_channel_t *chan)
break;
case FTDM_CHANNEL_STATE_PROGRESS:
+ /* RINGING is an alias for PROGRESS state in inbound calls ATM */
+ case FTDM_CHANNEL_STATE_RINGING:
{
if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) {
sig.event_id = FTDM_SIGEVENT_PROGRESS;
diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2008.vcproj
index 9ea351ba6a..8942a8f5b6 100644
--- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2008.vcproj
+++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2008.vcproj
@@ -60,9 +60,9 @@
/>
Debug
Win32
+
+ Debug
+ x64
+
Release
Win32
+
+ Release
+ x64
+
ftmod_r2
@@ -19,33 +27,53 @@
DynamicLibrary
+
+ DynamicLibrary
+
DynamicLibrary
+
+ DynamicLibrary
+
+
+
+
+
+
+
<_ProjectFileVersion>10.0.30319.1
- $(SolutionDir)$(Configuration)\
- $(Configuration)\
true
- $(SolutionDir)$(Configuration)\
- $(Configuration)\
+ true
true
+ true
AllRules.ruleset
+ AllRules.ruleset
+
+
AllRules.ruleset
+ AllRules.ruleset
+
+
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ $(SolutionDir)$(Platform)\$(Configuration)\
@@ -68,6 +96,25 @@
MachineX86
+
+
+ Disabled
+ ..\..\include;c:\Program Files\openr2\include\openr2;C:\Program Files\openr2\include;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_R2_EXPORTS;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+ ProgramDatabase
+
+
+ freetdm.lib;openr2.lib;%(AdditionalDependencies)
+ C:\Program Files\openr2\lib;$(OutDir);%(AdditionalLibraryDirectories)
+ true
+ Windows
+
+
..\..\include;C:\Program Files\openr2\include;%(AdditionalIncludeDirectories)
@@ -86,6 +133,23 @@
MachineX86
+
+
+ ..\..\include;C:\Program Files\openr2\include;%(AdditionalIncludeDirectories)
+ WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_R2_EXPORTS;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+
+
+ Level3
+ ProgramDatabase
+
+
+ true
+ Windows
+ true
+ true
+
+
diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c
index d5344814f0..30de78857a 100644
--- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c
+++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c
@@ -220,6 +220,23 @@ static char *strsep(char **stringp, const char *delim)
}
#endif /* WIN32 */
+static void ftdm_r2_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status)
+{
+ ftdm_sigmsg_t sig;
+ ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Signalling link status changed to %s\n", ftdm_signaling_status2str(status));
+
+ memset(&sig, 0, sizeof(sig));
+ sig.chan_id = ftdmchan->chan_id;
+ sig.span_id = ftdmchan->span_id;
+ sig.channel = ftdmchan;
+ sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
+ sig.sigstatus = status;
+ if (ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS) {
+ ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to change channel status to %s\n", ftdm_signaling_status2str(status));
+ }
+ return;
+}
+
static ftdm_call_cause_t ftdm_r2_cause_to_ftdm_cause(ftdm_channel_t *fchan, openr2_call_disconnect_cause_t cause)
{
switch (cause) {
@@ -593,17 +610,14 @@ static void ftdm_r2_on_line_blocked(openr2_chan_t *r2chan)
{
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Far end blocked in state %s\n", ftdm_channel_state2str(ftdmchan->state));
- ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED);
+ ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_SUSPENDED);
}
static void ftdm_r2_on_line_idle(openr2_chan_t *r2chan)
{
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Far end unblocked in state %s\n", ftdm_channel_state2str(ftdmchan->state));
- ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED);
-
- /* XXX when should we set/unset this flag? XXX */
- ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SIG_UP);
+ ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP);
}
static void ftdm_r2_write_log(openr2_log_level_t level, const char *file, const char *function, int line, const char *message)
@@ -1130,6 +1144,9 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_r2_configure_span)
span->signal_data = r2data;
span->outgoing_call = r2_outgoing_call;
+ /* use signals queue */
+ ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE);
+
return FTDM_SUCCESS;
fail:
@@ -1439,6 +1456,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
} else if (status != FTDM_TIMEOUT) {
ftdm_log(FTDM_LOG_ERROR, "ftdm_span_poll_event returned %d.\n", status);
}
+ ftdm_span_trigger_signals(span);
ftdm_sleep(20);
}
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h
index 5a3ca76c56..6fbf272d07 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h
@@ -58,7 +58,7 @@ typedef struct ftdm_sangoma_boost_trunkgroup {
ftdm_size_t size; /* Number of b-channels in group */
unsigned int last_used_index; /* index of last b-channel used */
ftdm_channel_t* ftdmchans[MAX_CHANS_PER_TRUNKGROUP];
- //DAVIDY need to merge congestion timeouts to this struct
+ //TODO need to merge congestion timeouts to this struct
} ftdm_sangoma_boost_trunkgroup_t;
#endif
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2008.vcproj
index e7fc1d6549..73e421818f 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2008.vcproj
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2008.vcproj
@@ -95,83 +95,6 @@
Name="VCPostBuildEventTool"
/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj
index 1dd09211e2..78689c36db 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.2010.vcxproj
@@ -172,7 +172,7 @@
Level4
- true
+ false
ProgramDatabase
4100;%(DisableSpecificWarnings)
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c
index a975204b62..50a01cc0ec 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c
@@ -55,7 +55,7 @@ ftdm_mutex_t *g_boost_modules_mutex = NULL;
ftdm_hash_t *g_boost_modules_hash = NULL;
#define MAX_TRUNK_GROUPS 64
-//DAVIDY need to merge congestion_timeouts with ftdm_sangoma_boost_trunkgroups
+//TODO need to merge congestion_timeouts with ftdm_sangoma_boost_trunkgroups
static time_t congestion_timeouts[MAX_TRUNK_GROUPS];
static ftdm_sangoma_boost_trunkgroup_t *g_trunkgroups[MAX_TRUNK_GROUPS];
@@ -1557,11 +1557,11 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
ftdm_set_string(event.calling_name, ftdmchan->caller_data.cid_name);
ftdm_set_string(event.rdnis.digits, ftdmchan->caller_data.rdnis.digits);
if (strlen(ftdmchan->caller_data.rdnis.digits)) {
- event.rdnis.digits_count = (uint8_t)strlen(ftdmchan->caller_data.rdnis.digits)+1;
- event.rdnis.ton = ftdmchan->caller_data.rdnis.type;
- event.rdnis.npi = ftdmchan->caller_data.rdnis.plan;
+ event.rdnis.digits_count = (uint8_t)strlen(ftdmchan->caller_data.rdnis.digits)+1;
+ event.rdnis.ton = ftdmchan->caller_data.rdnis.type;
+ event.rdnis.npi = ftdmchan->caller_data.rdnis.plan;
}
-
+
event.calling.screening_ind = ftdmchan->caller_data.screen;
event.calling.presentation_ind = ftdmchan->caller_data.pres;
@@ -2582,17 +2582,17 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_boost_configure_span)
} else if (!strcasecmp(var, "remote_port")) {
remote_port = atoi(val);
} else if (!strcasecmp(var, "outbound-called-ton")) {
- ftdm_span_set_ton(val, &span->default_caller_data.dnis.type);
+ ftdm_set_ton(val, &span->default_caller_data.dnis.type);
} else if (!strcasecmp(var, "outbound-called-npi")) {
- ftdm_span_set_npi(val, &span->default_caller_data.dnis.plan);
+ ftdm_set_npi(val, &span->default_caller_data.dnis.plan);
} else if (!strcasecmp(var, "outbound-calling-ton")) {
- ftdm_span_set_ton(val, &span->default_caller_data.cid_num.type);
+ ftdm_set_ton(val, &span->default_caller_data.cid_num.type);
} else if (!strcasecmp(var, "outbound-calling-npi")) {
- ftdm_span_set_npi(val, &span->default_caller_data.cid_num.plan);
+ ftdm_set_npi(val, &span->default_caller_data.cid_num.plan);
} else if (!strcasecmp(var, "outbound-rdnis-ton")) {
- ftdm_span_set_ton(val, &span->default_caller_data.rdnis.type);
+ ftdm_set_ton(val, &span->default_caller_data.rdnis.type);
} else if (!strcasecmp(var, "outbound-rdnis-npi")) {
- ftdm_span_set_npi(val, &span->default_caller_data.rdnis.plan);
+ ftdm_set_npi(val, &span->default_caller_data.rdnis.plan);
} else if (!sigmod) {
snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var);
FAIL_CONFIG_RETURN(FTDM_FAIL);
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj
index b4d234cc7d..b0a51786f5 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj
@@ -5,10 +5,18 @@
Debug
Win32
+
+ Debug
+ x64
+
Release
Win32
+
+ Release
+ x64
+
ftmod_sangoma_isdn
@@ -21,33 +29,58 @@
DynamicLibrary
true
+
+ DynamicLibrary
+ true
+
DynamicLibrary
+
+ DynamicLibrary
+
+
+
+
+
+
+
<_ProjectFileVersion>10.0.30319.1
- $(SolutionDir)$(Configuration)\
- $(Configuration)\
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
true
- $(SolutionDir)$(Configuration)\
- $(Configuration)\
+ true
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ $(Configuration)\
true
+ true
AllRules.ruleset
+ AllRules.ruleset
+
+
AllRules.ruleset
+ AllRules.ruleset
+
+
@@ -74,6 +107,29 @@
MachineX86
+
+
+ Disabled
+ C:\Program Files\libsng_isdn\include;C:\Program Files\libsng_isdn\include\sng_isdn;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+
+
+ EnableFastChecks
+
+
+ Level3
+ ProgramDatabase
+
+
+ freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies)
+ $(OutDir);C:\Program Files\libsng_isdn\lib;C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories)
+ true
+ Console
+ false
+
+
+
+
WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
@@ -93,6 +149,23 @@
MachineX86
+
+
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+ ProgramDatabase
+
+
+ true
+ Windows
+ true
+ true
+
+
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
index 583d5c1729..03b5a5fb1d 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
@@ -40,22 +40,24 @@
#include
#endif
-static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj);
+static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj);
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 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);
-static ftdm_io_interface_t g_sngisdn_io_interface;
-static sng_isdn_event_interface_t g_sngisdn_event_interface;
+static ftdm_io_interface_t g_sngisdn_io_interface;
+static sng_isdn_event_interface_t g_sngisdn_event_interface;
-ftdm_sngisdn_data_t g_sngisdn_data;
+ftdm_sngisdn_data_t g_sngisdn_data;
ftdm_state_map_t sangoma_isdn_state_map = {
{
@@ -113,7 +115,20 @@ ftdm_state_map_t sangoma_isdn_state_map = {
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_RING, FTDM_END},
- {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END}
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END}
+ },
+ {
+ ZSD_INBOUND,
+ ZSM_UNACCEPTABLE,
+ {FTDM_CHANNEL_STATE_PROCEED, FTDM_END},
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
+ FTDM_CHANNEL_STATE_UP, FTDM_END}
+ },
+ {
+ ZSD_INBOUND,
+ ZSM_UNACCEPTABLE,
+ {FTDM_CHANNEL_STATE_RINGING, FTDM_END},
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
},
{
ZSD_INBOUND,
@@ -187,9 +202,17 @@ ftdm_state_map_t sangoma_isdn_state_map = {
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_DIALING, FTDM_END},
- {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS,
- FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
+ FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP,
+ FTDM_CHANNEL_STATE_DOWN, FTDM_END}
},
+ {
+ ZSD_OUTBOUND,
+ ZSM_UNACCEPTABLE,
+ {FTDM_CHANNEL_STATE_PROCEED, FTDM_END},
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
+ FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
+ },
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
@@ -236,39 +259,51 @@ static __inline__ void ftdm_sangoma_isdn_advance_chan_states(ftdm_channel_t *ftd
}
}
+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;
+ sngisdn_snd_event(signal_data->dchan, event);
+
+ switch (event) {
+ /* Check if the span woke up from power-saving mode */
+ case FTDM_OOB_ALARM_CLEAR:
+ if (FTDM_SPAN_IS_BRI(span)) {
+ ftdm_channel_t *ftdmchan;
+ sngisdn_chan_data_t *sngisdn_info;
+ ftdm_iterator_t *chaniter = NULL;
+ ftdm_iterator_t *curr = NULL;
+
+ chaniter = ftdm_span_get_chan_iterator(span, NULL);
+ for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
+ ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
+ sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data;
+
+ if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) {
+ ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING);
+
+ ftdm_sched_timer(signal_data->sched, "delayed_setup", 1000, sngisdn_delayed_setup, (void*) ftdmchan->call_data, NULL);
+ }
+ }
+ ftdm_iterator_free(chaniter);
+ }
+ break;
+ default:
+ /* Ignore other events for now */
+ break;
+ }
+}
+
static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span)
{
- ftdm_status_t ret_status;
- ftdm_channel_t *ftdmchan;
- ftdm_iterator_t *chaniter = NULL;
- ftdm_iterator_t *curr = NULL;
-
+ ftdm_status_t ret_status;
+
ret_status = ftdm_span_poll_event(span, 0, NULL);
switch(ret_status) {
case FTDM_SUCCESS:
{
ftdm_event_t *event;
while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) {
-
- if (FTDM_SPAN_IS_BRI(span)) {
- switch (event->enum_id) {
- /* Check if the span woke up from power-saving mode */
- case FTDM_OOB_ALARM_CLEAR:
- {
- chaniter = ftdm_span_get_chan_iterator(span, NULL);
- for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
- ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
- sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
-
- if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) {
- ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING);
- sngisdn_snd_setup((ftdm_channel_t*)ftdmchan);
- }
- }
- ftdm_iterator_free(chaniter);
- }
- }
- }
+ ftdm_sangoma_isdn_process_phy_events(span, event->enum_id);
}
}
break;
@@ -280,9 +315,83 @@ static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span)
}
}
+static void ftdm_sangoma_isdn_dchan_set_queue_size(ftdm_channel_t *dchan)
+{
+ ftdm_status_t ret_status;
+ uint32_t queue_size;
+
+ queue_size = SNGISDN_DCHAN_QUEUE_LEN;
+ ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_RX_QUEUE_SIZE, &queue_size);
+ ftdm_assert(ret_status == FTDM_SUCCESS, "Failed to set Rx Queue size");
+
+ queue_size = SNGISDN_DCHAN_QUEUE_LEN;
+ ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &queue_size);
+ ftdm_assert(ret_status == FTDM_SUCCESS, "Failed to set Tx Queue size");
+
+ RETVOID;
+}
+
+static void ftdm_sangoma_isdn_wakeup_phy(ftdm_channel_t *dchan)
+{
+ ftdm_status_t ret_status;
+ ftdm_channel_hw_link_status_t status = FTDM_HW_LINK_CONNECTED;
+ ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_LINK_STATUS, &status);
+ if (ret_status != FTDM_SUCCESS) {
+ ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Failed to wake-up link\n");
+ }
+ return;
+}
+
+static void *ftdm_sangoma_isdn_dchan_run(ftdm_thread_t *me, void *obj)
+{
+ uint8_t data[1000];
+ ftdm_status_t status = FTDM_SUCCESS;
+ ftdm_wait_flag_t wflags = FTDM_READ;
+ ftdm_span_t *span = (ftdm_span_t*) obj;
+ ftdm_channel_t *dchan = ((sngisdn_span_data_t*)span->signal_data)->dchan;
+ ftdm_size_t len = 0;
+
+ ftdm_channel_set_feature(dchan, FTDM_CHANNEL_FEATURE_IO_STATS);
+ ftdm_sangoma_isdn_dchan_set_queue_size(dchan);
+
+ ftdm_assert(dchan, "Span does not have a dchannel");
+ ftdm_channel_open_chan(dchan);
+
+ while (ftdm_running() && !(ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD))) {
+ wflags = FTDM_READ;
+ status = ftdm_channel_wait(dchan, &wflags, 10000);
+ switch(status) {
+ case FTDM_FAIL:
+ ftdm_log_chan_msg(dchan, FTDM_LOG_CRIT, "Failed to wait for d-channel\n");
+ break;
+ case FTDM_TIMEOUT:
+ break;
+ case FTDM_SUCCESS:
+ if ((wflags & FTDM_READ)) {
+ len = 1000;
+ status = ftdm_channel_read(dchan, data, &len);
+ if (status == FTDM_SUCCESS) {
+ sngisdn_snd_data(dchan, data, len);
+ } else {
+ ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Failed to read from channel \n");
+ }
+#ifndef WIN32 /* It is valid on WIN32 for poll to return without errors, but no flags set */
+ } else {
+ ftdm_log_chan_msg(dchan, FTDM_LOG_CRIT, "Failed to poll for d-channel\n");
+#endif
+ }
+ break;
+ default:
+ ftdm_log_chan_msg(dchan, FTDM_LOG_CRIT, "Unhandled IO event\n");
+ }
+ }
+ ftdm_channel_close(&dchan);
+ return NULL;
+}
+
static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
{
- ftdm_interrupt_t *ftdm_sangoma_isdn_int[2];
+ ftdm_interrupt_t *ftdm_sangoma_isdn_int[3];
ftdm_status_t ret_status;
ftdm_span_t *span = (ftdm_span_t *) obj;
ftdm_channel_t *ftdmchan = NULL;
@@ -300,8 +409,13 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to get a ftdm_interrupt for span = %s!\n", span->name);
goto ftdm_sangoma_isdn_run_exit;
}
+
+ if (ftdm_queue_get_interrupt(span->pendingsignals, &ftdm_sangoma_isdn_int[1]) != FTDM_SUCCESS) {
+ ftdm_log(FTDM_LOG_CRIT, "%s:Failed to get a signal interrupt for span = %s!\n", span->name);
+ goto ftdm_sangoma_isdn_run_exit;
+ }
- if (ftdm_queue_get_interrupt(signal_data->event_queue, &ftdm_sangoma_isdn_int[1]) != FTDM_SUCCESS) {
+ if (ftdm_queue_get_interrupt(signal_data->event_queue, &ftdm_sangoma_isdn_int[2]) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to get a event interrupt for span = %s!\n", span->name);
goto ftdm_sangoma_isdn_run_exit;
}
@@ -310,8 +424,14 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
/* Check if there are any timers to process */
ftdm_sched_run(signal_data->sched);
+ ftdm_span_trigger_signals(span);
- ret_status = ftdm_interrupt_multiple_wait(ftdm_sangoma_isdn_int, 2, sleep);
+ if (ftdm_sched_get_time_to_next_timer(signal_data->sched, &sleep) == FTDM_SUCCESS) {
+ if (sleep < 0 || sleep > SNGISDN_EVENT_POLL_RATE) {
+ sleep = SNGISDN_EVENT_POLL_RATE;
+ }
+ }
+ ret_status = ftdm_interrupt_multiple_wait(ftdm_sangoma_isdn_int, 3, sleep);
/* find out why we returned from the interrupt queue */
switch (ret_status) {
case FTDM_SUCCESS: /* there was a state change on the span */
@@ -327,7 +447,6 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
ftdm_sangoma_isdn_process_stack_event(span, sngisdn_event);
ftdm_safe_free(sngisdn_event);
}
- ftdm_span_trigger_signals(span);
break;
case FTDM_TIMEOUT:
/* twiddle */
@@ -343,12 +462,6 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
/* Poll for events, e.g HW DTMF */
ftdm_sangoma_isdn_poll_events(span);
-
- if (ftdm_sched_get_time_to_next_timer(signal_data->sched, &sleep) == FTDM_SUCCESS) {
- if (sleep < 0 || sleep > SNGISDN_EVENT_POLL_RATE) {
- sleep = SNGISDN_EVENT_POLL_RATE;
- }
- }
}
/* clear the IN_THREAD flag so that we know the thread is done */
@@ -512,13 +625,15 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
break;
case FTDM_CHANNEL_STATE_GET_CALLERID:
{
- sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED);
- sngisdn_snd_proceed(ftdmchan);
+ if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) {
+ sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED);
+ sngisdn_snd_proceed(ftdmchan);
+ }
/* Wait in this state until we get FACILITY msg */
}
break;
case FTDM_CHANNEL_STATE_RING: /* incoming call request */
- {
+ {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending incoming call from %s to %s to FTDM core\n", ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.dnis.digits);
/* we have enough information to inform FTDM of the call*/
@@ -535,14 +650,34 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Requesting Line activation\n");
- sngisdn_set_flag(sngisdn_info, FLAG_ACTIVATING);
- sng_isdn_wake_up_phy(ftdmchan->span);
+ sngisdn_set_flag(sngisdn_info, FLAG_ACTIVATING);
+ ftdm_sangoma_isdn_wakeup_phy(ftdmchan);
ftdm_sched_timer(signal_data->sched, "timer_t3", signal_data->timer_t3*1000, sngisdn_t3_timeout, (void*) sngisdn_info, NULL);
} else {
sngisdn_snd_setup(ftdmchan);
}
}
break;
+ case FTDM_CHANNEL_STATE_PROCEED:
+ {
+ if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
+ /*OUTBOUND...so we were told by the line of this so noifiy the user*/
+ sigev.event_id = FTDM_SIGEVENT_PROCEED;
+ ftdm_span_send_signal(ftdmchan->span, &sigev);
+ } else {
+ if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) {
+ sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED);
+ sngisdn_snd_proceed(ftdmchan);
+ }
+ }
+ }
+ break;
+ case FTDM_CHANNEL_STATE_RINGING:
+ {
+ ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
+ sngisdn_snd_alert(ftdmchan, prog_ind);
+ }
+ break;
case FTDM_CHANNEL_STATE_PROGRESS:
{
/*check if the channel is inbound or outbound*/
@@ -550,9 +685,13 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
/*OUTBOUND...so we were told by the line of this so noifiy the user*/
sigev.event_id = FTDM_SIGEVENT_PROGRESS;
ftdm_span_send_signal(ftdmchan->span, &sigev);
- } else if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) {
- sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED);
- sngisdn_snd_proceed(ftdmchan);
+ } else {
+ /* If we already sent a PROCEED before, do not send a PROGRESS as there is nothing to indicate to the remote switch */
+ if (ftdmchan->last_state != FTDM_CHANNEL_STATE_PROCEED) {
+ /* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */
+ ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
+ sngisdn_snd_progress(ftdmchan, prog_ind);
+ }
}
}
break;
@@ -562,7 +701,9 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
ftdm_span_send_signal(ftdmchan->span, &sigev);
} else {
- sngisdn_snd_progress(ftdmchan);
+ /* Send a progress message, indicating: In-band information/pattern available */
+ ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_IB_AVAIL};
+ sngisdn_snd_progress(ftdmchan, prog_ind);
}
}
break;
@@ -633,7 +774,7 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
sngisdn_snd_release(ftdmchan, 0);
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
- sng_isdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
+ sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
}
} else {
sngisdn_snd_disconnect(ftdmchan);
@@ -658,9 +799,7 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
break;
case FTDM_CHANNEL_STATE_DOWN: /* the call is finished and removed */
{
- uint8_t glare = 0;
-
- glare = sngisdn_test_flag(sngisdn_info, FLAG_GLARE);
+ uint8_t glare = sngisdn_test_flag(sngisdn_info, FLAG_GLARE);
/* clear all of the call specific data store in the channel structure */
clear_call_data(sngisdn_info);
@@ -788,7 +927,7 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_span_sig_status)
static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
{
ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id);
- if (sng_isdn_stack_start(span) != FTDM_SUCCESS) {
+ if (sngisdn_stack_start(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name);
return FTDM_FAIL;
}
@@ -802,6 +941,12 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
return FTDM_FAIL;
}
+ /*start the dchan monitor thread*/
+ if (ftdm_thread_create_detached(ftdm_sangoma_isdn_dchan_run, span) != FTDM_SUCCESS) {
+ ftdm_log(FTDM_LOG_CRIT,"Failed to start Sangoma ISDN d-channel Monitor Thread!\n");
+ return FTDM_FAIL;
+ }
+
ftdm_log(FTDM_LOG_DEBUG,"Finished starting span %s\n", span->name);
return FTDM_SUCCESS;
}
@@ -823,7 +968,7 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span)
ftdm_sleep(10);
}
- if (sng_isdn_stack_stop(span) != FTDM_SUCCESS) {
+ if (sngisdn_stack_stop(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed to stop span %s\n", span->name);
}
@@ -875,7 +1020,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
return FTDM_FAIL;
}
- if (sng_isdn_stack_cfg(span) != FTDM_SUCCESS) {
+ if (sngisdn_stack_cfg(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Sangoma ISDN Stack configuration failed\n");
return FTDM_FAIL;
}
@@ -894,11 +1039,12 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
span->state_map = &sangoma_isdn_state_map;
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);
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP ||
span->trunk_type == FTDM_TRUNK_BRI) {
- sng_isdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
+ sngisdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
}
/* Initialize scheduling context */
@@ -917,7 +1063,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init)
ftdm_log(FTDM_LOG_INFO, "Loading ftmod_sangoma_isdn...\n");
memset(&g_sngisdn_data, 0, sizeof(g_sngisdn_data));
-
+ memset(&g_sngisdn_event_interface, 0, sizeof(g_sngisdn_event_interface));
/* set callbacks */
g_sngisdn_event_interface.cc.sng_con_ind = sngisdn_rcv_con_ind;
g_sngisdn_event_interface.cc.sng_con_cfm = sngisdn_rcv_con_cfm;
@@ -946,8 +1092,11 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init)
g_sngisdn_event_interface.sta.sng_q921_trc_ind = sngisdn_rcv_q921_trace;
g_sngisdn_event_interface.sta.sng_q931_sta_ind = sngisdn_rcv_q931_ind;
g_sngisdn_event_interface.sta.sng_q931_trc_ind = sngisdn_rcv_q931_trace;
- g_sngisdn_event_interface.sta.sng_cc_sta_ind = sngisdn_rcv_cc_ind;
+ g_sngisdn_event_interface.sta.sng_cc_sta_ind = sngisdn_rcv_cc_ind;
+ g_sngisdn_event_interface.io.sng_l1_data_req = sngisdn_rcv_l1_data_req;
+ g_sngisdn_event_interface.io.sng_l1_cmd_req = sngisdn_rcv_l1_cmd_req;
+
for(i=1;i<=MAX_VARIANTS;i++) {
ftdm_mutex_create(&g_sngisdn_data.ccs[i].mutex);
}
@@ -1008,11 +1157,11 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
goto done;
}
if (!strcasecmp(trace_opt, "q921")) {
- sng_isdn_activate_trace(span, SNGISDN_TRACE_Q921);
+ sngisdn_activate_trace(span, SNGISDN_TRACE_Q921);
} else if (!strcasecmp(trace_opt, "q931")) {
- sng_isdn_activate_trace(span, SNGISDN_TRACE_Q931);
+ sngisdn_activate_trace(span, SNGISDN_TRACE_Q931);
} else if (!strcasecmp(trace_opt, "disable")) {
- sng_isdn_activate_trace(span, SNGISDN_TRACE_DISABLE);
+ sngisdn_activate_trace(span, SNGISDN_TRACE_DISABLE);
} else {
stream->write_function(stream, "-ERR invalid trace option \n");
}
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h
index 36b5662faf..b9ab3395ae 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h
@@ -60,9 +60,37 @@
#define SNGISDN_EVENT_QUEUE_SIZE 100
#define SNGISDN_EVENT_POLL_RATE 100
#define SNGISDN_NUM_LOCAL_NUMBERS 8
+#define SNGISDN_DCHAN_QUEUE_LEN 200
/* TODO: rename all *_cc_* to *_an_* */
+#define SNGISDN_ENUM_NAMES(_NAME, _STRINGS) static const char * _NAME [] = { _STRINGS , NULL };
+#define SNGISDN_STR2ENUM_P(_FUNC1, _FUNC2, _TYPE) _TYPE _FUNC1 (const char *name); const char * _FUNC2 (_TYPE type);
+#define SNGISDN_STR2ENUM(_FUNC1, _FUNC2, _TYPE, _STRINGS, _MAX) \
+ _TYPE _FUNC1 (const char *name) \
+{ \
+ int i; \
+ _TYPE t = _MAX ; \
+ \
+ for (i = 0; i < _MAX ; i++) { \
+ if (!strcasecmp(name, _STRINGS[i])) { \
+ t = (_TYPE) i; \
+ break; \
+} \
+} \
+ \
+ return t; \
+} \
+ const char * _FUNC2 (_TYPE type) \
+{ \
+ if (type > _MAX) { \
+ type = _MAX; \
+} \
+ return _STRINGS[(int)type]; \
+} \
+
+
+
typedef enum {
FLAG_RESET_RX = (1 << 0),
FLAG_RESET_TX = (1 << 1),
@@ -74,7 +102,8 @@ typedef enum {
FLAG_DELAYED_REL = (1 << 7),
FLAG_SENT_PROCEED = (1 << 8),
FLAG_SEND_DISC = (1 << 9),
- FLAG_ACTIVATING = (1 << 10), /* Used for BRI only, flag is set after we request line CONNECTED */
+ /* Used for BRI only, flag is set after we request line CONNECTED */
+ FLAG_ACTIVATING = (1 << 10),
} sngisdn_flag_t;
@@ -134,6 +163,51 @@ typedef enum {
SNGISDN_EVENT_RST_IND,
} ftdm_sngisdn_event_id_t;
+typedef enum {
+ /* Call is not end-to-end ISDN */
+ SNGISDN_PROGIND_DESCR_NETE_ISDN,
+ /* Destination address is non-ISDN */
+ SNGISDN_PROGIND_DESCR_DEST_NISDN,
+ /* Origination address is non-ISDN */
+ SNGISDN_PROGIND_DESCR_ORIG_NISDN,
+ /* Call has returned to the ISDN */
+ SNGISDN_PROGIND_DESCR_RET_ISDN,
+ /* Interworking as occured and has resulted in a telecommunication service change */
+ SNGISDN_PROGIND_DESCR_SERV_CHANGE,
+ /* In-band information or an appropriate pattern is now available */
+ SNGISDN_PROGIND_DESCR_IB_AVAIL,
+ /* Invalid */
+ SNGISDN_PROGIND_DESCR_INVALID,
+} ftdm_sngisdn_progind_descr_t;
+#define SNGISDN_PROGIND_DESCR_STRINGS "not-end-to-end-isdn", "destination-is-non-isdn", "origination-is-non-isdn", "call-returned-to-isdn", "service-change", "inband-info-available", "invalid"
+SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_progind_descr, ftdm_sngisdn_progind_descr2str, ftdm_sngisdn_progind_descr_t);
+
+typedef enum {
+ /* User */
+ SNGISDN_PROGIND_LOC_USER,
+ /* Private network serving the local user */
+ SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR,
+ /* Public network serving the local user */
+ SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR,
+ /* Transit network */
+ SNGISDN_PROGIND_LOC_TRANSIT_NET,
+ /* Public network serving remote user */
+ SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR,
+ /* Private network serving remote user */
+ SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR,
+ /* Network beyond the interworking point */
+ SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW,
+ /* Invalid */
+ SNGISDN_PROGIND_LOC_INVALID,
+} ftdm_sngisdn_progind_loc_t;
+#define SNGISDN_PROGIND_LOC_STRINGS "user", "private-net-local-user", "public-net-local-user", "transit-network", "public-net-remote-user", "private-net-remote-user", "beyond-interworking", "invalid"
+SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t);
+
+typedef struct ftdm_sngisdn_prog_ind {
+ ftdm_sngisdn_progind_loc_t loc; /* location */
+ ftdm_sngisdn_progind_descr_t descr; /* description */
+} ftdm_sngisdn_progind_t;
+
/* Only timers that can be cancelled are listed here */
#define SNGISDN_NUM_TIMERS 1
/* Increase NUM_TIMERS as number of ftdm_sngisdn_timer_t increases */
@@ -168,6 +242,7 @@ typedef struct sngisdn_chan_data {
/* Span specific data */
typedef struct sngisdn_span_data {
ftdm_span_t *ftdm_span;
+ ftdm_channel_t *dchan;
uint8_t link_id;
uint8_t switchtype;
uint8_t signalling; /* SNGISDN_SIGNALING_CPE or SNGISDN_SIGNALING_NET */
@@ -179,9 +254,11 @@ typedef struct sngisdn_span_data {
uint8_t trace_flags; /* TODO: change to flags, so we can use ftdm_test_flag etc.. */
uint8_t overlap_dial;
uint8_t setup_arb;
+ uint8_t facility_ie_decode;
uint8_t facility;
int8_t facility_timeout;
uint8_t num_local_numbers;
+ uint8_t ignore_cause_value;
uint8_t timer_t3;
uint8_t restart_opt;
char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS];
@@ -269,60 +346,58 @@ extern ftdm_sngisdn_data_t g_sngisdn_data;
ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span);
/* Support functions */
-FT_DECLARE(uint32_t) get_unique_suInstId(int16_t cc_id);
-FT_DECLARE(void) clear_call_data(sngisdn_chan_data_t *sngisdn_info);
-FT_DECLARE(void) clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info);
+uint32_t get_unique_suInstId(int16_t cc_id);
+void clear_call_data(sngisdn_chan_data_t *sngisdn_info);
+void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info);
+ftdm_status_t get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data);
+ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data);
+
+
+ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail);
+ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt);
void stack_hdr_init(Header *hdr);
void stack_pst_init(Pst *pst);
-FT_DECLARE(ftdm_status_t) get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data);
-FT_DECLARE(ftdm_status_t) get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data);
-FT_DECLARE(ftdm_status_t) sng_isdn_set_avail_rate(ftdm_span_t *ftdmspan, sngisdn_avail_t avail);
-
-FT_DECLARE(ftdm_status_t) cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb);
-FT_DECLARE(ftdm_status_t) cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb);
-FT_DECLARE(ftdm_status_t) cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb);
-FT_DECLARE(ftdm_status_t) cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display);
-
-FT_DECLARE(ftdm_status_t) cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm);
-FT_DECLARE(ftdm_status_t) cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
-FT_DECLARE(ftdm_status_t) cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm);
-FT_DECLARE(ftdm_status_t) cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan);
-
/* Outbound Call Control functions */
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan);
void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan);
void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan);
-void sngisdn_snd_progress(ftdm_channel_t *ftdmchan);
-void sngisdn_snd_alert(ftdm_channel_t *ftdmchan);
+void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind);
+void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind);
void sngisdn_snd_connect(ftdm_channel_t *ftdmchan);
void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan);
void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare);
void sngisdn_snd_reset(ftdm_channel_t *ftdmchan);
void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan);
+void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan);
void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan);
void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan);
+void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len);
+void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event);
/* Inbound Call Control functions */
-void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces);
-void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces);
-void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces);
-void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt);
-void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt);
-void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt);
-void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
-void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
-void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
-void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
-void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
-void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, FacEvnt *facEvnt, uint8_t evntType, int16_t dChan, uint8_t ces);
-void sngisdn_rcv_sta_cfm ( int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
-void sngisdn_rcv_srv_ind ( int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
-void sngisdn_rcv_srv_cfm ( int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
-void sngisdn_rcv_rst_cfm ( int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
-void sngisdn_rcv_rst_ind ( int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
+void sngisdn_rcv_con_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces);
+void sngisdn_rcv_con_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces);
+void sngisdn_rcv_cnst_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces);
+void sngisdn_rcv_disc_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt);
+void sngisdn_rcv_rel_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt);
+void sngisdn_rcv_dat_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt);
+void sngisdn_rcv_sshl_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
+void sngisdn_rcv_sshl_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
+void sngisdn_rcv_rmrt_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
+void sngisdn_rcv_rmrt_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
+void sngisdn_rcv_flc_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
+void sngisdn_rcv_fac_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, FacEvnt *facEvnt, uint8_t evntType, int16_t dChan, uint8_t ces);
+void sngisdn_rcv_sta_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
+void sngisdn_rcv_srv_ind(int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
+void sngisdn_rcv_srv_cfm(int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
+void sngisdn_rcv_rst_cfm(int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
+void sngisdn_rcv_rst_ind(int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
+int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame);
+int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd);
+
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event);
void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event);
@@ -360,6 +435,26 @@ void sngisdn_rcv_cc_ind(CcMngmt *status);
void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...);
void sngisdn_rcv_sng_assert(char *message);
+ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb);
+ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb);
+ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb);
+ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *display);
+ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr);
+ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad);
+ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd);
+ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr);
+ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t data_len);
+
+ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb);
+ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb);
+ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb);
+ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt);
+ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad);
+ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind);
+ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr);
+ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t *data_len);
+
+
uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability);
uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_prot);
ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_user(uint8_t bearer_capability);
@@ -386,6 +481,7 @@ static __inline__ void sngisdn_set_flag(sngisdn_chan_data_t *sngisdn_info, sngis
void handle_sng_log(uint8_t level, char *fmt,...);
void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status);
+void sngisdn_delayed_setup(void* p_sngisdn_info);
void sngisdn_delayed_release(void* p_sngisdn_info);
void sngisdn_delayed_connect(void* p_sngisdn_info);
void sngisdn_delayed_disconnect(void* p_sngisdn_info);
@@ -393,10 +489,10 @@ void sngisdn_facility_timeout(void* p_sngisdn_info);
void sngisdn_t3_timeout(void* p_sngisdn_info);
/* Stack management functions */
-ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span);
-ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span);
-ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span);
-ftdm_status_t sng_isdn_wake_up_phy(ftdm_span_t *span);
+ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span);
+ftdm_status_t sngisdn_stack_start(ftdm_span_t *span);
+ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span);
+ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span);
void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span);
void sngisdn_print_spans(ftdm_stream_handle_t *stream);
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c
index a869bda48d..cce10cc1dd 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c
@@ -34,13 +34,24 @@
#include "ftmod_sangoma_isdn.h"
-ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span);
-ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span);
-ftdm_status_t add_local_number(const char* val, ftdm_span_t *span);
+static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span);
+static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span);
+static ftdm_status_t add_local_number(const char* val, ftdm_span_t *span);
+static ftdm_status_t parse_yesno(const char* var, const char* val, uint8_t *target);
extern ftdm_sngisdn_data_t g_sngisdn_data;
-ftdm_status_t add_local_number(const char* val, ftdm_span_t *span)
+static ftdm_status_t parse_yesno(const char* var, const char* val, uint8_t *target)
+{
+ if (ftdm_true(val)) {
+ *target = SNGISDN_OPT_TRUE;
+ } else {
+ *target = SNGISDN_OPT_FALSE;
+ }
+ return FTDM_SUCCESS;
+}
+
+static ftdm_status_t add_local_number(const char* val, ftdm_span_t *span)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
@@ -53,12 +64,14 @@ ftdm_status_t add_local_number(const char* val, ftdm_span_t *span)
return FTDM_SUCCESS;
}
-ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
+static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
{
unsigned i;
-
+ ftdm_iterator_t *chaniter = NULL;
+ ftdm_iterator_t *curr = NULL;
sngisdn_dchan_data_t *dchan_data;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
+
switch(span->trunk_type) {
case FTDM_TRUNK_T1:
if (!strcasecmp(switch_name, "ni2") ||
@@ -124,9 +137,9 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
/* add this span to its ent_cc */
signal_data->cc_id = i;
- /* create a new dchan */ /* for NFAS - no-dchan on b-channels only links */
+ /* create a new dchan */ /* for NFAS - no-dchan on b-channels-only links */
g_sngisdn_data.num_dchan++;
- signal_data->dchan_id = g_sngisdn_data.num_dchan;
+ signal_data->dchan_id = g_sngisdn_data.num_dchan;
dchan_data = &g_sngisdn_data.dchans[signal_data->dchan_id];
dchan_data->num_spans++;
@@ -138,20 +151,27 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
ftdm_log(FTDM_LOG_DEBUG, "%s: cc_id:%d dchan_id:%d span_id:%d\n", span->name, signal_data->cc_id, signal_data->dchan_id, signal_data->span_id);
- /* Add the channels to the span */
- for (i=1;i<=span->chan_count;i++) {
- unsigned chan_id;
- ftdm_channel_t *ftdmchan = span->channels[i];
- /* NFAS is not supported on E1, so span_id will always be 1 for E1 so this will work for E1 as well */
- chan_id = ((signal_data->span_id-1)*NUM_T1_CHANNELS_PER_SPAN)+ftdmchan->physical_chan_id;
- dchan_data->channels[chan_id] = (sngisdn_chan_data_t*)ftdmchan->call_data;
- dchan_data->num_chans++;
+
+ chaniter = ftdm_span_get_chan_iterator(span, NULL);
+ for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
+ int32_t chan_id;
+ ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
+ if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) {
+ /* set the d-channel */
+ signal_data->dchan = ftdmchan;
+ } else {
+ /* Add the channels to the span */
+ /* NFAS is not supported on E1, so span_id will always be 1 for E1 so this will work for E1 as well */
+ chan_id = ((signal_data->span_id-1)*NUM_T1_CHANNELS_PER_SPAN)+ftdmchan->physical_chan_id;
+ dchan_data->channels[chan_id] = (sngisdn_chan_data_t*)ftdmchan->call_data;
+ dchan_data->num_chans++;
+ }
}
-
+ ftdm_iterator_free(chaniter);
return FTDM_SUCCESS;
}
-ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span)
+static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
if (!strcasecmp(signalling, "net") ||
@@ -181,6 +201,8 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
signal_data->min_digits = 8;
signal_data->overlap_dial = SNGISDN_OPT_DEFAULT;
signal_data->setup_arb = SNGISDN_OPT_DEFAULT;
+ signal_data->facility_ie_decode = SNGISDN_OPT_DEFAULT;
+ signal_data->ignore_cause_value = SNGISDN_OPT_DEFAULT;
signal_data->timer_t3 = 8;
signal_data->restart_opt = SNGISDN_OPT_DEFAULT;
@@ -193,20 +215,19 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
if (span->trunk_type == FTDM_TRUNK_BRI ||
span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
-
- ftdm_span_set_npi("unknown", &span->default_caller_data.dnis.plan);
- ftdm_span_set_ton("unknown", &span->default_caller_data.dnis.type);
- ftdm_span_set_npi("unknown", &span->default_caller_data.cid_num.plan);
- ftdm_span_set_ton("unknown", &span->default_caller_data.cid_num.type);
- ftdm_span_set_npi("unknown", &span->default_caller_data.rdnis.plan);
- ftdm_span_set_ton("unknown", &span->default_caller_data.rdnis.type);
+ ftdm_set_npi("unknown", &span->default_caller_data.dnis.plan);
+ ftdm_set_ton("unknown", &span->default_caller_data.dnis.type);
+ ftdm_set_npi("unknown", &span->default_caller_data.cid_num.plan);
+ ftdm_set_ton("unknown", &span->default_caller_data.cid_num.type);
+ ftdm_set_npi("unknown", &span->default_caller_data.rdnis.plan);
+ ftdm_set_ton("unknown", &span->default_caller_data.rdnis.type);
} else {
- ftdm_span_set_npi("e164", &span->default_caller_data.dnis.plan);
- ftdm_span_set_ton("national", &span->default_caller_data.dnis.type);
- ftdm_span_set_npi("e164", &span->default_caller_data.cid_num.plan);
- ftdm_span_set_ton("national", &span->default_caller_data.cid_num.type);
- ftdm_span_set_npi("e164", &span->default_caller_data.rdnis.plan);
- ftdm_span_set_ton("national", &span->default_caller_data.rdnis.type);
+ ftdm_set_npi("isdn", &span->default_caller_data.dnis.plan);
+ ftdm_set_ton("national", &span->default_caller_data.dnis.type);
+ ftdm_set_npi("isdn", &span->default_caller_data.cid_num.plan);
+ ftdm_set_ton("national", &span->default_caller_data.cid_num.type);
+ ftdm_set_npi("isdn", &span->default_caller_data.rdnis.plan);
+ ftdm_set_ton("national", &span->default_caller_data.rdnis.type);
}
for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) {
@@ -238,49 +259,30 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
} else {
ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val);
}
- } else if (!strcasecmp(var, "setup arbitration")) {
- if (!strcasecmp(val, "yes")) {
- signal_data->setup_arb = SNGISDN_OPT_TRUE;
- } else if (!strcasecmp(val, "no")) {
- signal_data->setup_arb = SNGISDN_OPT_FALSE;
- } else {
- ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val);
- }
+ } else if (!strcasecmp(var, "setup-arbitration")) {
+ parse_yesno(var, val, &signal_data->setup_arb);
} else if (!strcasecmp(var, "facility")) {
- if (!strcasecmp(val, "yes")) {
- signal_data->facility = SNGISDN_OPT_TRUE;
- } else if (!strcasecmp(val, "no")) {
- signal_data->facility = SNGISDN_OPT_FALSE;
- } else {
- ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val);
- }
+ parse_yesno(var, val, &signal_data->facility);
} else if (!strcasecmp(var, "min_digits")) {
signal_data->min_digits = atoi(val);
} else if (!strcasecmp(var, "outbound-called-ton")) {
- ftdm_span_set_ton(val, &span->default_caller_data.dnis.type);
+ ftdm_set_ton(val, &span->default_caller_data.dnis.type);
} else if (!strcasecmp(var, "outbound-called-npi")) {
- ftdm_span_set_npi(val, &span->default_caller_data.dnis.plan);
+ ftdm_set_npi(val, &span->default_caller_data.dnis.plan);
} else if (!strcasecmp(var, "outbound-calling-ton")) {
- ftdm_span_set_ton(val, &span->default_caller_data.cid_num.type);
+ ftdm_set_ton(val, &span->default_caller_data.cid_num.type);
} else if (!strcasecmp(var, "outbound-calling-npi")) {
- ftdm_span_set_npi(val, &span->default_caller_data.cid_num.plan);
+ ftdm_set_npi(val, &span->default_caller_data.cid_num.plan);
} else if (!strcasecmp(var, "outbound-rdnis-ton")) {
- ftdm_span_set_ton(val, &span->default_caller_data.rdnis.type);
+ ftdm_set_ton(val, &span->default_caller_data.rdnis.type);
} else if (!strcasecmp(var, "outbound-rdnis-npi")) {
- ftdm_span_set_npi(val, &span->default_caller_data.rdnis.plan);
+ ftdm_set_npi(val, &span->default_caller_data.rdnis.plan);
} else if (!strcasecmp(var, "outbound-bearer_cap")) {
- ftdm_span_set_bearer_capability(val, &span->default_caller_data.bearer_capability);
+ ftdm_set_bearer_capability(val, (uint8_t*)&span->default_caller_data.bearer_capability);
} else if (!strcasecmp(var, "outbound-bearer_layer1")) {
- ftdm_span_set_bearer_layer1(val, &span->default_caller_data.bearer_layer1);
+ ftdm_set_bearer_layer1(val, (uint8_t*)&span->default_caller_data.bearer_layer1);
} else if (!strcasecmp(var, "channel-restart-on-link-up")) {
- if (!strcasecmp(val, "yes")) {
- signal_data->restart_opt = SNGISDN_OPT_TRUE;
- } else if (!strcasecmp(val, "no")) {
- signal_data->restart_opt = SNGISDN_OPT_FALSE;
- } else {
- ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val);
- }
-
+ parse_yesno(var, val, &signal_data->restart_opt);
} else if (!strcasecmp(var, "local-number")) {
if (add_local_number(val, span) != FTDM_SUCCESS) {
return FTDM_FAIL;
@@ -290,6 +292,10 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
if (signal_data->facility_timeout < 0) {
signal_data->facility_timeout = 0;
}
+ } else if (!strcasecmp(var, "facility-ie-decode")) {
+ parse_yesno(var, val, &signal_data->facility_ie_decode);
+ } else if (!strcasecmp(var, "ignore-cause-value")) {
+ parse_yesno(var, val, &signal_data->ignore_cause_value);
} else {
ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var);
}
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c
index 94683d8a4b..de10a9fac0 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c
@@ -38,52 +38,52 @@ extern ftdm_sngisdn_data_t g_sngisdn_data;
uint8_t sng_isdn_stack_switchtype(sngisdn_switchtype_t switchtype);
-ftdm_status_t sng_isdn_cfg_phy(ftdm_span_t *span);
-ftdm_status_t sng_isdn_cfg_q921(ftdm_span_t *span);
-ftdm_status_t sng_isdn_cfg_q931(ftdm_span_t *span);
-ftdm_status_t sng_isdn_cfg_cc(ftdm_span_t *span);
+ftdm_status_t sngisdn_cfg_phy(ftdm_span_t *span);
+ftdm_status_t sngisdn_cfg_q921(ftdm_span_t *span);
+ftdm_status_t sngisdn_cfg_q931(ftdm_span_t *span);
+ftdm_status_t sngisdn_cfg_cc(ftdm_span_t *span);
-ftdm_status_t sng_isdn_stack_cfg_phy_gen(void);
-ftdm_status_t sng_isdn_stack_cfg_q921_gen(void);
-ftdm_status_t sng_isdn_stack_cfg_q931_gen(void);
-ftdm_status_t sng_isdn_stack_cfg_cc_gen(void);
+ftdm_status_t sngisdn_stack_cfg_phy_gen(void);
+ftdm_status_t sngisdn_stack_cfg_q921_gen(void);
+ftdm_status_t sngisdn_stack_cfg_q931_gen(void);
+ftdm_status_t sngisdn_stack_cfg_cc_gen(void);
-ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span);
-ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span);
-ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management);
-ftdm_status_t sng_isdn_stack_cfg_q931_tsap(ftdm_span_t *span);
-ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span);
-ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span);
+ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span);
+ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span);
+ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management);
+ftdm_status_t sngisdn_stack_cfg_q931_tsap(ftdm_span_t *span);
+ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span);
+ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span);
-ftdm_status_t sng_isdn_stack_cfg_cc_sap(ftdm_span_t *span);
+ftdm_status_t sngisdn_stack_cfg_cc_sap(ftdm_span_t *span);
-ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
+ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
if (!g_sngisdn_data.gen_config_done) {
g_sngisdn_data.gen_config_done = 1;
ftdm_log(FTDM_LOG_DEBUG, "Starting general stack configuration\n");
- if(sng_isdn_stack_cfg_phy_gen()!= FTDM_SUCCESS) {
+ if(sngisdn_stack_cfg_phy_gen()!= FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed general physical configuration\n");
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "General stack physical done\n");
- if(sng_isdn_stack_cfg_q921_gen()!= FTDM_SUCCESS) {
+ if(sngisdn_stack_cfg_q921_gen()!= FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed general q921 configuration\n");
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "General stack q921 done\n");
- if(sng_isdn_stack_cfg_q931_gen()!= FTDM_SUCCESS) {
+ if(sngisdn_stack_cfg_q931_gen()!= FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed general q921 configuration\n");
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "General stack q931 done\n");
- if(sng_isdn_stack_cfg_cc_gen()!= FTDM_SUCCESS) {
+ if(sngisdn_stack_cfg_cc_gen()!= FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed general CC configuration\n");
return FTDM_FAIL;
}
@@ -92,26 +92,26 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
}
/* TODO: for NFAS, should only call these function for spans with d-chans */
- if (sng_isdn_stack_cfg_phy_psap(span) != FTDM_SUCCESS) {
+ if (sngisdn_stack_cfg_phy_psap(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:phy_psap configuration failed\n", span->name);
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "%s:phy_psap configuration done\n", span->name);
- if (sng_isdn_stack_cfg_q921_msap(span) != FTDM_SUCCESS) {
+ if (sngisdn_stack_cfg_q921_msap(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:q921_msap configuration failed\n", span->name);
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "%s:q921_msap configuration done\n", span->name);
- if (sng_isdn_stack_cfg_q921_dlsap(span, 0) != FTDM_SUCCESS) {
+ if (sngisdn_stack_cfg_q921_dlsap(span, 0) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:q921_dlsap configuration failed\n", span->name);
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "%s:q921_dlsap configuration done\n", span->name);
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
- if (sng_isdn_stack_cfg_q921_dlsap(span, 1) != FTDM_SUCCESS) {
+ if (sngisdn_stack_cfg_q921_dlsap(span, 1) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:q921_dlsap management configuration failed\n", span->name);
return FTDM_FAIL;
}
@@ -119,13 +119,13 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
}
- if (sng_isdn_stack_cfg_q931_dlsap(span) != FTDM_SUCCESS) {
+ if (sngisdn_stack_cfg_q931_dlsap(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:q931_dlsap configuration failed\n", span->name);
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "%s:q931_dlsap configuration done\n", span->name);
- if (sng_isdn_stack_cfg_q931_lce(span) != FTDM_SUCCESS) {
+ if (sngisdn_stack_cfg_q931_lce(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:q931_lce configuration failed\n", span->name);
return FTDM_FAIL;
}
@@ -134,13 +134,13 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
if (!g_sngisdn_data.ccs[signal_data->cc_id].config_done) {
g_sngisdn_data.ccs[signal_data->cc_id].config_done = 1;
/* if BRI, need to configure dlsap_mgmt */
- if (sng_isdn_stack_cfg_q931_tsap(span) != FTDM_SUCCESS) {
+ if (sngisdn_stack_cfg_q931_tsap(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:q931_tsap configuration failed\n", span->name);
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "%s:q931_tsap configuration done\n", span->name);
- if (sng_isdn_stack_cfg_cc_sap(span) != FTDM_SUCCESS) {
+ if (sngisdn_stack_cfg_cc_sap(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "%s:cc_sap configuration failed\n", span->name);
return FTDM_FAIL;
}
@@ -153,37 +153,37 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
-ftdm_status_t sng_isdn_stack_cfg_phy_gen(void)
+ftdm_status_t sngisdn_stack_cfg_phy_gen(void)
{
/*local variables*/
- L1Mngmt cfg; /*configuration structure*/
- Pst pst; /*post structure*/
+ L1Mngmt cfg; /*configuration structure*/
+ Pst pst; /*post structure*/
- /* initalize the post structure */
- stack_pst_init(&pst);
+ /* initalize the post structure */
+ stack_pst_init(&pst);
- /* insert the destination Entity */
- pst.dstEnt = ENTL1;
+ /* insert the destination Entity */
+ pst.dstEnt = ENTL1;
- /*clear the configuration structure*/
+ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
- /*fill in some general sections of the header*/
- stack_hdr_init(&cfg.hdr);
+ /*fill in some general sections of the header*/
+ stack_hdr_init(&cfg.hdr);
- /*fill in the specific fields of the header*/
- cfg.hdr.msgType = TCFG;
- cfg.hdr.entId.ent = ENTL1;
- cfg.hdr.entId.inst = S_INST;
- cfg.hdr.elmId.elmnt = STGEN;
+ /*fill in the specific fields of the header*/
+ cfg.hdr.msgType = TCFG;
+ cfg.hdr.entId.ent = ENTL1;
+ cfg.hdr.entId.inst = S_INST;
+ cfg.hdr.elmId.elmnt = STGEN;
- stack_pst_init(&cfg.t.cfg.s.l1Gen.sm );
- cfg.t.cfg.s.l1Gen.sm.srcEnt = ENTL1;
- cfg.t.cfg.s.l1Gen.sm.dstEnt = ENTSM;
+ stack_pst_init(&cfg.t.cfg.s.l1Gen.sm );
+ cfg.t.cfg.s.l1Gen.sm.srcEnt = ENTL1;
+ cfg.t.cfg.s.l1Gen.sm.dstEnt = ENTSM;
- cfg.t.cfg.s.l1Gen.nmbLnks = MAX_L1_LINKS+1;
- cfg.t.cfg.s.l1Gen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */
- cfg.t.cfg.s.l1Gen.poolTrLower = POOL_LW_TR; /* lower pool threshold */
+ cfg.t.cfg.s.l1Gen.nmbLnks = MAX_L1_LINKS;
+ cfg.t.cfg.s.l1Gen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */
+ cfg.t.cfg.s.l1Gen.poolTrLower = POOL_LW_TR; /* lower pool threshold */
if (sng_isdn_phy_config(&pst, &cfg)) {
return FTDM_FAIL;
@@ -191,55 +191,40 @@ ftdm_status_t sng_isdn_stack_cfg_phy_gen(void)
return FTDM_SUCCESS;
}
-ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span)
-{
- ftdm_iterator_t *chaniter;
- ftdm_iterator_t *curr;
- L1Mngmt cfg;
- Pst pst;
+ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span)
+{
+ L1Mngmt cfg;
+ Pst pst;
- int32_t d_channel_fd = -1;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
- /* initalize the post structure */
- stack_pst_init(&pst);
+ /* initalize the post structure */
+ stack_pst_init(&pst);
- /* insert the destination Entity */
- pst.dstEnt = ENTL1;
+ /* insert the destination Entity */
+ pst.dstEnt = ENTL1;
- /*clear the configuration structure*/
+ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
- /*fill in some general sections of the header*/
- stack_hdr_init(&cfg.hdr);
+ /*fill in some general sections of the header*/
+ stack_hdr_init(&cfg.hdr);
- /*fill in the specific fields of the header*/
- cfg.hdr.msgType = TCFG;
- cfg.hdr.entId.ent = ENTL1;
- cfg.hdr.entId.inst = S_INST;
- cfg.hdr.elmId.elmnt = STPSAP;
+ /*fill in the specific fields of the header*/
+ cfg.hdr.msgType = TCFG;
+ cfg.hdr.entId.ent = ENTL1;
+ cfg.hdr.entId.inst = S_INST;
+ cfg.hdr.elmId.elmnt = STPSAP;
cfg.hdr.elmId.elmntInst1 = signal_data->link_id;
-
- /* Find the d-channel */
- chaniter = ftdm_span_get_chan_iterator(span, NULL);
- for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
- ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
- if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) {
- d_channel_fd = (int32_t)ftdmchan->sockfd;
- break;
- }
- }
- ftdm_iterator_free(chaniter);
-
- if(d_channel_fd < 0) {
+ if (!signal_data->dchan) {
ftdm_log(FTDM_LOG_ERROR, "%s:No d-channels specified\n", span->name);
return FTDM_FAIL;
}
-
- cfg.t.cfg.s.l1PSAP.sockfd = d_channel_fd;
-
+
+ cfg.t.cfg.s.l1PSAP.sockfd = (int32_t)signal_data->dchan->sockfd;
+
switch(span->trunk_type) {
case FTDM_TRUNK_E1:
cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_PRI;
@@ -255,8 +240,8 @@ ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span)
default:
ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported trunk type %d\n", span->name, span->trunk_type);
return FTDM_FAIL;
- }
- cfg.t.cfg.s.l1PSAP.spId = signal_data->link_id;
+ }
+ cfg.t.cfg.s.l1PSAP.spId = signal_data->link_id;
if (sng_isdn_phy_config(&pst, &cfg)) {
return FTDM_FAIL;
@@ -265,28 +250,28 @@ ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span)
}
-ftdm_status_t sng_isdn_stack_cfg_q921_gen(void)
+ftdm_status_t sngisdn_stack_cfg_q921_gen(void)
{
BdMngmt cfg;
- Pst pst;
+ Pst pst;
- /* initalize the post structure */
- stack_pst_init(&pst);
+ /* initalize the post structure */
+ stack_pst_init(&pst);
/* insert the destination Entity */
- pst.dstEnt = ENTLD;
+ pst.dstEnt = ENTLD;
- /*clear the configuration structure*/
- memset(&cfg, 0, sizeof(cfg));
+ /*clear the configuration structure*/
+ memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/
- stack_hdr_init(&cfg.hdr);
-
- cfg.hdr.msgType = TCFG;
- cfg.hdr.entId.ent = ENTLD;
- cfg.hdr.entId.inst = S_INST;
- cfg.hdr.elmId.elmnt = STGEN;
- /* fill in the Gen Conf structures internal pst struct */
+ stack_hdr_init(&cfg.hdr);
- stack_pst_init(&cfg.t.cfg.s.bdGen.sm);
+ cfg.hdr.msgType = TCFG;
+ cfg.hdr.entId.ent = ENTLD;
+ cfg.hdr.entId.inst = S_INST;
+ cfg.hdr.elmId.elmnt = STGEN;
+ /* fill in the Gen Conf structures internal pst struct */
+
+ stack_pst_init(&cfg.t.cfg.s.bdGen.sm);
cfg.t.cfg.s.bdGen.sm.dstEnt = ENTSM; /* entity */
@@ -299,8 +284,8 @@ ftdm_status_t sng_isdn_stack_cfg_q921_gen(void)
#ifdef LAPD_3_4
cfg.t.cfg.s.bdGen.timeRes = 100; /* timer resolution = 1 sec */
#endif
- cfg.t.cfg.s.bdGen.poolTrUpper = 2; /* upper pool threshold */
- cfg.t.cfg.s.bdGen.poolTrLower = 1; /* lower pool threshold */
+ cfg.t.cfg.s.bdGen.poolTrUpper = 2; /* upper pool threshold */
+ cfg.t.cfg.s.bdGen.poolTrLower = 1; /* lower pool threshold */
if (sng_isdn_q921_config(&pst, &cfg)) {
return FTDM_FAIL;
@@ -308,30 +293,30 @@ ftdm_status_t sng_isdn_stack_cfg_q921_gen(void)
return FTDM_SUCCESS;
}
-ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
+ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span)
{
BdMngmt cfg;
- Pst pst;
+ Pst pst;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
- /* initalize the post structure */
- stack_pst_init(&pst);
+ /* initalize the post structure */
+ stack_pst_init(&pst);
/* insert the destination Entity */
- pst.dstEnt = ENTLD;
+ pst.dstEnt = ENTLD;
- /*clear the configuration structure*/
- memset(&cfg, 0, sizeof(cfg));
+ /*clear the configuration structure*/
+ memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/
- stack_hdr_init(&cfg.hdr);
+ stack_hdr_init(&cfg.hdr);
cfg.hdr.msgType = TCFG;
- cfg.hdr.entId.ent = ENTLD;
- cfg.hdr.entId.inst = S_INST;
- cfg.hdr.elmId.elmnt = STMSAP;
+ cfg.hdr.entId.ent = ENTLD;
+ cfg.hdr.entId.inst = S_INST;
+ cfg.hdr.elmId.elmnt = STMSAP;
cfg.t.cfg.s.bdMSAP.lnkNmb = signal_data->link_id;
-
+
cfg.t.cfg.s.bdMSAP.maxOutsFrms = 24; /* MAC window */
cfg.t.cfg.s.bdMSAP.tQUpperTrs = 32; /* Tx Queue Upper Threshold */
cfg.t.cfg.s.bdMSAP.tQLowerTrs = 24; /* Tx Queue Lower Threshold */
@@ -343,7 +328,7 @@ ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
cfg.t.cfg.s.bdMSAP.route = RTESPEC; /* Route */
cfg.t.cfg.s.bdMSAP.dstProcId = SFndProcId(); /* destination proc id */
cfg.t.cfg.s.bdMSAP.dstEnt = ENTL1; /* entity */
- cfg.t.cfg.s.bdMSAP.dstInst = S_INST; /* instance */
+ cfg.t.cfg.s.bdMSAP.dstInst = S_INST; /* instance */
cfg.t.cfg.s.bdMSAP.t201Tmr = 1; /* T201 - should be equal to t200Tmr */
cfg.t.cfg.s.bdMSAP.t202Tmr = 2; /* T202 */
cfg.t.cfg.s.bdMSAP.bndRetryCnt = 2; /* bind retry counter */
@@ -392,7 +377,7 @@ ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
if (signal_data->setup_arb == SNGISDN_OPT_TRUE) {
cfg.t.cfg.s.bdMSAP.setUpArb = ACTIVE;
} else if (signal_data->setup_arb == SNGISDN_OPT_FALSE) {
- cfg.t.cfg.s.bdMSAP.setUpArb = PASSIVE;
+ cfg.t.cfg.s.bdMSAP.setUpArb = PASSIVE;
}
if (sng_isdn_q921_config(&pst, &cfg)) {
@@ -401,27 +386,27 @@ ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
return FTDM_SUCCESS;
}
-ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management)
+ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management)
{
BdMngmt cfg;
- Pst pst;
+ Pst pst;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
- /* initalize the post structure */
- stack_pst_init(&pst);
+ /* initalize the post structure */
+ stack_pst_init(&pst);
/* insert the destination Entity */
- pst.dstEnt = ENTLD;
+ pst.dstEnt = ENTLD;
- /*clear the configuration structure*/
- memset(&cfg, 0, sizeof(cfg));
+ /*clear the configuration structure*/
+ memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/
- stack_hdr_init(&cfg.hdr);
+ stack_hdr_init(&cfg.hdr);
/*fill in the specific fields of the header*/
- cfg.hdr.msgType = TCFG;
- cfg.hdr.entId.ent = ENTLD;
- cfg.hdr.entId.inst = S_INST;
- cfg.hdr.elmId.elmnt = STDLSAP;
+ cfg.hdr.msgType = TCFG;
+ cfg.hdr.entId.ent = ENTLD;
+ cfg.hdr.entId.inst = S_INST;
+ cfg.hdr.elmId.elmnt = STDLSAP;
cfg.t.cfg.s.bdDLSAP.lnkNmb = signal_data->link_id;
@@ -433,10 +418,10 @@ ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t managemen
} else {
cfg.t.cfg.s.bdDLSAP.k = 7; /* k */
}
-
+
cfg.t.cfg.s.bdDLSAP.n200 = 3; /* n200 */
cfg.t.cfg.s.bdDLSAP.congTmr = 300; /* congestion timer */
- cfg.t.cfg.s.bdDLSAP.t200Tmr = 1; /* t1 changed from 25 */
+ cfg.t.cfg.s.bdDLSAP.t200Tmr = 1; /* t1 changed from 25 */
cfg.t.cfg.s.bdDLSAP.t203Tmr = 10; /* t3 changed from 50 */
cfg.t.cfg.s.bdDLSAP.mod = 128; /* modulo */
cfg.t.cfg.s.bdDLSAP.selector = 0; /* Selector 0 */
@@ -483,31 +468,31 @@ ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t managemen
return FTDM_SUCCESS;
}
-ftdm_status_t sng_isdn_stack_cfg_q931_gen(void)
+ftdm_status_t sngisdn_stack_cfg_q931_gen(void)
{
InMngmt cfg;
- Pst pst;
+ Pst pst;
- /* initalize the post structure */
- stack_pst_init(&pst);
+ /* initalize the post structure */
+ stack_pst_init(&pst);
- /* insert the destination Entity */
- pst.dstEnt = ENTIN;
+ /* insert the destination Entity */
+ pst.dstEnt = ENTIN;
- /*clear the configuration structure*/
+ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
- /*fill in some general sections of the header*/
- stack_hdr_init(&cfg.hdr);
+ /*fill in some general sections of the header*/
+ stack_hdr_init(&cfg.hdr);
- /*fill in the specific fields of the header*/
- cfg.hdr.msgType = TCFG;
- cfg.hdr.entId.ent = ENTIN;
- cfg.hdr.entId.inst = S_INST;
- cfg.hdr.elmId.elmnt = STGEN;
+ /*fill in the specific fields of the header*/
+ cfg.hdr.msgType = TCFG;
+ cfg.hdr.entId.ent = ENTIN;
+ cfg.hdr.entId.inst = S_INST;
+ cfg.hdr.elmId.elmnt = STGEN;
- /* fill in the Gen Conf structures internal pst struct */
- stack_pst_init(&cfg.t.cfg.s.inGen.sm);
+ /* fill in the Gen Conf structures internal pst struct */
+ stack_pst_init(&cfg.t.cfg.s.inGen.sm);
cfg.t.cfg.s.inGen.nmbSaps = MAX_VARIANTS+1; /* Total number of variants supported */
@@ -538,29 +523,29 @@ ftdm_status_t sng_isdn_stack_cfg_q931_gen(void)
}
/* Link between CC and q931 */
-ftdm_status_t sng_isdn_stack_cfg_q931_tsap(ftdm_span_t *span)
+ftdm_status_t sngisdn_stack_cfg_q931_tsap(ftdm_span_t *span)
{
InMngmt cfg;
- Pst pst;
+ Pst pst;
unsigned i;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
- /* initalize the post structure */
- stack_pst_init(&pst);
+ /* initalize the post structure */
+ stack_pst_init(&pst);
- /* insert the destination Entity */
- pst.dstEnt = ENTIN;
+ /* insert the destination Entity */
+ pst.dstEnt = ENTIN;
- /*clear the configuration structure*/
+ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
- /*fill in some general sections of the header*/
- stack_hdr_init(&cfg.hdr);
+ /*fill in some general sections of the header*/
+ stack_hdr_init(&cfg.hdr);
- /*fill in the specific fields of the header*/
- cfg.hdr.msgType = TCFG;
- cfg.hdr.entId.ent = ENTIN;
- cfg.hdr.entId.inst = S_INST;
- cfg.hdr.elmId.elmnt = STTSAP;
+ /*fill in the specific fields of the header*/
+ cfg.hdr.msgType = TCFG;
+ cfg.hdr.entId.ent = ENTIN;
+ cfg.hdr.entId.inst = S_INST;
+ cfg.hdr.elmId.elmnt = STTSAP;
cfg.t.cfg.s.inTSAP.sapId = signal_data->cc_id;
@@ -601,34 +586,34 @@ ftdm_status_t sng_isdn_stack_cfg_q931_tsap(ftdm_span_t *span)
return FTDM_SUCCESS;
}
-ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
+ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
{
InMngmt cfg;
- Pst pst;
+ Pst pst;
unsigned i;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
- /* initalize the post structure */
- stack_pst_init(&pst);
+ /* initalize the post structure */
+ stack_pst_init(&pst);
- /* insert the destination Entity */
- pst.dstEnt = ENTIN;
+ /* insert the destination Entity */
+ pst.dstEnt = ENTIN;
- /*clear the configuration structure*/
+ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
- /*fill in some general sections of the header*/
- stack_hdr_init(&cfg.hdr);
+ /*fill in some general sections of the header*/
+ stack_hdr_init(&cfg.hdr);
+
+ /*fill in the specific fields of the header*/
+ cfg.hdr.msgType = TCFG;
+ cfg.hdr.entId.ent = ENTIN;
+ cfg.hdr.entId.inst = S_INST;
+ cfg.hdr.elmId.elmnt = STDLSAP;
- /*fill in the specific fields of the header*/
- cfg.hdr.msgType = TCFG;
- cfg.hdr.entId.ent = ENTIN;
- cfg.hdr.entId.inst = S_INST;
- cfg.hdr.elmId.elmnt = STDLSAP;
-
cfg.hdr.response.selector=0;
-
+
cfg.t.cfg.s.inDLSAP.sapId = signal_data->link_id;
cfg.t.cfg.s.inDLSAP.spId = signal_data->link_id;
cfg.t.cfg.s.inDLSAP.swtch = sng_isdn_stack_switchtype(signal_data->switchtype);
@@ -674,7 +659,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
cfg.t.cfg.s.inDLSAP.ctldInt[1] = 1;
}
- cfg.t.cfg.s.inDLSAP.numRstInd = 255;
+ cfg.t.cfg.s.inDLSAP.numRstInd = 255;
cfg.t.cfg.s.inDLSAP.relOpt = TRUE;
#ifdef ISDN_SRV
cfg.t.cfg.s.inDLSAP.bcas = FALSE;
@@ -860,39 +845,39 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
return FTDM_SUCCESS;
}
-ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span)
+ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span)
{
InMngmt cfg;
- Pst pst;
+ Pst pst;
uint8_t i;
- uint8_t numCes=1;
+ uint8_t numCes=1;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP && signal_data->signalling == SNGISDN_SIGNALING_NET) {
numCes = 8;
}
- /* initalize the post structure */
- stack_pst_init(&pst);
+ /* initalize the post structure */
+ stack_pst_init(&pst);
- /* insert the destination Entity */
- pst.dstEnt = ENTIN;
+ /* insert the destination Entity */
+ pst.dstEnt = ENTIN;
- /*clear the configuration structure*/
+ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg));
- /*fill in some general sections of the header*/
- stack_hdr_init(&cfg.hdr);
+ /*fill in some general sections of the header*/
+ stack_hdr_init(&cfg.hdr);
- /*fill in the specific fields of the header*/
- cfg.hdr.msgType = TCFG;
- cfg.hdr.entId.ent = ENTIN;
- cfg.hdr.entId.inst = S_INST;
- cfg.hdr.elmId.elmnt = STDLC;
+ /*fill in the specific fields of the header*/
+ cfg.hdr.msgType = TCFG;
+ cfg.hdr.entId.ent = ENTIN;
+ cfg.hdr.entId.inst = S_INST;
+ cfg.hdr.elmId.elmnt = STDLC;
cfg.hdr.response.selector=0;
cfg.t.cfg.s.inLCe.sapId = signal_data->link_id;
-
+
cfg.t.cfg.s.inLCe.lnkUpDwnInd = TRUE;
cfg.t.cfg.s.inLCe.tCon.enb = TRUE;
@@ -901,7 +886,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span)
cfg.t.cfg.s.inLCe.tDisc.val = 35;
cfg.t.cfg.s.inLCe.t314.enb = FALSE; /* if segmentation enabled, set to TRUE */
cfg.t.cfg.s.inLCe.t314.val = 35;
-
+
cfg.t.cfg.s.inLCe.t332i.enb = FALSE; /* set to TRUE for NFAS */
#ifdef NFAS
@@ -921,7 +906,6 @@ ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span)
cfg.t.cfg.s.inLCe.tRstAck.enb = TRUE;
cfg.t.cfg.s.inLCe.tRstAck.val = 10;
-
cfg.t.cfg.s.inLCe.usid = 0;
cfg.t.cfg.s.inLCe.tid = 0;
@@ -936,7 +920,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span)
}
-ftdm_status_t sng_isdn_stack_cfg_cc_gen(void)
+ftdm_status_t sngisdn_stack_cfg_cc_gen(void)
{
CcMngmt cfg;
Pst pst;
@@ -975,7 +959,7 @@ ftdm_status_t sng_isdn_stack_cfg_cc_gen(void)
}
-ftdm_status_t sng_isdn_stack_cfg_cc_sap(ftdm_span_t *span)
+ftdm_status_t sngisdn_stack_cfg_cc_sap(ftdm_span_t *span)
{
CcMngmt cfg;
Pst pst;
@@ -1007,11 +991,11 @@ ftdm_status_t sng_isdn_stack_cfg_cc_sap(ftdm_span_t *span)
cfg.t.cfg.s.ccISAP.pst.dstInst = S_INST;
cfg.t.cfg.s.ccISAP.pst.dstProcId = SFndProcId();
- cfg.t.cfg.s.ccISAP.pst.prior = PRIOR0;
- cfg.t.cfg.s.ccISAP.pst.route = RTESPEC;
- cfg.t.cfg.s.ccISAP.pst.region = S_REG;
- cfg.t.cfg.s.ccISAP.pst.pool = S_POOL;
- cfg.t.cfg.s.ccISAP.pst.selector = 0;
+ cfg.t.cfg.s.ccISAP.pst.prior = PRIOR0;
+ cfg.t.cfg.s.ccISAP.pst.route = RTESPEC;
+ cfg.t.cfg.s.ccISAP.pst.region = S_REG;
+ cfg.t.cfg.s.ccISAP.pst.pool = S_POOL;
+ cfg.t.cfg.s.ccISAP.pst.selector = 0;
cfg.t.cfg.s.ccISAP.suId = signal_data->cc_id;
cfg.t.cfg.s.ccISAP.spId = signal_data->cc_id;
@@ -1029,19 +1013,19 @@ ftdm_status_t sng_isdn_stack_cfg_cc_sap(ftdm_span_t *span)
void stack_pst_init(Pst *pst)
{
memset(pst, 0, sizeof(Pst));
- /*fill in the post structure*/
- pst->dstProcId = SFndProcId();
- pst->dstInst = S_INST;
+ /*fill in the post structure*/
+ pst->dstProcId = SFndProcId();
+ pst->dstInst = S_INST;
- pst->srcProcId = SFndProcId();
- pst->srcEnt = ENTSM;
- pst->srcInst = S_INST;
+ pst->srcProcId = SFndProcId();
+ pst->srcEnt = ENTSM;
+ pst->srcInst = S_INST;
- pst->prior = PRIOR0;
- pst->route = RTESPEC;
- pst->region = S_REG;
- pst->pool = S_POOL;
- pst->selector = 0;
+ pst->prior = PRIOR0;
+ pst->route = RTESPEC;
+ pst->region = S_REG;
+ pst->pool = S_POOL;
+ pst->selector = 0;
return;
}
@@ -1050,21 +1034,21 @@ void stack_pst_init(Pst *pst)
void stack_hdr_init(Header *hdr)
{
hdr->msgType = 0;
- hdr->msgLen = 0;
- hdr->entId.ent = 0;
- hdr->entId.inst = 0;
- hdr->elmId.elmnt = 0;
- hdr->elmId.elmntInst1 = 0;
- hdr->elmId.elmntInst2 = 0;
- hdr->elmId.elmntInst3 = 0;
- hdr->seqNmb = 0;
- hdr->version = 0;
- hdr->response.prior = PRIOR0;
- hdr->response.route = RTESPEC;
- hdr->response.mem.region = S_REG;
- hdr->response.mem.pool = S_POOL;
- hdr->transId = 0;
- hdr->response.selector = 0;
+ hdr->msgLen = 0;
+ hdr->entId.ent = 0;
+ hdr->entId.inst = 0;
+ hdr->elmId.elmnt = 0;
+ hdr->elmId.elmntInst1 = 0;
+ hdr->elmId.elmntInst2 = 0;
+ hdr->elmId.elmntInst3 = 0;
+ hdr->seqNmb = 0;
+ hdr->version = 0;
+ hdr->response.prior = PRIOR0;
+ hdr->response.route = RTESPEC;
+ hdr->response.mem.region = S_REG;
+ hdr->response.mem.pool = S_POOL;
+ hdr->transId = 0;
+ hdr->response.selector = 0;
return;
}
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c
index bfc00d07ba..225244f57e 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c
@@ -37,27 +37,26 @@
void stack_resp_hdr_init(Header *hdr);
-ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span);
-ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span);
+ftdm_status_t sngisdn_activate_phy(ftdm_span_t *span);
+ftdm_status_t sngisdn_deactivate_phy(ftdm_span_t *span);
-ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span);
-ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt);
+ftdm_status_t sngisdn_activate_cc(ftdm_span_t *span);
-ftdm_status_t sng_isdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction);
-ftdm_status_t sng_isdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction);
+ftdm_status_t sngisdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction);
+ftdm_status_t sngisdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction);
extern ftdm_sngisdn_data_t g_sngisdn_data;
-ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span);
+ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span);
-ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span)
+ftdm_status_t sngisdn_stack_start(ftdm_span_t *span)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
- if (sng_isdn_cntrl_q921(span, ABND_ENA, NOTUSED) != FTDM_SUCCESS) {
+ if (sngisdn_cntrl_q921(span, ABND_ENA, NOTUSED) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q921\n", span->name);
return FTDM_FAIL;
}
@@ -72,7 +71,7 @@ ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span)
ftdm_log(FTDM_LOG_DEBUG, "%s:Stack q921 activated\n", span->name);
if (!g_sngisdn_data.ccs[signal_data->cc_id].activation_done) {
g_sngisdn_data.ccs[signal_data->cc_id].activation_done = 1;
- if (sng_isdn_activate_cc(span) != FTDM_SUCCESS) {
+ if (sngisdn_activate_cc(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack CC\n", span->name);
return FTDM_FAIL;
}
@@ -80,7 +79,7 @@ ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span)
}
- if (sng_isdn_cntrl_q931(span, ABND_ENA, SAELMNT) != FTDM_SUCCESS) {
+ if (sngisdn_cntrl_q931(span, ABND_ENA, SAELMNT) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q931\n", span->name);
return FTDM_FAIL;
}
@@ -90,20 +89,20 @@ ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span)
return FTDM_SUCCESS;
}
-ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span)
+ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span)
{
/* Stop L1 first, so we do not receive any more frames */
- if (sng_isdn_deactivate_phy(span) != FTDM_SUCCESS) {
+ if (sngisdn_deactivate_phy(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack phy\n", span->name);
return FTDM_FAIL;
}
- if (sng_isdn_cntrl_q931(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
+ if (sngisdn_cntrl_q931(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q931\n", span->name);
return FTDM_FAIL;
}
- if (sng_isdn_cntrl_q921(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
+ if (sngisdn_cntrl_q921(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q921\n", span->name);
return FTDM_FAIL;
}
@@ -113,41 +112,7 @@ ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span)
}
-ftdm_status_t sng_isdn_wake_up_phy(ftdm_span_t *span)
-{
- L1Mngmt cntrl;
- Pst pst;
-
- sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
-
- /* initalize the post structure */
- stack_pst_init(&pst);
-
- /* insert the destination Entity */
- pst.dstEnt = ENTL1;
-
- /* initalize the control structure */
- memset(&cntrl, 0, sizeof(cntrl));
-
- /* initalize the control header */
- stack_hdr_init(&cntrl.hdr);
-
- cntrl.hdr.msgType = TCNTRL; /* configuration */
- cntrl.hdr.entId.ent = ENTL1; /* entity */
- cntrl.hdr.entId.inst = S_INST; /* instance */
- cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */
-
- cntrl.t.cntrl.action = AENA;
- cntrl.t.cntrl.subAction = SAELMNT;
- cntrl.t.cntrl.sapId = signal_data->link_id;
-
- if (sng_isdn_phy_cntrl(&pst, &cntrl)) {
- return FTDM_FAIL;
- }
- return FTDM_SUCCESS;
-}
-
-ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span)
+ftdm_status_t sngisdn_activate_phy(ftdm_span_t *span)
{
/* There is no need to start phy, as it will Q921 will send a activate request to phy when it starts */
@@ -155,7 +120,7 @@ ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span)
return FTDM_SUCCESS;
}
-ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span)
+ftdm_status_t sngisdn_deactivate_phy(ftdm_span_t *span)
{
L1Mngmt cntrl;
Pst pst;
@@ -189,8 +154,41 @@ ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span)
return FTDM_SUCCESS;
}
+ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span)
+{
+ L1Mngmt cntrl;
+ Pst pst;
-ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span)
+ sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
+
+ /* initalize the post structure */
+ stack_pst_init(&pst);
+
+ /* insert the destination Entity */
+ pst.dstEnt = ENTL1;
+
+ /* initalize the control structure */
+ memset(&cntrl, 0, sizeof(cntrl));
+
+ /* initalize the control header */
+ stack_hdr_init(&cntrl.hdr);
+
+ cntrl.hdr.msgType = TCNTRL; /* configuration */
+ cntrl.hdr.entId.ent = ENTL1; /* entity */
+ cntrl.hdr.entId.inst = S_INST; /* instance */
+ cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */
+
+ cntrl.t.cntrl.action = AENA;
+ cntrl.t.cntrl.subAction = SAELMNT;
+ cntrl.t.cntrl.sapId = signal_data->link_id;
+
+ if (sng_isdn_phy_cntrl(&pst, &cntrl)) {
+ return FTDM_FAIL;
+ }
+ return FTDM_SUCCESS;
+}
+
+ftdm_status_t sngisdn_activate_cc(ftdm_span_t *span)
{
CcMngmt cntrl;
Pst pst;
@@ -224,7 +222,7 @@ ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span)
return FTDM_SUCCESS;
}
-ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt)
+ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
switch (trace_opt) {
@@ -233,7 +231,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
ftdm_log(FTDM_LOG_INFO, "s%d Disabling q921 trace\n", signal_data->link_id);
sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q921);
- if (sng_isdn_cntrl_q921(span, ADISIMM, SATRC) != FTDM_SUCCESS) {
+ if (sngisdn_cntrl_q921(span, ADISIMM, SATRC) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "s%d Failed to disable q921 trace\n");
}
}
@@ -241,7 +239,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
ftdm_log(FTDM_LOG_INFO, "s%d Disabling q931 trace\n", signal_data->link_id);
sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q931);
- if (sng_isdn_cntrl_q931(span, ADISIMM, SATRC) != FTDM_SUCCESS) {
+ if (sngisdn_cntrl_q931(span, ADISIMM, SATRC) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "s%d Failed to disable q931 trace\n");
}
}
@@ -251,7 +249,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
ftdm_log(FTDM_LOG_INFO, "s%d Enabling q921 trace\n", signal_data->link_id);
sngisdn_set_trace_flag(signal_data, SNGISDN_TRACE_Q921);
- if (sng_isdn_cntrl_q921(span, AENA, SATRC) != FTDM_SUCCESS) {
+ if (sngisdn_cntrl_q921(span, AENA, SATRC) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "s%d Failed to enable q921 trace\n");
}
}
@@ -261,7 +259,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
ftdm_log(FTDM_LOG_INFO, "s%d Enabling q931 trace\n", signal_data->link_id);
sngisdn_set_trace_flag(signal_data, SNGISDN_TRACE_Q931);
- if (sng_isdn_cntrl_q931(span, AENA, SATRC) != FTDM_SUCCESS) {
+ if (sngisdn_cntrl_q931(span, AENA, SATRC) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "s%d Failed to enable q931 trace\n");
}
}
@@ -271,7 +269,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
}
-ftdm_status_t sng_isdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction)
+ftdm_status_t sngisdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction)
{
InMngmt cntrl;
Pst pst;
@@ -310,7 +308,7 @@ ftdm_status_t sng_isdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t sub
}
-ftdm_status_t sng_isdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction)
+ftdm_status_t sngisdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction)
{
BdMngmt cntrl;
Pst pst;
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
index 8408c673ef..d557ca3ba0 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
@@ -127,10 +127,16 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1");
#endif
/* Fill in call information */
- cpy_calling_num_from_stack(&ftdmchan->caller_data, &conEvnt->cgPtyNmb);
- cpy_called_num_from_stack(&ftdmchan->caller_data, &conEvnt->cdPtyNmb);
- cpy_calling_name_from_stack(&ftdmchan->caller_data, &conEvnt->display);
- cpy_redir_num_from_stack(&ftdmchan->caller_data, &conEvnt->redirNmb);
+ get_calling_num(ftdmchan, &conEvnt->cgPtyNmb);
+ get_called_num(ftdmchan, &conEvnt->cdPtyNmb);
+ get_redir_num(ftdmchan, &conEvnt->redirNmb);
+ get_calling_subaddr(ftdmchan, &conEvnt->cgPtySad);
+
+ if (get_calling_name_from_display(ftdmchan, &conEvnt->display) != FTDM_SUCCESS) {
+ get_calling_name_from_usr_usr(ftdmchan, &conEvnt->usrUsr);
+ }
+ get_prog_ind_ie(ftdmchan, &conEvnt->progInd);
+
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Incoming call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
if (conEvnt->bearCap[0].eh.pres) {
@@ -138,37 +144,43 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
ftdmchan->caller_data.bearer_capability = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].infoTranCap.val);
}
- if (signal_data->switchtype == SNGISDN_SWITCH_NI2) {
- if (conEvnt->shift11.eh.pres && conEvnt->ni2OctStr.eh.pres) {
- if (conEvnt->ni2OctStr.str.len == 4 && conEvnt->ni2OctStr.str.val[0] == 0x37) {
- snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", conEvnt->ni2OctStr.str.val[3]);
- }
+
+ if (conEvnt->shift11.eh.pres && conEvnt->ni2OctStr.eh.pres) {
+ if (conEvnt->ni2OctStr.str.len == 4 && conEvnt->ni2OctStr.str.val[0] == 0x37) {
+ snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", conEvnt->ni2OctStr.str.val[3]);
}
-
- if (signal_data->facility == SNGISDN_OPT_TRUE && conEvnt->facilityStr.eh.pres) {
- /* Verify whether the Caller Name will come in a subsequent FACILITY message */
- uint16_t ret_val;
- char retrieved_str[255];
-
- ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str);
- /*
- return values for "sng_isdn_retrieve_facility_information_following":
- If there will be no information following, or fails to decode IE, returns -1
- If there will be no information following, but current FACILITY IE contains a caller name, returns 0
- If there will be information following, returns 1
- */
+ }
- if (ret_val == 1) {
- ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n");
- ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID);
- /* Launch timer in case we never get a FACILITY msg */
- if (signal_data->facility_timeout) {
- ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout,
- sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
+ if (conEvnt->facilityStr.eh.pres) {
+ if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) {
+ get_facility_ie(ftdmchan, &conEvnt->facilityStr);
+ } else if (signal_data->facility == SNGISDN_OPT_TRUE) {
+ if (signal_data->switchtype == SNGISDN_SWITCH_NI2) {
+ /* Verify whether the Caller Name will come in a subsequent FACILITY message */
+ uint16_t ret_val;
+ char retrieved_str[255];
+
+ ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str);
+ /*
+ return values for "sng_isdn_retrieve_facility_information_following":
+ If there will be no information following, or fails to decode IE, returns -1
+ If there will be no information following, but current FACILITY IE contains a caller name, returns 0
+ If there will be information following, returns 1
+ */
+
+ if (ret_val == 1) {
+ ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n");
+ ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID);
+ /* Launch timer in case we never get a FACILITY msg */
+ if (signal_data->facility_timeout) {
+ ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout,
+ sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
+ }
+ break;
+ } else if (ret_val == 0) {
+ strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
}
break;
- } else if (ret_val == 0) {
- strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
}
}
}
@@ -243,11 +255,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
uint8_t ces = sngisdn_event->ces;
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
-
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+ CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt;
- /* Function does not require any info from conStEvnt struct for now */
- /* CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; */
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
@@ -269,9 +279,11 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
switch(ftdmchan->state) {
+ case FTDM_CHANNEL_STATE_PROCEED:
case FTDM_CHANNEL_STATE_PROGRESS:
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
case FTDM_CHANNEL_STATE_DIALING:
+ get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
break;
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
@@ -335,9 +347,13 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
suId, suInstId, spInstId, ces);
switch(evntType) {
+ case MI_CALLPROC:
case MI_PROGRESS:
- if (signal_data->switchtype == SNGISDN_SWITCH_NI2 &&
- cnStEvnt->causeDgn[0].eh.pres && cnStEvnt->causeDgn[0].causeVal.pres) {
+ case MI_ALERTING:
+ get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd);
+
+ if (signal_data->ignore_cause_value != SNGISDN_OPT_TRUE &&
+ cnStEvnt->causeDgn[0].eh.pres && cnStEvnt->causeDgn[0].causeVal.pres) {
switch(cnStEvnt->causeDgn[0].causeVal.val) {
case 17: /* User Busy */
@@ -362,22 +378,20 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
goto sngisdn_process_cnst_ind_end;
}
}
- /* fall-through */
- case MI_ALERTING:
- case MI_CALLPROC:
-
+
switch(ftdmchan->state) {
- case FTDM_CHANNEL_STATE_DIALING:
- if (evntType == MI_PROGRESS ||
- (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL)) {
+ case FTDM_CHANNEL_STATE_DIALING:
+ case FTDM_CHANNEL_STATE_PROCEED:
+ if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+ } else if (evntType == MI_CALLPROC) {
+ ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED);
} else {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
}
break;
case FTDM_CHANNEL_STATE_PROGRESS:
- if (evntType == MI_PROGRESS ||
- (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL)) {
+ if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
}
break;
@@ -406,7 +420,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
ftdm_size_t min_digits = ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->min_digits;
ftdm_size_t num_digits;
- cpy_called_num_from_stack(&ftdmchan->caller_data, &cnStEvnt->cdPtyNmb);
+ get_called_num(ftdmchan, &cnStEvnt->cdPtyNmb);
num_digits = strlen(ftdmchan->caller_data.dnis.digits);
if (cnStEvnt->sndCmplt.eh.pres || num_digits >= min_digits) {
@@ -417,6 +431,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
}
break;
case FTDM_CHANNEL_STATE_RING:
+ case FTDM_CHANNEL_STATE_PROCEED:
case FTDM_CHANNEL_STATE_PROGRESS:
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
case FTDM_CHANNEL_STATE_UP:
@@ -446,6 +461,7 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
uint32_t spInstId = sngisdn_event->spInstId;
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
+ sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
DiscEvnt *discEvnt = &sngisdn_event->event.discEvnt;
@@ -454,12 +470,20 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
- switch (ftdmchan->state) {
+ switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_RING:
case FTDM_CHANNEL_STATE_DIALING:
+ case FTDM_CHANNEL_STATE_PROCEED:
case FTDM_CHANNEL_STATE_PROGRESS:
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
- case FTDM_CHANNEL_STATE_UP:
+ case FTDM_CHANNEL_STATE_UP:
+ if (discEvnt->facilityStr.eh.pres) {
+ if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) {
+ get_facility_ie(ftdmchan, &discEvnt->facilityStr);
+ } else {
+ /* Call libsng_isdn facility decode function and copy variables here */
+ }
+ }
if (discEvnt->causeDgn[0].eh.pres && discEvnt->causeDgn[0].causeVal.pres) {
ftdmchan->caller_data.hangup_cause = discEvnt->causeDgn[0].causeVal.val;
} else {
@@ -503,6 +527,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
uint32_t spInstId = sngisdn_event->spInstId;
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
+ sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
RelEvnt *relEvnt = &sngisdn_event->event.relEvnt;
@@ -535,9 +560,10 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
case FTDM_CHANNEL_STATE_DIALING:
/* Remote side rejected our SETUP message on outbound call */
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
- sng_isdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
+ sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
}
/* fall-through */
+ case FTDM_CHANNEL_STATE_PROCEED:
case FTDM_CHANNEL_STATE_PROGRESS:
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
case FTDM_CHANNEL_STATE_UP:
@@ -547,6 +573,15 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
not changed while we were waiting for ftdmchan->mutex by comparing suInstId's */
if (((sngisdn_chan_data_t*)ftdmchan->call_data)->suInstId == suInstId ||
((sngisdn_chan_data_t*)ftdmchan->call_data)->spInstId == spInstId) {
+
+ if (relEvnt->facilityStr.eh.pres) {
+ if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) {
+ get_facility_ie(ftdmchan, &relEvnt->facilityStr);
+ } else {
+ /* Call libsng_isdn facility decode function and copy variables here */
+ }
+ }
+
if (relEvnt->causeDgn[0].eh.pres && relEvnt->causeDgn[0].causeVal.pres) {
ftdmchan->caller_data.hangup_cause = relEvnt->causeDgn[0].causeVal.val;
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "cause:%d\n", ftdmchan->caller_data.hangup_cause);
@@ -725,15 +760,16 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_GET_CALLERID:
/* Update the caller ID Name */
+
if (facEvnt->facElmt.facStr.pres) {
char retrieved_str[255];
-
+
/* return values for "sng_isdn_retrieve_facility_information_following":
If there will be no information following, or fails to decode IE, returns -1
If there will be no information following, but current FACILITY IE contains a caller name, returns 0
If there will be information following, returns 1
*/
-
+
if (sng_isdn_retrieve_facility_caller_name(&facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len, retrieved_str) == 0) {
strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
} else {
@@ -751,6 +787,25 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
/* We received the caller ID Name in FACILITY, but its too late, facility-timeout already occurred */
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "FACILITY received, but we already proceeded with call\n");
break;
+ case FTDM_CHANNEL_STATE_UP:
+ {
+ ftdm_sigmsg_t sigev;
+ if (facEvnt->facElmt.facStr.pres) {
+ if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) {
+ get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len);
+ } else {
+ /* Call libsng_isdn facility decode function and copy variables here */
+ }
+ }
+ memset(&sigev, 0, sizeof(sigev));
+ sigev.chan_id = ftdmchan->chan_id;
+ sigev.span_id = ftdmchan->span_id;
+ sigev.channel = ftdmchan;
+
+ sigev.event_id = FTDM_SIGEVENT_MSG;
+ ftdm_span_send_signal(ftdmchan->span, &sigev);
+ }
+ break;
default:
/* We do not support other FACILITY types for now, so do nothing */
break;
@@ -865,6 +920,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T302 Timer expired, proceeding with call\n");
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
break;
+ case FTDM_CHANNEL_STATE_PROCEED:
case FTDM_CHANNEL_STATE_PROGRESS:
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Remote switch expecting OVERLAP receive, but we are already PROCEEDING\n");
@@ -882,6 +938,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
break;
case 3:
switch (ftdmchan->state) {
+ case FTDM_CHANNEL_STATE_PROCEED:
case FTDM_CHANNEL_STATE_PROGRESS:
/* T310 timer has expired */
ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val;
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
index cb508a54b4..08b14a08ce 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
@@ -34,18 +34,12 @@
#include "ftmod_sangoma_isdn.h"
-void sngisdn_snd_setup(ftdm_channel_t *ftdmchan);
-void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan);
-void sngisdn_snd_progress(ftdm_channel_t *ftdmchan);
-void sngisdn_snd_connect(ftdm_channel_t *ftdmchan);
-void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan);
-void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare);
-
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
{
- ConEvnt conEvnt;
+ ConEvnt conEvnt;
sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
- sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
+ sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
+ ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
ftdm_assert((!sngisdn_info->suInstId && !sngisdn_info->spInstId), "Trying to call out, but call data was not cleared\n");
@@ -123,14 +117,6 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
conEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
}
- conEvnt.progInd.eh.pres = PRSNT_NODEF;
- conEvnt.progInd.location.pres = PRSNT_NODEF;
- conEvnt.progInd.location.val = IN_LOC_USER;
- conEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
- conEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
- conEvnt.progInd.progDesc.pres = PRSNT_NODEF;
- conEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN; /* Not end-to-end ISDN */
-
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
conEvnt.sndCmplt.eh.pres = PRSNT_NODEF;
}
@@ -140,10 +126,13 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
}
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Outgoing call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
- cpy_called_num_from_user(&conEvnt.cdPtyNmb, &ftdmchan->caller_data);
- cpy_calling_num_from_user(&conEvnt.cgPtyNmb, &ftdmchan->caller_data);
- cpy_redir_num_from_user(&conEvnt.redirNmb, &ftdmchan->caller_data);
- cpy_calling_name_from_user(&conEvnt, ftdmchan);
+ set_called_num(ftdmchan, &conEvnt.cdPtyNmb);
+ set_calling_num(ftdmchan, &conEvnt.cgPtyNmb);
+ set_calling_subaddr(ftdmchan, &conEvnt.cgPtySad);
+ set_redir_num(ftdmchan, &conEvnt.redirNmb);
+ set_calling_name(ftdmchan, &conEvnt);
+ set_facility_ie(ftdmchan, &conEvnt.facilityStr);
+ set_prog_ind_ie(ftdmchan, &conEvnt.progInd, prog_ind);
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
@@ -330,14 +319,14 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan)
return;
}
-void sngisdn_snd_progress(ftdm_channel_t *ftdmchan)
+void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind)
{
CnStEvnt cnStEvnt;
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
- if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
+ if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending PROGRESS, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
@@ -351,14 +340,7 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan)
}
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
-
- cnStEvnt.progInd.eh.pres = PRSNT_NODEF;
- cnStEvnt.progInd.location.pres = PRSNT_NODEF;
- cnStEvnt.progInd.location.val = IN_LOC_USER;
- cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
- cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
- cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF;
- cnStEvnt.progInd.progDesc.val = IN_PD_IBAVAIL;
+ set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, signal_data->dchan_id, sngisdn_info->ces)) {
@@ -367,14 +349,14 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan)
return;
}
-void sngisdn_snd_alert(ftdm_channel_t *ftdmchan)
+void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind)
{
CnStEvnt cnStEvnt;
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
- if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
+ if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending ALERT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
@@ -383,13 +365,7 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan)
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
- cnStEvnt.progInd.eh.pres = PRSNT_NODEF;
- cnStEvnt.progInd.location.pres = PRSNT_NODEF;
- cnStEvnt.progInd.location.val = IN_LOC_USER;
- cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
- cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
- cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF;
- cnStEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN;
+ set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending ALERT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
@@ -401,10 +377,10 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan)
void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
{
- CnStEvnt cnStEvnt;
-
+ CnStEvnt cnStEvnt;
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
+ ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending CONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
@@ -415,7 +391,6 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
-
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
@@ -447,14 +422,8 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
cnStEvnt.chanId.chanNmbSlotMap.len = 1;
cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
}
-
- cnStEvnt.progInd.eh.pres = PRSNT_NODEF;
- cnStEvnt.progInd.location.pres = PRSNT_NODEF;
- cnStEvnt.progInd.location.val = IN_LOC_USER;
- cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
- cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
- cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF;
- cnStEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN; /* Not end-to-end ISDN */
+
+ set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) {
@@ -463,6 +432,32 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
return;
}
+void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan)
+{
+ FacEvnt facEvnt;
+
+ sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
+ sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
+
+ if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
+ ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending FACILITY, but no call data, ignoring (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
+ return;
+ }
+
+ memset(&facEvnt, 0, sizeof(facEvnt));
+
+ set_facility_ie_str(ftdmchan, &facEvnt.facElmt.facStr.val[2], (ftdm_size_t*)&facEvnt.facElmt.facStr.len);
+
+ facEvnt.facElmt.facStr.val[0] = 0x1C;
+ facEvnt.facElmt.facStr.val[1] = facEvnt.facElmt.facStr.len;
+
+ ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending FACILITY (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
+
+ if (sng_isdn_facility_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &facEvnt, MI_FACIL, signal_data->dchan_id, sngisdn_info->ces)) {
+ ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused FACILITY request\n");
+ }
+ return;
+}
void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan)
{
@@ -517,7 +512,7 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
- if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
+ if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending DISCONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
@@ -538,6 +533,8 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
discEvnt.causeDgn[0].recommend.pres = NOTPRSNT;
discEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT;
+ set_facility_ie(ftdmchan, &discEvnt.facilityStr);
+
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
if (sng_isdn_disc_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &discEvnt)) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused DISCONNECT request\n");
@@ -582,6 +579,8 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
spInstId = sngisdn_info->spInstId;
}
+ set_facility_ie(ftdmchan, &relEvnt.facilityStr);
+
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RELEASE/RELEASE COMPLETE (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, suInstId, spInstId);
if (glare) {
@@ -597,6 +596,74 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
}
+/* We received an incoming frame on the d-channel, send data to the stack */
+void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)
+{
+ sng_l1_frame_t l1_frame;
+ sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data;
+
+ memset(&l1_frame, 0, sizeof(l1_frame));
+ l1_frame.len = len;
+
+ memcpy(&l1_frame.data, data, len);
+
+ if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_CRC)) {
+ l1_frame.flags |= SNG_L1FRAME_ERROR_CRC;
+ }
+
+ if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_FRAME)) {
+ l1_frame.flags |= SNG_L1FRAME_ERROR_FRAME;
+ }
+
+ if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_ABORT)) {
+ l1_frame.flags |= SNG_L1FRAME_ERROR_ABORT;
+ }
+
+ if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_FIFO)) {
+ l1_frame.flags |= SNG_L1FRAME_ERROR_FIFO;
+ }
+
+ if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_DMA)) {
+ l1_frame.flags |= SNG_L1FRAME_ERROR_DMA;
+ }
+
+ if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)) {
+ /* Should we trigger congestion here? */
+ l1_frame.flags |= SNG_L1FRAME_QUEUE_THRES;
+ }
+
+ if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL)) {
+ /* Should we trigger congestion here? */
+ l1_frame.flags |= SNG_L1FRAME_QUEUE_FULL;
+ }
+
+ sng_isdn_data_ind(signal_data->link_id, &l1_frame);
+}
+
+void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event)
+{
+ sng_l1_event_t l1_event;
+ sngisdn_span_data_t *signal_data = NULL;
+ memset(&l1_event, 0, sizeof(l1_event));
+
+
+ signal_data = (sngisdn_span_data_t*) dchan->span->signal_data;
+ switch(event) {
+ case FTDM_OOB_ALARM_CLEAR:
+ l1_event.type = SNG_L1EVENT_ALARM_OFF;
+ sng_isdn_event_ind(signal_data->link_id, &l1_event);
+ break;
+ case FTDM_OOB_ALARM_TRAP:
+ l1_event.type = SNG_L1EVENT_ALARM_ON;
+ sng_isdn_event_ind(signal_data->link_id, &l1_event);
+ break;
+ default:
+ /* We do not care about the other OOB events for now */
+ return;
+ }
+ return;
+}
+
/* For Emacs:
* Local Variables:
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c
index 7c375f7c64..af180d1f7c 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c
@@ -732,7 +732,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP);
- sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
+ sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
} else {
ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n",
status->t.usta.suId,
@@ -741,7 +741,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN);
- sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
+ sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
}
}
break;
@@ -862,6 +862,82 @@ end_of_trace:
return;
}
+/* The stacks is wants to transmit a frame */
+int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame)
+{
+ ftdm_status_t status;
+ ftdm_wait_flag_t flags = FTDM_WRITE;
+ sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId];
+ ftdm_size_t length = l1_frame->len;
+
+ ftdm_assert(signal_data, "Received Data request on unconfigured span\n");
+
+ do {
+ flags = FTDM_WRITE;
+ status = signal_data->dchan->fio->wait(signal_data->dchan, &flags, 1000);
+ if (status != FTDM_SUCCESS) {
+ ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_WARNING, "transmit timed-out\n");
+ return -1;
+ }
+
+
+ if ((flags & FTDM_WRITE)) {
+ status = signal_data->dchan->fio->write(signal_data->dchan, l1_frame->data, (ftdm_size_t*)&length);
+ if (status != FTDM_SUCCESS) {
+ ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_CRIT, "Failed to transmit frame\n");
+ return -1;
+ }
+ break;
+ /* On WIN32, it is possible for poll to return without FTDM_WRITE flag set, so we try to retransmit */
+#ifndef WIN32
+ } else {
+ ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_WARNING, "Failed to poll for d-channel\n");
+ return -1;
+#endif
+ }
+ } while(1);
+ return 0;
+}
+
+int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd)
+{
+ sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId];
+ ftdm_assert(signal_data, "Received Data request on unconfigured span\n");
+
+ switch(l1_cmd->type) {
+ case SNG_L1CMD_SET_LINK_STATUS:
+ {
+ ftdm_channel_hw_link_status_t status = FTDM_HW_LINK_CONNECTED;
+ ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_SET_LINK_STATUS, &status);
+ }
+ break;
+ case SNG_L1CMD_GET_LINK_STATUS:
+ {
+ ftdm_channel_hw_link_status_t status = 0;
+ ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_GET_LINK_STATUS, &status);
+ if (status == FTDM_HW_LINK_CONNECTED) {
+ l1_cmd->cmd.status = 1;
+ } else if (status == FTDM_HW_LINK_DISCONNECTED) {
+ l1_cmd->cmd.status = 0;
+ } else {
+ ftdm_log_chan(signal_data->dchan, FTDM_LOG_CRIT, "Invalid link status reported %d\n", status);
+ l1_cmd->cmd.status = 0;
+ }
+ }
+ break;
+ case SNG_L1CMD_FLUSH_STATS:
+ ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_FLUSH_IOSTATS, NULL);
+ break;
+ case SNG_L1CMD_FLUSH_BUFFERS:
+ ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_FLUSH_BUFFERS, NULL);
+ break;
+ default:
+ ftdm_log_chan(signal_data->dchan, FTDM_LOG_CRIT, "Unsupported channel command:%d\n", l1_cmd->type);
+ return -1;
+ }
+ return 0;
+}
+
void sngisdn_rcv_sng_assert(char *message)
{
ftdm_assert(0, message);
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c
index 7322aeddaa..42bcd1e20a 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c
@@ -33,13 +33,22 @@
*/
#include "ftmod_sangoma_isdn.h"
+#define SNGISDN_Q931_FACILITY_IE_ID 0x1C
+
+/* ftmod_sangoma_isdn specific enum look-up functions */
+
+SNGISDN_ENUM_NAMES(SNGISDN_PROGIND_DESCR_NAMES, SNGISDN_PROGIND_DESCR_STRINGS)
+SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_descr, ftdm_sngisdn_progind_descr2str, ftdm_sngisdn_progind_descr_t, SNGISDN_PROGIND_DESCR_NAMES, SNGISDN_PROGIND_DESCR_INVALID)
+
+SNGISDN_ENUM_NAMES(SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_STRINGS)
+SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t, SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_INVALID)
ftdm_status_t sngisdn_check_free_ids(void);
extern ftdm_sngisdn_data_t g_sngisdn_data;
void get_memory_info(void);
-FT_DECLARE(void) clear_call_data(sngisdn_chan_data_t *sngisdn_info)
+void clear_call_data(sngisdn_chan_data_t *sngisdn_info)
{
uint32_t cc_id = ((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->cc_id;
@@ -56,7 +65,7 @@ FT_DECLARE(void) clear_call_data(sngisdn_chan_data_t *sngisdn_info)
return;
}
-FT_DECLARE(void) clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
+void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
{
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Clearing glare data (suId:%d suInstId:%u spInstId:%u actv-suInstId:%u actv-spInstId:%u)\n",
sngisdn_info->glare.suId,
@@ -81,7 +90,7 @@ FT_DECLARE(void) clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
}
-FT_DECLARE(uint32_t) get_unique_suInstId(int16_t cc_id)
+uint32_t get_unique_suInstId(int16_t cc_id)
{
uint32_t suInstId;
ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n");
@@ -103,7 +112,7 @@ FT_DECLARE(uint32_t) get_unique_suInstId(int16_t cc_id)
return 0;
}
-FT_DECLARE(ftdm_status_t) get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data)
+ftdm_status_t get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data)
{
ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n");
ftdm_assert_return(g_sngisdn_data.ccs[cc_id].activation_done, FTDM_FAIL, "Trying to find call on unconfigured CC\n");
@@ -115,7 +124,7 @@ FT_DECLARE(ftdm_status_t) get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suIns
return FTDM_SUCCESS;
}
-FT_DECLARE(ftdm_status_t) get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data)
+ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data)
{
ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n");
ftdm_assert_return(g_sngisdn_data.ccs[cc_id].activation_done, FTDM_FAIL, "Trying to find call on unconfigured CC\n");
@@ -127,9 +136,8 @@ FT_DECLARE(ftdm_status_t) get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spIns
return FTDM_SUCCESS;
}
-ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
+ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
{
-
if (span->trunk_type == FTDM_TRUNK_BRI ||
span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
@@ -147,77 +155,84 @@ ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
return FTDM_SUCCESS;
}
-FT_DECLARE(ftdm_status_t) cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb)
+ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
{
+ ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
if (cgPtyNmb->eh.pres != PRSNT_NODEF) {
return FTDM_FAIL;
}
if (cgPtyNmb->screenInd.pres == PRSNT_NODEF) {
- ftdm->screen = cgPtyNmb->screenInd.val;
+ caller_data->screen = cgPtyNmb->screenInd.val;
}
if (cgPtyNmb->presInd0.pres == PRSNT_NODEF) {
- ftdm->pres = cgPtyNmb->presInd0.val;
+ caller_data->pres = cgPtyNmb->presInd0.val;
}
if (cgPtyNmb->nmbPlanId.pres == PRSNT_NODEF) {
- ftdm->cid_num.plan = cgPtyNmb->nmbPlanId.val;
+ caller_data->cid_num.plan = cgPtyNmb->nmbPlanId.val;
}
+
if (cgPtyNmb->typeNmb1.pres == PRSNT_NODEF) {
- ftdm->cid_num.type = cgPtyNmb->typeNmb1.val;
+ caller_data->cid_num.type = cgPtyNmb->typeNmb1.val;
}
if (cgPtyNmb->nmbDigits.pres == PRSNT_NODEF) {
- ftdm_copy_string(ftdm->cid_num.digits, (const char*)cgPtyNmb->nmbDigits.val, cgPtyNmb->nmbDigits.len+1);
+ ftdm_copy_string(caller_data->cid_num.digits, (const char*)cgPtyNmb->nmbDigits.val, cgPtyNmb->nmbDigits.len+1);
}
+ memcpy(&caller_data->ani, &caller_data->cid_num, sizeof(caller_data->ani));
return FTDM_SUCCESS;
}
-FT_DECLARE(ftdm_status_t) cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb)
+ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb)
{
+ ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
if (cdPtyNmb->eh.pres != PRSNT_NODEF) {
return FTDM_FAIL;
}
if (cdPtyNmb->nmbPlanId.pres == PRSNT_NODEF) {
- ftdm->dnis.plan = cdPtyNmb->nmbPlanId.val;
+ caller_data->dnis.plan = cdPtyNmb->nmbPlanId.val;
}
if (cdPtyNmb->typeNmb0.pres == PRSNT_NODEF) {
- ftdm->dnis.type = cdPtyNmb->typeNmb0.val;
+ caller_data->dnis.type = cdPtyNmb->typeNmb0.val;
}
if (cdPtyNmb->nmbDigits.pres == PRSNT_NODEF) {
- unsigned i = strlen(ftdm->dnis.digits);
+ /* In overlap receive mode, append the new digits to the existing dnis */
+ unsigned i = strlen(caller_data->dnis.digits);
- ftdm_copy_string(&ftdm->dnis.digits[i], (const char*)cdPtyNmb->nmbDigits.val, cdPtyNmb->nmbDigits.len+1);
+ ftdm_copy_string(&caller_data->dnis.digits[i], (const char*)cdPtyNmb->nmbDigits.val, cdPtyNmb->nmbDigits.len+1);
}
return FTDM_SUCCESS;
}
-FT_DECLARE(ftdm_status_t) cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb)
+ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb)
{
+ ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
if (redirNmb->eh.pres != PRSNT_NODEF) {
return FTDM_FAIL;
}
if (redirNmb->nmbPlanId.pres == PRSNT_NODEF) {
- ftdm->rdnis.plan = redirNmb->nmbPlanId.val;
+ caller_data->rdnis.plan = redirNmb->nmbPlanId.val;
}
if (redirNmb->typeNmb.pres == PRSNT_NODEF) {
- ftdm->rdnis.type = redirNmb->typeNmb.val;
+ caller_data->rdnis.type = redirNmb->typeNmb.val;
}
if (redirNmb->nmbDigits.pres == PRSNT_NODEF) {
- ftdm_copy_string(ftdm->rdnis.digits, (const char*)redirNmb->nmbDigits.val, redirNmb->nmbDigits.len+1);
+ ftdm_copy_string(caller_data->rdnis.digits, (const char*)redirNmb->nmbDigits.val, redirNmb->nmbDigits.len+1);
}
return FTDM_SUCCESS;
}
-FT_DECLARE(ftdm_status_t) cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display)
+ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *display)
{
+ ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
if (display->eh.pres != PRSNT_NODEF) {
return FTDM_FAIL;
}
@@ -225,71 +240,209 @@ FT_DECLARE(ftdm_status_t) cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm,
return FTDM_FAIL;
}
- ftdm_copy_string(ftdm->cid_name, (const char*)display->dispInfo.val, display->dispInfo.len+1);
+ ftdm_copy_string(caller_data->cid_name, (const char*)display->dispInfo.val, display->dispInfo.len+1);
return FTDM_SUCCESS;
}
-FT_DECLARE(ftdm_status_t) cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm)
+ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr)
{
- uint8_t len = strlen(ftdm->cid_num.digits);
+ ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
+ if (usrUsr->eh.pres != PRSNT_NODEF) {
+ return FTDM_FAIL;
+ }
+
+ if (usrUsr->protocolDisc.val != PD_IA5) {
+ return FTDM_FAIL;
+ }
+
+ if (usrUsr->usrInfo.pres != PRSNT_NODEF) {
+ return FTDM_FAIL;
+ }
+
+ ftdm_copy_string(caller_data->cid_name, (const char*)usrUsr->usrInfo.val, usrUsr->usrInfo.len+1);
+ return FTDM_SUCCESS;
+}
+
+ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
+{
+ char subaddress[100];
+
+ if (cgPtySad->eh.pres != PRSNT_NODEF) {
+ return FTDM_FAIL;
+ }
+ memset(subaddress, 0, sizeof(subaddress));
+ if(cgPtySad->sadInfo.len >= sizeof(subaddress)) {
+ ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Calling Party Subaddress exceeds local size limit (len:%d max:%d)\n", cgPtySad->sadInfo.len, sizeof(subaddress));
+ cgPtySad->sadInfo.len = sizeof(subaddress)-1;
+ }
+
+ memcpy(subaddress, (char*)cgPtySad->sadInfo.val, cgPtySad->sadInfo.len);
+ subaddress[cgPtySad->sadInfo.len] = '\0';
+ ftdm_channel_add_var(ftdmchan, "isdn.calling_subaddr", subaddress);
+ return FTDM_SUCCESS;
+}
+
+ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr)
+{
+ if (!facilityStr->eh.pres) {
+ return FTDM_FAIL;
+ }
+
+ return get_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, facilityStr->facilityStr.len);
+}
+
+ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t data_len)
+{
+ ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
+ if (data_len > sizeof(caller_data->raw_data)-2) {
+ ftdm_log(FTDM_LOG_CRIT, "Length of Facility IE exceeds maximum length\n");
+ return FTDM_FAIL;
+ }
+
+ memset(caller_data->raw_data, 0, sizeof(caller_data->raw_data));
+ /* Always include Facility IE identifier + len so this can be used as a sanity check by the user */
+ caller_data->raw_data[0] = SNGISDN_Q931_FACILITY_IE_ID;
+ caller_data->raw_data[1] = data_len;
+
+ memcpy(&caller_data->raw_data[2], data, data_len);
+ caller_data->raw_data_len = data_len+2;
+ return FTDM_SUCCESS;
+}
+
+ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd)
+{
+ uint8_t val;
+ if (!progInd->eh.pres) {
+ return FTDM_FAIL;
+ }
+
+ if (progInd->progDesc.pres) {
+ switch (progInd->progDesc.val) {
+ case IN_PD_NOTETEISDN:
+ val = SNGISDN_PROGIND_DESCR_NETE_ISDN;
+ break;
+ case IN_PD_DSTNOTISDN:
+ val = SNGISDN_PROGIND_DESCR_DEST_NISDN;
+ break;
+ case IN_PD_ORGNOTISDN:
+ val = SNGISDN_PROGIND_DESCR_ORIG_NISDN;
+ break;
+ case IN_PD_CALLRET:
+ val = SNGISDN_PROGIND_DESCR_RET_ISDN;
+ break;
+ case IN_PD_DELRESP:
+ val = SNGISDN_PROGIND_DESCR_SERV_CHANGE;
+ break;
+ case IN_PD_IBAVAIL:
+ val = SNGISDN_PROGIND_DESCR_IB_AVAIL;
+ break;
+ default:
+ ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unknown Progress Indicator Description (%d)\n", progInd->progDesc.val);
+ val = SNGISDN_PROGIND_DESCR_INVALID;
+ break;
+ }
+ ftdm_channel_add_var(ftdmchan, "isdn.prog_ind.descr", ftdm_sngisdn_progind_descr2str(val));
+ }
+
+ if (progInd->location.pres) {
+ switch (progInd->location.val) {
+ case IN_LOC_USER:
+ val = SNGISDN_PROGIND_LOC_USER;
+ break;
+ case IN_LOC_PRIVNETLU:
+ val = SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR;
+ break;
+ case IN_LOC_PUBNETLU:
+ val = SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR;
+ break;
+ case IN_LOC_TRANNET:
+ val = SNGISDN_PROGIND_LOC_TRANSIT_NET;
+ break;
+ case IN_LOC_PUBNETRU:
+ val = SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR;
+ break;
+ case IN_LOC_PRIVNETRU:
+ val = SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR;
+ break;
+ case IN_LOC_NETINTER:
+ val = SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW;
+ break;
+ default:
+ ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unknown Progress Indicator Location (%d)", progInd->location.val);
+ val = SNGISDN_PROGIND_LOC_INVALID;
+ break;
+ }
+ ftdm_channel_add_var(ftdmchan, "isdn.prog_ind.loc", ftdm_sngisdn_progind_loc2str(val));
+ }
+ return FTDM_SUCCESS;
+}
+
+
+ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
+{
+ ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
+ uint8_t len = strlen(caller_data->cid_num.digits);
if (!len) {
return FTDM_SUCCESS;
}
cgPtyNmb->eh.pres = PRSNT_NODEF;
cgPtyNmb->screenInd.pres = PRSNT_NODEF;
- cgPtyNmb->screenInd.val = ftdm->screen;
+ cgPtyNmb->screenInd.val = caller_data->screen;
cgPtyNmb->presInd0.pres = PRSNT_NODEF;
- cgPtyNmb->presInd0.val = ftdm->pres;
-
+ cgPtyNmb->presInd0.val = caller_data->pres;
+
cgPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
- cgPtyNmb->nmbPlanId.val = ftdm->cid_num.plan;
+ cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan;
cgPtyNmb->typeNmb1.pres = PRSNT_NODEF;
- cgPtyNmb->typeNmb1.val = ftdm->cid_num.type;
+ cgPtyNmb->typeNmb1.val = caller_data->cid_num.type;
cgPtyNmb->nmbDigits.pres = PRSNT_NODEF;
cgPtyNmb->nmbDigits.len = len;
- memcpy(cgPtyNmb->nmbDigits.val, ftdm->cid_num.digits, len);
+ memcpy(cgPtyNmb->nmbDigits.val, caller_data->cid_num.digits, len);
return FTDM_SUCCESS;
}
-FT_DECLARE(ftdm_status_t) cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm)
+ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb)
{
- uint8_t len = strlen(ftdm->dnis.digits);
+ ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
+ uint8_t len = strlen(caller_data->dnis.digits);
+
if (!len) {
return FTDM_SUCCESS;
}
cdPtyNmb->eh.pres = PRSNT_NODEF;
cdPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
- if (ftdm->dnis.plan == FTDM_NPI_INVALID) {
+ if (caller_data->dnis.plan == FTDM_NPI_INVALID) {
cdPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
} else {
- cdPtyNmb->nmbPlanId.val = ftdm->dnis.plan;
+ cdPtyNmb->nmbPlanId.val = caller_data->dnis.plan;
}
cdPtyNmb->typeNmb0.pres = PRSNT_NODEF;
- if (ftdm->dnis.type == FTDM_TON_INVALID) {
+ if (caller_data->dnis.type == FTDM_TON_INVALID) {
cdPtyNmb->typeNmb0.val = FTDM_TON_UNKNOWN;
} else {
- cdPtyNmb->typeNmb0.val = ftdm->dnis.type;
+ cdPtyNmb->typeNmb0.val = caller_data->dnis.type;
}
cdPtyNmb->nmbDigits.pres = PRSNT_NODEF;
cdPtyNmb->nmbDigits.len = len;
- memcpy(cdPtyNmb->nmbDigits.val, ftdm->dnis.digits, len);
+ memcpy(cdPtyNmb->nmbDigits.val, caller_data->dnis.digits, len);
return FTDM_SUCCESS;
}
-FT_DECLARE(ftdm_status_t) cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm)
+ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb)
{
- uint8_t len = strlen(ftdm->rdnis.digits);
+ ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
+ uint8_t len = strlen(caller_data->rdnis.digits);
if (!len) {
return FTDM_SUCCESS;
}
@@ -297,36 +450,36 @@ FT_DECLARE(ftdm_status_t) cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_calle
redirNmb->eh.pres = PRSNT_NODEF;
redirNmb->nmbPlanId.pres = PRSNT_NODEF;
- if (ftdm->rdnis.plan == FTDM_NPI_INVALID) {
+ if (caller_data->rdnis.plan == FTDM_NPI_INVALID) {
redirNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
} else {
- redirNmb->nmbPlanId.val = ftdm->rdnis.plan;
+ redirNmb->nmbPlanId.val = caller_data->rdnis.plan;
}
redirNmb->typeNmb.pres = PRSNT_NODEF;
- if (ftdm->rdnis.type == FTDM_TON_INVALID) {
+ if (caller_data->rdnis.type == FTDM_TON_INVALID) {
redirNmb->typeNmb.val = FTDM_TON_UNKNOWN;
} else {
- redirNmb->typeNmb.val = ftdm->rdnis.type;
+ redirNmb->typeNmb.val = caller_data->rdnis.type;
}
redirNmb->nmbDigits.pres = PRSNT_NODEF;
redirNmb->nmbDigits.len = len;
- memcpy(redirNmb->nmbDigits.val, ftdm->rdnis.digits, len);
+ memcpy(redirNmb->nmbDigits.val, caller_data->rdnis.digits, len);
return FTDM_SUCCESS;
}
-FT_DECLARE(ftdm_status_t) cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan)
+ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt)
{
uint8_t len;
- ftdm_caller_data_t *ftdm = &ftdmchan->caller_data;
+ ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
/* sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; */
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
- len = strlen(ftdm->cid_name);
+ len = strlen(caller_data->cid_name);
if (!len) {
return FTDM_SUCCESS;
}
@@ -341,7 +494,7 @@ FT_DECLARE(ftdm_status_t) cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_chan
conEvnt->usrUsr.usrInfo.len = len;
/* in sangoma_brid we used to send usr-usr info as !,
change to previous style if current one does not work */
- memcpy(conEvnt->usrUsr.usrInfo.val, ftdm->cid_name, len);
+ memcpy(conEvnt->usrUsr.usrInfo.val, caller_data->cid_name, len);
} else {
switch (signal_data->switchtype) {
case SNGISDN_SWITCH_NI2:
@@ -359,7 +512,7 @@ FT_DECLARE(ftdm_status_t) cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_chan
conEvnt->display.eh.pres = PRSNT_NODEF;
conEvnt->display.dispInfo.pres = PRSNT_NODEF;
conEvnt->display.dispInfo.len = len;
- memcpy(conEvnt->display.dispInfo.val, ftdm->cid_name, len);
+ memcpy(conEvnt->display.dispInfo.val, caller_data->cid_name, len);
break;
case SNGISDN_SWITCH_QSIG:
/* It seems like QSIG does not support Caller ID Name */
@@ -372,6 +525,139 @@ FT_DECLARE(ftdm_status_t) cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_chan
return FTDM_SUCCESS;
}
+ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
+{
+ const char* clg_subaddr = NULL;
+ clg_subaddr = ftdm_channel_get_var(ftdmchan, "isdn.calling_subaddr");
+ if ((clg_subaddr != NULL) && (*clg_subaddr)) {
+ unsigned len = strlen (clg_subaddr);
+ cgPtySad->eh.pres = PRSNT_NODEF;
+ cgPtySad->typeSad.pres = 1;
+ cgPtySad->typeSad.val = 0; /* NSAP */
+ cgPtySad->oddEvenInd.pres = 1;
+ cgPtySad->oddEvenInd.val = 0;
+
+ ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Calling Party Subaddress:%s\n", clg_subaddr);
+ cgPtySad->sadInfo.pres = 1;
+ cgPtySad->sadInfo.len = len;
+ memcpy(cgPtySad->sadInfo.val, clg_subaddr, len);
+ }
+ return FTDM_SUCCESS;
+}
+
+
+ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr)
+{
+ ftdm_status_t status;
+ status = set_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, (ftdm_size_t*)&facilityStr->facilityStr.len);
+ if (status == FTDM_SUCCESS) {
+ facilityStr->eh.pres = PRSNT_NODEF;
+ facilityStr->facilityStr.pres = PRSNT_NODEF;
+ }
+ return status;
+}
+
+ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t *data_len)
+{
+ ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
+
+ if (caller_data->raw_data_len > 0 && caller_data->raw_data[0] == SNGISDN_Q931_FACILITY_IE_ID) {
+
+ *data_len = caller_data->raw_data[1];
+ memcpy(data, &caller_data->raw_data[2], *data_len);
+ return FTDM_SUCCESS;
+ }
+ return FTDM_FAIL;
+}
+
+ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind)
+{
+ const char *str = NULL;
+ int descr = prog_ind.descr;
+ int loc = prog_ind.loc;
+
+ str = ftdm_channel_get_var(ftdmchan, "isdn.prog_ind.descr");
+ if (str && *str) {
+ /* User wants to override progress indicator */
+ descr = ftdm_str2ftdm_sngisdn_progind_descr(str);
+ }
+
+ if (descr == SNGISDN_PROGIND_DESCR_INVALID) {
+ /* User does not want to send progress indicator */
+ return FTDM_SUCCESS;
+ }
+
+ str = ftdm_channel_get_var(ftdmchan, "isdn.prog_ind.loc");
+ if (str && *str) {
+ loc = ftdm_str2ftdm_sngisdn_progind_loc(str);
+ }
+ if (loc == SNGISDN_PROGIND_LOC_INVALID) {
+ loc = SNGISDN_PROGIND_LOC_USER;
+ }
+
+ progInd->eh.pres = PRSNT_NODEF;
+ progInd->codeStand0.pres = PRSNT_NODEF;
+ progInd->codeStand0.val = IN_CSTD_CCITT;
+
+ progInd->progDesc.pres = PRSNT_NODEF;
+ switch(descr) {
+ case SNGISDN_PROGIND_DESCR_NETE_ISDN:
+ progInd->progDesc.val = IN_PD_NOTETEISDN;
+ break;
+ case SNGISDN_PROGIND_DESCR_DEST_NISDN:
+ progInd->progDesc.val = IN_PD_DSTNOTISDN;
+ break;
+ case SNGISDN_PROGIND_DESCR_ORIG_NISDN:
+ progInd->progDesc.val = IN_PD_ORGNOTISDN;
+ break;
+ case SNGISDN_PROGIND_DESCR_RET_ISDN:
+ progInd->progDesc.val = IN_PD_CALLRET;
+ break;
+ case SNGISDN_PROGIND_DESCR_SERV_CHANGE:
+ /* Trillium defines do not match ITU-T Q931 Progress descriptions,
+ indicate a delayed response for now */
+ progInd->progDesc.val = IN_PD_DELRESP;
+ break;
+ case SNGISDN_PROGIND_DESCR_IB_AVAIL:
+ progInd->progDesc.val = IN_PD_IBAVAIL;
+ break;
+ default:
+ ftdm_log(FTDM_LOG_WARNING, "Invalid prog_ind description:%d\n", descr);
+ progInd->progDesc.val = IN_PD_NOTETEISDN;
+ break;
+ }
+
+ progInd->location.pres = PRSNT_NODEF;
+ switch (loc) {
+ case SNGISDN_PROGIND_LOC_USER:
+ progInd->location.val = IN_LOC_USER;
+ break;
+ case SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR:
+ progInd->location.val = IN_LOC_PRIVNETLU;
+ break;
+ case SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR:
+ progInd->location.val = IN_LOC_PUBNETLU;
+ break;
+ case SNGISDN_PROGIND_LOC_TRANSIT_NET:
+ progInd->location.val = IN_LOC_TRANNET;
+ break;
+ case SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR:
+ progInd->location.val = IN_LOC_PUBNETRU;
+ break;
+ case SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR:
+ progInd->location.val = IN_LOC_PRIVNETRU;
+ break;
+ case SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW:
+ progInd->location.val = IN_LOC_NETINTER;
+ break;
+ default:
+ ftdm_log(FTDM_LOG_WARNING, "Invalid prog_ind location:%d\n", loc);
+ progInd->location.val = IN_PD_NOTETEISDN;
+ }
+ return FTDM_SUCCESS;
+}
+
+
void sngisdn_t3_timeout(void* p_sngisdn_info)
{
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
@@ -394,6 +680,17 @@ void sngisdn_t3_timeout(void* p_sngisdn_info)
ftdm_mutex_unlock(ftdmchan->mutex);
}
+void sngisdn_delayed_setup(void* p_sngisdn_info)
+{
+ sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
+ ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
+
+ ftdm_mutex_lock(ftdmchan->mutex);
+ sngisdn_snd_setup(ftdmchan);
+ ftdm_mutex_unlock(ftdmchan->mutex);
+ return;
+}
+
void sngisdn_delayed_release(void* p_sngisdn_info)
{
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
@@ -517,13 +814,12 @@ uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability)
switch(bearer_capability) {
case FTDM_BEARER_CAP_SPEECH:
return IN_ITC_SPEECH;
-
case FTDM_BEARER_CAP_64K_UNRESTRICTED:
return IN_ITC_UNRDIG;
-
case FTDM_BEARER_CAP_3_1KHZ_AUDIO:
return IN_ITC_A31KHZ;
-
+ case FTDM_BEARER_CAP_INVALID:
+ return IN_ITC_SPEECH;
/* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
}
return FTDM_BEARER_CAP_SPEECH;
@@ -534,13 +830,12 @@ uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_pr
switch(layer1_prot) {
case FTDM_USER_LAYER1_PROT_V110:
return IN_UIL1_CCITTV110;
-
case FTDM_USER_LAYER1_PROT_ULAW:
return IN_UIL1_G711ULAW;
-
case FTDM_USER_LAYER1_PROT_ALAW:
return IN_UIL1_G711ALAW;
-
+ case FTDM_USER_LAYER1_PROT_INVALID:
+ return IN_UIL1_G711ULAW;
/* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
}
return IN_UIL1_G711ULAW;
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c
index 624d35c147..e5167164b3 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c
@@ -613,6 +613,21 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
return 0;
break;
case PROT_Q931_IE_CALLED_PARTY_SUBADDRESS:
+ {
+ uint8_t type;
+ uint8_t currentOct, j=0;
+ char calling_subaddr_string[82];
+ memset(calling_subaddr_string, 0, sizeof(calling_subaddr_string));
+ type = get_bits(OCTET(3),5,7);
+ currentOct = 3;
+ while(currentOct++ <= len+1) {
+ calling_subaddr_string[j++]=ia5[get_bits(OCTET(currentOct),1,4)][get_bits(OCTET(currentOct),5,8)];
+ }
+ calling_subaddr_string[j++]='\0';
+ *str_len += sprintf(&str[*str_len], "%s (l:%d) type:%s(%d) \n",
+ calling_subaddr_string, (j-1), get_code_2_str(type, dcodQ931TypeOfSubaddressTable), type);
+ }
+ break;
case PROT_Q931_IE_REDIRECTION_NUMBER:
case PROT_Q931_IE_NOTIFICATION_IND:
case PROT_Q931_IE_DATE_TIME:
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h
index d210c50db9..f054de9377 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h
@@ -544,5 +544,11 @@ struct code2str dcodQ931GenDigitsTypeTable[] = {
{-1, "Invalid"},
};
+struct code2str dcodQ931TypeOfSubaddressTable[] = {
+ { 0x00, "NSAP"},
+ { 0x02, "User-specified"},
+ { -1, "Invalid"},
+};
+
#endif /* __FTMOD_SANGOMA_ISDN_TRACE_H__ */
diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
index 8e8acc24e3..0ac628a260 100644
--- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
+++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
@@ -115,12 +115,16 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event);
static __inline__ int tdmv_api_wait_socket(ftdm_channel_t *ftdmchan, int timeout, int *flags)
{
-#ifdef LIBSANGOMA_VERSION
+#ifdef LIBSANGOMA_VERSION
int err;
uint32_t inflags = *flags;
uint32_t outflags = 0;
sangoma_wait_obj_t *sangoma_wait_obj = ftdmchan->io_data;
+ if (timeout == -1) {
+ timeout = SANGOMA_WAIT_INFINITE;
+ }
+
err = sangoma_waitfor(sangoma_wait_obj, inflags, &outflags, timeout);
*flags = 0;
if (err == SANG_STATUS_SUCCESS) {
@@ -169,7 +173,7 @@ static __inline__ sng_fd_t tdmv_api_open_span_chan(int span, int chan)
static __inline__ sng_fd_t __tdmv_api_open_span_chan(int span, int chan)
{
return __sangoma_open_tdmapi_span_chan(span, chan);
-}
+}
#endif
static ftdm_io_interface_t wanpipe_interface;
@@ -333,8 +337,8 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start
ftdm_log(FTDM_LOG_ERROR, "Failed to enable RBS/CAS events in device %d:%d fd:%d\n", chan->span_id, chan->chan_id, sockfd);
continue;
}
- /* probably done by the driver but lets write defensive code this time */
sangoma_flush_bufs(chan->sockfd, &tdm_api);
+ sangoma_flush_event_bufs(chan->sockfd, &tdm_api);
#else
/*
* With wanpipe 3.4.4.2 I get failure even though the events are enabled, /var/log/messages said:
@@ -513,10 +517,10 @@ static FIO_OPEN_FUNCTION(wanpipe_open)
wanpipe_tdm_api_t tdm_api;
memset(&tdm_api,0,sizeof(tdm_api));
+
sangoma_tdm_flush_bufs(ftdmchan->sockfd, &tdm_api);
-#ifdef LIBSANGOMA_VERSION
- sangoma_flush_event_bufs(ftdmchan->sockfd, &tdm_api);
-#endif
+ sangoma_flush_stats(ftdmchan->sockfd, &tdm_api);
+ memset(&ftdmchan->iostats, 0, sizeof(ftdmchan->iostats));
if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921 || ftdmchan->type == FTDM_CHAN_TYPE_DQ931) {
ftdmchan->native_codec = ftdmchan->effective_codec = FTDM_CODEC_NONE;
@@ -745,6 +749,29 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
}
}
break;
+ case FTDM_COMMAND_FLUSH_BUFFERS:
+ {
+ err = sangoma_flush_bufs(ftdmchan->sockfd, &tdm_api);
+ }
+ break;
+ case FTDM_COMMAND_FLUSH_IOSTATS:
+ {
+ err = sangoma_flush_stats(ftdmchan->sockfd, &tdm_api);
+ memset(&ftdmchan->iostats, 0, sizeof(ftdmchan->iostats));
+ }
+ break;
+ case FTDM_COMMAND_SET_RX_QUEUE_SIZE:
+ {
+ uint32_t queue_size = FTDM_COMMAND_OBJ_INT;
+ err = sangoma_set_rx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size);
+ }
+ break;
+ case FTDM_COMMAND_SET_TX_QUEUE_SIZE:
+ {
+ uint32_t queue_size = FTDM_COMMAND_OBJ_INT;
+ err = sangoma_set_tx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size);
+ }
+ break;
default:
break;
};
@@ -758,6 +785,106 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
return FTDM_SUCCESS;
}
+static void wanpipe_write_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_tx_hdr_t *tx_stats)
+{
+ ftdmchan->iostats.tx.errors = tx_stats->wp_api_tx_hdr_errors;
+ ftdmchan->iostats.tx.queue_size = tx_stats->wp_api_tx_hdr_max_queue_length;
+ ftdmchan->iostats.tx.queue_len = tx_stats->wp_api_tx_hdr_number_of_frames_in_queue;
+
+ /* we don't test for 80% full in tx since is typically full for voice channels, should we test tx 80% full for D-channels? */
+ if (ftdmchan->iostats.tx.queue_len >= ftdmchan->iostats.tx.queue_size) {
+ ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Tx Queue Full (%d/%d)\n",
+ ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.tx.queue_size);
+ ftdm_set_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
+ } else if (ftdm_test_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL)){
+ ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Tx Queue no longer full (%d/%d)\n",
+ ftdmchan->iostats.tx.queue_len, ftdmchan->iostats.tx.queue_size);
+ ftdm_clear_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
+ }
+
+ if (ftdmchan->iostats.tx.idle_packets < tx_stats->wp_api_tx_hdr_number_of_frames_in_queue) {
+ ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets;
+ /* HDLC channels do not always transmit, so its ok for drivers to fill with idle */
+ if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
+ ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx idle: %d\n", ftdmchan->iostats.tx.idle_packets);
+ }
+ }
+
+ if (!ftdmchan->iostats.tx.packets) {
+ ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "First packet write stats: Tx queue len: %d, Tx queue size: %d, Tx idle: %d\n",
+ ftdmchan->iostats.tx.queue_len,
+ ftdmchan->iostats.tx.queue_size,
+ ftdmchan->iostats.tx.idle_packets);
+ }
+
+ ftdmchan->iostats.tx.packets++;
+}
+
+static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx_stats)
+{
+ ftdmchan->iostats.rx.errors = rx_stats->wp_api_rx_hdr_errors;
+ ftdmchan->iostats.rx.queue_size = rx_stats->wp_api_rx_hdr_max_queue_length;
+ ftdmchan->iostats.rx.queue_len = rx_stats->wp_api_rx_hdr_number_of_frames_in_queue;
+
+ if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_ABORT_ERROR_BIT))) {
+ ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_ABORT);
+ } else {
+ ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_ABORT);
+ }
+
+ if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_DMA_ERROR_BIT))) {
+ ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_DMA);
+ } else {
+ ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_DMA);
+ }
+
+ if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_FIFO_ERROR_BIT))) {
+ ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FIFO);
+ } else {
+ ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FIFO);
+ }
+
+ if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_CRC_ERROR_BIT))) {
+ ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_CRC);
+ } else {
+ ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_CRC);
+ }
+
+ if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_FRAME_ERROR_BIT))) {
+ ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FRAME);
+ } else {
+ ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FRAME);
+ }
+
+ if (ftdmchan->iostats.rx.queue_len >= (0.8 * ftdmchan->iostats.rx.queue_size)) {
+ ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Rx Queue length exceeded 80% threshold (%d/%d)\n",
+ ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
+ ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
+ } else if (ftdm_test_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)){
+ /* any reason we have wanpipe_tdm_api_iface.h in ftmod_wanpipe/ dir? */
+ ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Rx Queue length reduced 80% threshold (%d/%d)\n",
+ ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
+ ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
+ }
+
+ if (ftdmchan->iostats.rx.queue_len >= ftdmchan->iostats.rx.queue_size) {
+ ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Rx Queue Full (%d/%d)\n",
+ ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
+ ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
+ } else if (ftdm_test_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL)){
+ ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Rx Queue no longer full (%d/%d)\n",
+ ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
+ ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
+ }
+
+ if (!ftdmchan->iostats.rx.packets) {
+ ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "First packet read stats: Rx queue len: %d, Rx queue size: %d\n",
+ ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
+ }
+
+ ftdmchan->iostats.rx.packets++;
+}
+
/**
* \brief Reads data from a Wanpipe channel
* \param ftdmchan Channel to read from
@@ -786,9 +913,11 @@ static FIO_READ_FUNCTION(wanpipe_read)
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno));
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read from sangoma device: %s (%d)\n", strerror(errno), rx_len);
return FTDM_FAIL;
- }
-
+ }
+ if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS)) {
+ wanpipe_read_stats(ftdmchan, &hdrframe);
+ }
return FTDM_SUCCESS;
}
@@ -814,6 +943,9 @@ static FIO_WRITE_FUNCTION(wanpipe_write)
/* should we be checking if bsent == *datalen here? */
if (bsent > 0) {
*datalen = bsent;
+ if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS)) {
+ wanpipe_write_stats(ftdmchan, &hdrframe);
+ }
return FTDM_SUCCESS;
}
diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ozmod_wanpipe.2005.vcproj b/libs/freetdm/src/ftmod/ftmod_wanpipe/ozmod_wanpipe.2005.vcproj
deleted file mode 100644
index abebf30427..0000000000
--- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ozmod_wanpipe.2005.vcproj
+++ /dev/null
@@ -1,196 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/wanpipe_tdm_api_iface.h b/libs/freetdm/src/ftmod/ftmod_wanpipe/wanpipe_tdm_api_iface.h
deleted file mode 100644
index 3801ff9c8c..0000000000
--- a/libs/freetdm/src/ftmod/ftmod_wanpipe/wanpipe_tdm_api_iface.h
+++ /dev/null
@@ -1,351 +0,0 @@
-/*****************************************************************************
-* wanpipe_tdm_api_iface.h
-*
-* WANPIPE(tm) AFT TE1 Hardware Support
-*
-* Authors: Nenad Corbic
-*
-* Copyright (c) 2007 - 08, Sangoma Technologies
-* 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 nor the
-* names of its contributors may be used to endorse or promote products
-* derived from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY ``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 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.
-
-* ============================================================================
-* Oct 04, 2005 Nenad Corbic Initial version.
-*
-* Jul 25, 2006 David Rokhvarg Ported to Windows.
-*****************************************************************************/
-
-#ifndef __WANPIPE_TDM_API_IFACE_H_
-#define __WANPIPE_TDM_API_IFACE_H_
-
-
-#if defined(__WINDOWS__)
-typedef HANDLE sng_fd_t;
-#else
-typedef int sng_fd_t;
-#endif
-
-/* Indicate to library that new features exist */
-#define WP_TDM_FEATURE_DTMF_EVENTS 1
-#define WP_TDM_FEATURE_FE_ALARM 1
-#define WP_TDM_FEATURE_EVENTS 1
-#define WP_TDM_FEATURE_LINK_STATUS 1
-
-enum wanpipe_tdm_api_cmds {
-
- SIOC_WP_TDM_GET_USR_MTU_MRU, /* 0x00 */
-
- SIOC_WP_TDM_SET_USR_PERIOD, /* 0x01 */
- SIOC_WP_TDM_GET_USR_PERIOD, /* 0x02 */
-
- SIOC_WP_TDM_SET_HW_MTU_MRU, /* 0x03 */
- SIOC_WP_TDM_GET_HW_MTU_MRU, /* 0x04 */
-
- SIOC_WP_TDM_SET_CODEC, /* 0x05 */
- SIOC_WP_TDM_GET_CODEC, /* 0x06 */
-
- SIOC_WP_TDM_SET_POWER_LEVEL, /* 0x07 */
- SIOC_WP_TDM_GET_POWER_LEVEL, /* 0x08 */
-
- SIOC_WP_TDM_TOGGLE_RX, /* 0x09 */
- SIOC_WP_TDM_TOGGLE_TX, /* 0x0A */
-
- SIOC_WP_TDM_GET_HW_CODING, /* 0x0B */
- SIOC_WP_TDM_SET_HW_CODING, /* 0x0C */
-
- SIOC_WP_TDM_GET_FULL_CFG, /* 0x0D */
-
- SIOC_WP_TDM_SET_EC_TAP, /* 0x0E */
- SIOC_WP_TDM_GET_EC_TAP, /* 0x0F */
-
- SIOC_WP_TDM_ENABLE_RBS_EVENTS, /* 0x10 */
- SIOC_WP_TDM_DISABLE_RBS_EVENTS, /* 0x11 */
- SIOC_WP_TDM_WRITE_RBS_BITS, /* 0x12 */
-
- SIOC_WP_TDM_GET_STATS, /* 0x13 */
- SIOC_WP_TDM_FLUSH_BUFFERS, /* 0x14 */
-
- SIOC_WP_TDM_READ_EVENT, /* 0x15 */
-
- SIOC_WP_TDM_SET_EVENT, /* 0x16 */
-
- SIOC_WP_TDM_SET_RX_GAINS, /* 0x17 */
- SIOC_WP_TDM_SET_TX_GAINS, /* 0x18 */
- SIOC_WP_TDM_CLEAR_RX_GAINS, /* 0x19 */
- SIOC_WP_TDM_CLEAR_TX_GAINS, /* 0x1A */
-
- SIOC_WP_TDM_GET_FE_ALARMS, /* 0x1B */
-
- SIOC_WP_TDM_ENABLE_HWEC, /* 0x1C */
- SIOC_WP_TDM_DISABLE_HWEC, /* 0x1D */
-
- SIOC_WP_TDM_SET_FE_STATUS, /* 0x1E */
- SIOC_WP_TDM_GET_FE_STATUS, /* 0x1F */
-
- SIOC_WP_TDM_GET_HW_DTMF, /* 0x20 */
-
- SIOC_WP_TDM_NOTSUPP /* */
-
-};
-
-#define SIOC_WP_TDM_GET_LINK_STATUS SIOC_WP_TDM_GET_FE_STATUS
-
-enum wanpipe_tdm_api_events {
- WP_TDMAPI_EVENT_NONE,
- WP_TDMAPI_EVENT_RBS,
- WP_TDMAPI_EVENT_ALARM,
- WP_TDMAPI_EVENT_DTMF,
- WP_TDMAPI_EVENT_RM_DTMF,
- WP_TDMAPI_EVENT_RXHOOK,
- WP_TDMAPI_EVENT_RING,
- WP_TDMAPI_EVENT_RING_DETECT,
- WP_TDMAPI_EVENT_RING_TRIP_DETECT,
- WP_TDMAPI_EVENT_TONE,
- WP_TDMAPI_EVENT_TXSIG_KEWL,
- WP_TDMAPI_EVENT_TXSIG_START,
- WP_TDMAPI_EVENT_TXSIG_OFFHOOK,
- WP_TDMAPI_EVENT_TXSIG_ONHOOK,
- WP_TDMAPI_EVENT_ONHOOKTRANSFER,
- WP_TDMAPI_EVENT_SETPOLARITY,
- WP_TDMAPI_EVENT_BRI_CHAN_LOOPBACK,
- WP_TDMAPI_EVENT_LINK_STATUS
-};
-
-#define WP_TDMAPI_EVENT_FE_ALARM WP_TDMAPI_EVENT_ALARM
-
-
-#define WP_TDMAPI_EVENT_ENABLE 0x01
-#define WP_TDMAPI_EVENT_DISABLE 0x02
-#define WP_TDMAPI_EVENT_MODE_DECODE(mode) \
- ((mode) == WP_TDMAPI_EVENT_ENABLE) ? "Enable" : \
- ((mode) == WP_TDMAPI_EVENT_DISABLE) ? "Disable" : \
- "(Unknown mode)"
-
-#define WPTDM_A_BIT WAN_RBS_SIG_A
-#define WPTDM_B_BIT WAN_RBS_SIG_B
-#define WPTDM_C_BIT WAN_RBS_SIG_C
-#define WPTDM_D_BIT WAN_RBS_SIG_D
-
-#define WP_TDMAPI_EVENT_RXHOOK_OFF 0x01
-#define WP_TDMAPI_EVENT_RXHOOK_ON 0x02
-#define WP_TDMAPI_EVENT_RXHOOK_DECODE(state) \
- ((state) == WP_TDMAPI_EVENT_RXHOOK_OFF) ? "Off-hook" : \
- ((state) == WP_TDMAPI_EVENT_RXHOOK_ON) ? "On-hook" : \
- "(Unknown state)"
-
-#define WP_TDMAPI_EVENT_RING_PRESENT 0x01
-#define WP_TDMAPI_EVENT_RING_STOP 0x02
-#define WP_TDMAPI_EVENT_RING_DECODE(state) \
- ((state) == WP_TDMAPI_EVENT_RING_PRESENT) ? "Ring Present" : \
- ((state) == WP_TDMAPI_EVENT_RING_STOP) ? "Ring Stop" : \
- "(Unknown state)"
-
-#define WP_TDMAPI_EVENT_RING_TRIP_PRESENT 0x01
-#define WP_TDMAPI_EVENT_RING_TRIP_STOP 0x02
-#define WP_TDMAPI_EVENT_RING_TRIP_DECODE(state) \
- ((state) == WP_TDMAPI_EVENT_RING_TRIP_PRESENT) ? "Ring Present" : \
- ((state) == WP_TDMAPI_EVENT_RING_TRIP_STOP) ? "Ring Stop" : \
- "(Unknown state)"
-/*Link Status */
-#define WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED 0x01
-#define WP_TDMAPI_EVENT_LINK_STATUS_DISCONNECTED 0x02
-#define WP_TDMAPI_EVENT_LINK_STATUS_DECODE(status) \
- ((status) == WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED) ? "Connected" : \
- ((status) == WP_TDMAPI_EVENT_LINK_STATUS_DISCONNECTED) ? "Disconnected" : \
- "Unknown"
-#define WP_TDMAPI_EVENT_TONE_DIAL 0x01
-#define WP_TDMAPI_EVENT_TONE_BUSY 0x02
-#define WP_TDMAPI_EVENT_TONE_RING 0x03
-#define WP_TDMAPI_EVENT_TONE_CONGESTION 0x04
-
-/* BRI channels list */
-#define WAN_BRI_BCHAN1 0x01
-#define WAN_BRI_BCHAN2 0x02
-#define WAN_BRI_DCHAN 0x03
-
-
-typedef struct {
-
- u_int8_t type;
- u_int8_t mode;
- u_int32_t time_stamp;
- u_int8_t channel;
- u_int32_t chan_map;
- u_int8_t span;
- union {
- struct {
- u_int8_t alarm;
- } te1_alarm;
- struct {
- u_int8_t rbs_bits;
- } te1_rbs;
- struct {
- u_int8_t state;
- u_int8_t sig;
- } rm_hook;
- struct {
- u_int8_t state;
- } rm_ring;
- struct {
- u_int8_t type;
- } rm_tone;
- struct {
- u_int8_t digit; /* DTMF: digit */
- u_int8_t port; /* DTMF: SOUT/ROUT */
- u_int8_t type; /* DTMF: PRESET/STOP */
- } dtmf;
- struct {
- u_int16_t polarity;
- u_int16_t ohttimer;
- } rm_common;
- struct{
- u_int16_t status;
- } linkstatus;
- } wp_tdm_api_event_u;
-#define wp_tdm_api_event_type type
-#define wp_tdm_api_event_mode mode
-#define wp_tdm_api_event_alarm wp_tdm_api_event_u.te1_alarm.alarm
-#define wp_tdm_api_event_alarm wp_tdm_api_event_u.te1_alarm.alarm
-#define wp_tdm_api_event_rbs_bits wp_tdm_api_event_u.te1_rbs.rbs_bits
-#define wp_tdm_api_event_hook_state wp_tdm_api_event_u.rm_hook.state
-#define wp_tdm_api_event_hook_sig wp_tdm_api_event_u.rm_hook.sig
-#define wp_tdm_api_event_ring_state wp_tdm_api_event_u.rm_ring.state
-#define wp_tdm_api_event_tone_type wp_tdm_api_event_u.rm_tone.type
-#define wp_tdm_api_event_dtmf_digit wp_tdm_api_event_u.dtmf.digit
-#define wp_tdm_api_event_dtmf_type wp_tdm_api_event_u.dtmf.type
-#define wp_tdm_api_event_dtmf_port wp_tdm_api_event_u.dtmf.port
-#define wp_tdm_api_event_ohttimer wp_tdm_api_event_u.rm_common.ohttimer
-#define wp_tdm_api_event_polarity wp_tdm_api_event_u.rm_common.polarity
-#define wp_tdm_api_event_link_status wp_tdm_api_event_u.linkstatus.status
-} wp_tdm_api_event_t;
-
-typedef struct {
- union {
- unsigned char reserved[16];
- }wp_rx_hdr_u;
-} wp_tdm_api_rx_hdr_t;
-
-typedef struct {
- wp_tdm_api_rx_hdr_t hdr;
- unsigned char data[1];
-} wp_tdm_api_rx_element_t;
-
-typedef struct {
- union {
- struct {
- unsigned char _rbs_rx_bits;
- unsigned int _time_stamp;
- }wp_tx;
- unsigned char reserved[16];
- }wp_tx_hdr_u;
-#define wp_api_time_stamp wp_tx_hdr_u.wp_tx._time_stamp
-} wp_tdm_api_tx_hdr_t;
-
-typedef struct {
- wp_tdm_api_tx_hdr_t hdr;
- unsigned char data[1];
-} wp_tdm_api_tx_element_t;
-
-
-
-typedef struct wp_tdm_chan_stats
-{
- unsigned int rx_packets; /* total packets received */
- unsigned int tx_packets; /* total packets transmitted */
- unsigned int rx_bytes; /* total bytes received */
- unsigned int tx_bytes; /* total bytes transmitted */
- unsigned int rx_errors; /* bad packets received */
- unsigned int tx_errors; /* packet transmit problems */
- unsigned int rx_dropped; /* no space in linux buffers */
- unsigned int tx_dropped; /* no space available in linux */
- unsigned int multicast; /* multicast packets received */
-#if !defined(__WINDOWS__)
- unsigned int collisions;
-#endif
- /* detailed rx_errors: */
- unsigned int rx_length_errors;
- unsigned int rx_over_errors; /* receiver ring buff overflow */
- unsigned int rx_crc_errors; /* recved pkt with crc error */
- unsigned int rx_frame_errors; /* recv'd frame alignment error */
-#if !defined(__WINDOWS__)
- unsigned int rx_fifo_errors; /* recv'r fifo overrun */
-#endif
- unsigned int rx_missed_errors; /* receiver missed packet */
-
- /* detailed tx_errors */
-#if !defined(__WINDOWS__)
- unsigned int tx_aborted_errors;
- unsigned int tx_carrier_errors;
-#endif
- unsigned int tx_fifo_errors;
- unsigned int tx_heartbeat_errors;
- unsigned int tx_window_errors;
-
-}wp_tdm_chan_stats_t;
-
-
-
-typedef struct wanpipe_tdm_api_cmd{
- unsigned int cmd;
- unsigned int hw_tdm_coding; /* Set/Get HW TDM coding: uLaw muLaw */
- unsigned int hw_mtu_mru; /* Set/Get HW TDM MTU/MRU */
- unsigned int usr_period; /* Set/Get User Period in ms */
- unsigned int tdm_codec; /* Set/Get TDM Codec: SLinear */
- unsigned int power_level; /* Set/Get Power level treshold */
- unsigned int rx_disable; /* Enable/Disable Rx */
- unsigned int tx_disable; /* Enable/Disable Tx */
- unsigned int usr_mtu_mru; /* Set/Get User TDM MTU/MRU */
- unsigned int ec_tap; /* Echo Cancellation Tap */
- unsigned int rbs_poll; /* Enable/Disable RBS Polling */
- unsigned int rbs_rx_bits; /* Rx RBS Bits */
- unsigned int rbs_tx_bits; /* Tx RBS Bits */
- unsigned int hdlc; /* HDLC based device */
- unsigned int idle_flag; /* IDLE flag to Tx */
- unsigned int fe_alarms; /* FE Alarms detected */
- wp_tdm_chan_stats_t stats; /* TDM Statistics */
- /* Do NOT add anything above this! Important for binary backward compatibility. */
- wp_tdm_api_event_t event; /* TDM Event */
- unsigned int data_len;
- void *data;
- unsigned char fe_status; /* FE status - Connected or Disconnected */
- unsigned int hw_dtmf; /* HW DTMF enabled */
-}wanpipe_tdm_api_cmd_t;
-
-typedef struct wanpipe_tdm_api_event{
- int (*wp_rbs_event)(sng_fd_t fd, unsigned char rbs_bits);
- int (*wp_dtmf_event)(sng_fd_t fd, unsigned char dtmf, unsigned char type, unsigned char port);
- int (*wp_rxhook_event)(sng_fd_t fd, unsigned char hook_state);
- int (*wp_ring_detect_event)(sng_fd_t fd, unsigned char ring_state);
- int (*wp_ring_trip_detect_event)(sng_fd_t fd, unsigned char ring_state);
- int (*wp_fe_alarm_event)(sng_fd_t fd, unsigned char fe_alarm_event);
- int (*wp_link_status_event)(sng_fd_t fd, unsigned char link_status_event);
-}wanpipe_tdm_api_event_t;
-
-typedef struct wanpipe_tdm_api{
- wanpipe_tdm_api_cmd_t wp_tdm_cmd;
- wanpipe_tdm_api_event_t wp_tdm_event;
-}wanpipe_tdm_api_t;
-
-
-#endif
diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h
index 31bc88b9ca..45254e817f 100644
--- a/libs/freetdm/src/include/freetdm.h
+++ b/libs/freetdm/src/include/freetdm.h
@@ -41,6 +41,7 @@
#include "ftdm_declare.h"
+#include "ftdm_call_utils.h"
/*! \brief Max number of channels per physical span */
#define FTDM_MAX_CHANNELS_PHYSICAL_SPAN 32
@@ -62,23 +63,6 @@
#define FTDM_INVALID_INT_PARM 0xFF
-/*! \brief FreeTDM APIs possible return codes */
-typedef enum {
- FTDM_SUCCESS, /*!< Success */
- FTDM_FAIL, /*!< Failure, generic error return code, use ftdm_channel_get_last_error or ftdm_span_get_last_error for details */
- FTDM_MEMERR, /*!< Memory error, most likely allocation failure */
- 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 */
-} ftdm_status_t;
-
-/*! \brief FreeTDM bool type. */
-typedef enum {
- FTDM_FALSE,
- FTDM_TRUE
-} ftdm_bool_t;
-
/*! \brief Thread/Mutex OS abstraction API. */
#include "ftdm_os.h"
@@ -220,8 +204,10 @@ typedef enum {
FTDM_TON_SUBSCRIBER_NUMBER,
FTDM_TON_ABBREVIATED_NUMBER,
FTDM_TON_RESERVED,
- FTDM_TON_INVALID = 255
+ FTDM_TON_INVALID
} ftdm_ton_t;
+#define TON_STRINGS "unknown", "international", "national", "network-specific", "subscriber-number", "abbreviated-number", "reserved", "invalid"
+FTDM_STR2ENUM_P(ftdm_str2ftdm_ton, ftdm_ton2str, ftdm_ton_t)
/*! Numbering Plan Identification (NPI) */
typedef enum {
@@ -232,8 +218,52 @@ typedef enum {
FTDM_NPI_NATIONAL = 8,
FTDM_NPI_PRIVATE = 9,
FTDM_NPI_RESERVED = 10,
- FTDM_NPI_INVALID = 255
+ FTDM_NPI_INVALID
} ftdm_npi_t;
+#define NPI_STRINGS "unknown", "ISDN", "data", "telex", "national", "private", "reserved", "invalid"
+FTDM_STR2ENUM_P(ftdm_str2ftdm_npi, ftdm_npi2str, ftdm_npi_t)
+
+/*! Presentation Ind */
+typedef enum {
+ FTDM_PRES_ALLOWED,
+ FTDM_PRES_RESTRICTED,
+ FTDM_PRES_NOT_AVAILABLE,
+ FTDM_PRES_RESERVED,
+ FTDM_PRES_INVALID
+} ftdm_presentation_t;
+#define PRESENTATION_STRINGS "presentation-allowed", "presentation-restricted", "number-not-available", "reserved", "Invalid"
+FTDM_STR2ENUM_P(ftdm_str2ftdm_presentation, ftdm_presentation2str, ftdm_presentation_t)
+
+/*! Screening Ind */
+typedef enum {
+ FTDM_SCREENING_NOT_SCREENED,
+ FTDM_SCREENING_VERIFIED_PASSED,
+ FTDM_SCREENING_VERIFIED_FAILED,
+ FTDM_SCREENING_NETWORK_PROVIDED,
+ FTDM_SCREENING_INVALID
+} ftdm_screening_t;
+#define SCREENING_STRINGS "user-provided-not-screened", "user-provided-verified-and-passed", "user-provided-verified-and-failed", "network-provided", "invalid"
+FTDM_STR2ENUM_P(ftdm_str2ftdm_screening, ftdm_screening2str, ftdm_screening_t)
+
+/*! \brief bearer capability */
+typedef enum {
+ FTDM_BEARER_CAP_SPEECH = 0x00,
+ FTDM_BEARER_CAP_64K_UNRESTRICTED = 0x02,
+ FTDM_BEARER_CAP_3_1KHZ_AUDIO = 0x03,
+ FTDM_BEARER_CAP_INVALID
+} ftdm_bearer_cap_t;
+#define BEARER_CAP_STRINGS "speech", "unrestricted-digital-information", "3.1-Khz-audio", "invalid"
+FTDM_STR2ENUM_P(ftdm_str2ftdm_bearer_cap, ftdm_bearer_cap2str, ftdm_bearer_cap_t)
+
+/*! \brief user information layer 1 protocol */
+typedef enum {
+ FTDM_USER_LAYER1_PROT_V110 = 0x01,
+ FTDM_USER_LAYER1_PROT_ULAW = 0x02,
+ FTDM_USER_LAYER1_PROT_ALAW = 0x03,
+ FTDM_USER_LAYER1_PROT_INVALID
+} ftdm_user_layer1_prot_t;
+#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)
/*! \brief Number abstraction */
typedef struct {
@@ -242,20 +272,6 @@ typedef struct {
uint8_t plan;
} ftdm_number_t;
-/*! \brief bearer capability */
-typedef enum {
- FTDM_BEARER_CAP_SPEECH = 0x00,
- FTDM_BEARER_CAP_64K_UNRESTRICTED = 0x02,
- FTDM_BEARER_CAP_3_1KHZ_AUDIO = 0x03
-} ftdm_bearer_cap_t;
-
-/*! \brief user information layer 1 protocol */
-typedef enum {
- FTDM_USER_LAYER1_PROT_V110 = 0x01,
- FTDM_USER_LAYER1_PROT_ULAW = 0x02,
- FTDM_USER_LAYER1_PROT_ALAW = 0x03,
-} ftdm_user_layer1_prot_t;
-
/*! \brief Caller information */
typedef struct ftdm_caller_data {
char cid_date[8]; /*!< Caller ID date */
@@ -285,10 +301,12 @@ typedef enum {
/*! \brief Signaling messages sent by the stacks */
typedef enum {
- FTDM_SIGEVENT_START, /*!< Incoming call (ie: incoming SETUP msg or Ring) */
+ FTDM_SIGEVENT_START,/*!< Incoming call (ie: incoming SETUP msg or Ring) */
FTDM_SIGEVENT_STOP, /*!< Hangup */
+ FTDM_SIGEVENT_RELEASED, /*!< Channel is completely released and available */
FTDM_SIGEVENT_UP, /*!< Outgoing call has been answered */
- FTDM_SIGEVENT_FLASH, /*< Flash event (typically on-hook/off-hook for analog devices) */
+ FTDM_SIGEVENT_FLASH, /*!< Flash event (typically on-hook/off-hook for analog devices) */
+ FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got a response */
FTDM_SIGEVENT_PROGRESS, /*!< Outgoing call is making progress */
FTDM_SIGEVENT_PROGRESS_MEDIA, /*!< Outgoing call is making progress and there is media available */
FTDM_SIGEVENT_ALARM_TRAP, /*!< Hardware alarm ON */
@@ -298,11 +316,12 @@ typedef enum {
FTDM_SIGEVENT_RESTART, /*!< Restart has been requested. Typically you hangup your call resources here */
FTDM_SIGEVENT_SIGSTATUS_CHANGED, /*!< Signaling protocol status changed (ie: D-chan up), see new status in raw_data ftdm_sigmsg_t member */
FTDM_SIGEVENT_COLLISION, /*!< Outgoing call was dropped because an incoming call arrived at the same time */
+ FTDM_SIGEVENT_MSG, /*!< We received an in-call msg */
FTDM_SIGEVENT_INVALID
} ftdm_signal_event_t;
-#define SIGNAL_STRINGS "START", "STOP", "UP", "FLASH", "PROGRESS", \
+#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "PROGRESS", \
"PROGRESS_MEDIA", "ALARM_TRAP", "ALARM_CLEAR", \
- "COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "INVALID"
+ "COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "MSG", "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)
@@ -430,12 +449,15 @@ typedef enum {
FTDM_COMMAND_FLUSH_TX_BUFFERS,
FTDM_COMMAND_FLUSH_RX_BUFFERS,
FTDM_COMMAND_FLUSH_BUFFERS,
+ FTDM_COMMAND_FLUSH_IOSTATS,
FTDM_COMMAND_SET_PRE_BUFFER_SIZE,
FTDM_COMMAND_SET_LINK_STATUS,
FTDM_COMMAND_GET_LINK_STATUS,
FTDM_COMMAND_ENABLE_LOOP,
FTDM_COMMAND_DISABLE_LOOP,
- FTDM_COMMAND_COUNT
+ FTDM_COMMAND_COUNT,
+ FTDM_COMMAND_SET_RX_QUEUE_SIZE,
+ FTDM_COMMAND_SET_TX_QUEUE_SIZE,
} ftdm_command_t;
/*! \brief Custom memory handler hooks. Not recommended to use unless you need memory allocation customizations */
@@ -577,7 +599,7 @@ typedef enum {
* 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_RING,
+ FTDM_CHANNEL_INDICATE_RINGING,
FTDM_CHANNEL_INDICATE_PROCEED,
FTDM_CHANNEL_INDICATE_PROGRESS,
FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA,
diff --git a/libs/freetdm/src/include/ftdm_call_utils.h b/libs/freetdm/src/include/ftdm_call_utils.h
new file mode 100644
index 0000000000..835a5c6cdc
--- /dev/null
+++ b/libs/freetdm/src/include/ftdm_call_utils.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2010, Sangoma Technologies
+ * David Yat Sin
+ * 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_CALL_UTILS_H__
+#define __FTDM_CALL_UTILS_H__
+
+/*!
+ * \brief Set the Numbering Plan Identification from a string
+ *
+ * \param npi_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_npi(const char *npi_string, uint8_t *target);
+
+
+/*!
+ * \brief Set the Type of number from a string
+ *
+ * \param ton_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_ton(const char *ton_string, uint8_t *target);
+
+/*!
+ * \brief Set the Bearer Capability from a string
+ *
+ * \param bc_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_bearer_capability(const char *bc_string, uint8_t *target);
+
+/*!
+ * \brief Set the Bearer Capability - Layer 1 from a string
+ *
+ * \param bc_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_bearer_layer1(const char *bc_string, uint8_t *target);
+
+/*!
+ * \brief Set the Screening Ind from a string
+ *
+ * \param screen_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_screening_ind(const char *string, uint8_t *target);
+
+
+/*!
+ * \brief Set the Presentation Ind from an enum
+ *
+ * \param screen_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_presentation_ind(const char *string, uint8_t *target);
+
+
+/*!
+ * \brief Checks whether a string contains only numbers
+ *
+ * \param number string value
+ *
+ * \retval FTDM_SUCCESS success
+ * \retval FTDM_FAIL failure
+ */
+FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number);
+
+#endif /* __FTDM_CALL_UTILS_H__ */
+
diff --git a/libs/freetdm/src/include/ftdm_declare.h b/libs/freetdm/src/include/ftdm_declare.h
index ab3b5c8966..4aba703f28 100644
--- a/libs/freetdm/src/include/ftdm_declare.h
+++ b/libs/freetdm/src/include/ftdm_declare.h
@@ -171,6 +171,23 @@ typedef int ftdm_socket_t;
#include
#endif
+/*! \brief FreeTDM APIs possible return codes */
+typedef enum {
+ FTDM_SUCCESS, /*!< Success */
+ FTDM_FAIL, /*!< Failure, generic error return code, use ftdm_channel_get_last_error or ftdm_span_get_last_error for details */
+ FTDM_MEMERR, /*!< Memory error, most likely allocation failure */
+ 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 */
+} ftdm_status_t;
+
+/*! \brief FreeTDM bool type. */
+typedef enum {
+ FTDM_FALSE,
+ FTDM_TRUE
+} ftdm_bool_t;
+
/*!
* \brief FreeTDM channel.
* This is the basic data structure used to place calls and I/O operations
diff --git a/libs/freetdm/src/include/private/ftdm_call_utils.h b/libs/freetdm/src/include/private/ftdm_call_utils.h
deleted file mode 100644
index 782abde927..0000000000
--- a/libs/freetdm/src/include/private/ftdm_call_utils.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2010, Sangoma Technologies
- * David Yat Sin
- * 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_CALL_UTILS_H__
-#define __FTDM_CALL_UTILS_H__
-
-#include "freetdm.h"
-
-FT_DECLARE(ftdm_status_t) ftdm_span_set_npi(const char *npi_string, uint8_t *target);
-FT_DECLARE(ftdm_status_t) ftdm_span_set_ton(const char *ton_string, uint8_t *target);
-FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_capability(const char *bc_string, ftdm_bearer_cap_t *target);
-FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_layer1(const char *bc_string, ftdm_user_layer1_prot_t *target);
-FT_DECLARE(ftdm_status_t) ftdm_is_number(char *number);
-
-#endif /* __FTDM_CALL_UTILS_H__ */
-
diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h
index ab20ef8171..7683ec7145 100644
--- a/libs/freetdm/src/include/private/ftdm_core.h
+++ b/libs/freetdm/src/include/private/ftdm_core.h
@@ -222,8 +222,7 @@ extern "C" {
#define ftdm_is_dtmf(key) ((key > 47 && key < 58) || (key > 64 && key < 69) || (key > 96 && key < 101) || key == 35 || key == 42 || key == 87 || key == 119)
-#define FTDM_SPAN_IS_BRI(x) ((x)->trunk_type == FTDM_TRUNK_BRI || (x)->trunk_type == FTDM_TRUNK_BRI_PTMP)
-
+#define FTDM_SPAN_IS_BRI(x) ((x)->trunk_type == FTDM_TRUNK_BRI || (x)->trunk_type == FTDM_TRUNK_BRI_PTMP)
/*!
\brief Copy flags from one arbitrary object to another
\command dest the object to copy the flags to
@@ -358,6 +357,7 @@ typedef struct {
} ftdm_dtmf_debug_t;
#endif
+
typedef struct {
const char *file;
const char *func;
@@ -367,6 +367,35 @@ typedef struct {
ftdm_time_t time;
} ftdm_channel_history_entry_t;
+typedef enum {
+ FTDM_IOSTATS_ERROR_CRC = (1 << 0),
+ FTDM_IOSTATS_ERROR_FRAME = (1 << 1),
+ FTDM_IOSTATS_ERROR_ABORT = (1 << 2),
+ FTDM_IOSTATS_ERROR_FIFO = (1 << 3),
+ FTDM_IOSTATS_ERROR_DMA = (1 << 4),
+ FTDM_IOSTATS_ERROR_QUEUE_THRES = (1 << 5), /* Queue reached high threshold */
+ FTDM_IOSTATS_ERROR_QUEUE_FULL = (1 << 6), /* Queue is full */
+} ftdm_iostats_error_type_t;
+
+typedef struct {
+ struct {
+ uint32_t errors;
+ uint16_t flags;
+ uint8_t queue_size; /* max queue size configured */
+ uint8_t queue_len; /* Current number of elements in queue */
+ uint64_t packets;
+ } rx;
+
+ struct {
+ uint32_t errors;
+ uint16_t flags;
+ uint8_t idle_packets;
+ uint8_t queue_size; /* max queue size configured */
+ uint8_t queue_len; /* Current number of elements in queue */
+ uint64_t packets;
+ } tx;
+} ftdm_channel_iostats_t;
+
/* 2^8 table size, one for each byte (sample) value */
#define FTDM_GAINS_TABLE_SIZE 256
struct ftdm_channel {
@@ -441,6 +470,7 @@ struct ftdm_channel {
int availability_rate;
void *user_private;
ftdm_timer_id_t hangup_timer;
+ ftdm_channel_iostats_t iostats;
#ifdef FTDM_DEBUG_DTMF
ftdm_dtmf_debug_t dtmfdbg;
#endif
@@ -637,10 +667,21 @@ FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan);
#define ftdm_channel_lock(chan) ftdm_mutex_lock(chan->mutex)
#define ftdm_channel_unlock(chan) ftdm_mutex_unlock(chan->mutex)
+
+#define ftdm_log_throttle(level, ...) \
+ time_current_throttle_log = ftdm_current_time_in_ms(); \
+ if (time_current_throttle_log - time_last_throttle_log > FTDM_THROTTLE_LOG_INTERVAL) {\
+ ftdm_log(level, __VA_ARGS__); \
+ time_last_throttle_log = time_current_throttle_log; \
+ }
+
#define ftdm_log_chan_ex(fchan, file, func, line, level, format, ...) ftdm_log(file, func, line, level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
#define ftdm_log_chan(fchan, level, format, ...) ftdm_log(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
#define ftdm_log_chan_msg(fchan, level, msg) ftdm_log(level, "[s%dc%d][%d:%d] " msg, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id)
+#define ftdm_log_chan_throttle(fchan, level, format, ...) ftdm_log_throttle(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
+#define ftdm_log_chan_msg_throttle(fchan, level, format, ...) ftdm_log_throttle(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
+
#define ftdm_span_lock(span) ftdm_mutex_lock(span->mutex)
#define ftdm_span_unlock(span) ftdm_mutex_unlock(span->mutex)
diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h
index 78ac8f63eb..f265cb1a3d 100644
--- a/libs/freetdm/src/include/private/ftdm_types.h
+++ b/libs/freetdm/src/include/private/ftdm_types.h
@@ -181,6 +181,8 @@ typedef enum {
* after having called ftdm_send_span_signal(), which with this flag it will just enqueue the signal
* for later delivery */
FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 10),
+ /* If this flag is set, channel will be moved to proceed state when calls goes to routing */
+ FTDM_SPAN_USE_PROCEED_STATE = (1 << 11),
} ftdm_span_flag_t;
/*! \brief Channel supported features */
@@ -194,6 +196,7 @@ typedef enum {
FTDM_CHANNEL_FEATURE_CALLWAITING = (1 << 6), /*!< Channel will allow call waiting (ie: FXS devices) (read/write) */
FTDM_CHANNEL_FEATURE_HWEC = (1<<7), /*!< Channel has a hardware echo canceller */
FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE = (1<<8), /*!< hardware echo canceller is disabled when there are no calls on this channel */
+ FTDM_CHANNEL_FEATURE_IO_STATS = (1<<9), /*!< Channel supports IO statistics (HDLC channels only) */
} ftdm_channel_feature_t;
typedef enum {
@@ -203,6 +206,7 @@ typedef enum {
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,
@@ -210,6 +214,7 @@ typedef enum {
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,
@@ -222,8 +227,8 @@ typedef enum {
FTDM_CHANNEL_STATE_INVALID
} ftdm_channel_state_t;
#define CHANNEL_STATE_STRINGS "DOWN", "HOLD", "SUSPENDED", "DIALTONE", "COLLECT", \
- "RING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \
- "RESTART", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", \
+ "RING", "RINGING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \
+ "RESTART", "PROCEED", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", \
"HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "INVALID"
FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t)
diff --git a/libs/freetdm/src/testanalog.c b/libs/freetdm/src/testanalog.c
index 84d09f73c9..326bb5aec5 100644
--- a/libs/freetdm/src/testanalog.c
+++ b/libs/freetdm/src/testanalog.c
@@ -50,7 +50,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_signal)
switch(sigmsg->event_id) {
case FTDM_SIGEVENT_START:
- ftdm_channel_call_indicate(sigmsg->channel, FTDM_CHANNEL_INDICATE_RING);
+ ftdm_channel_call_indicate(sigmsg->channel, FTDM_CHANNEL_INDICATE_RINGING);
ftdm_log(FTDM_LOG_DEBUG, "launching thread and indicating ring\n");
ftdm_thread_create_detached(test_call, sigmsg->channel);
break;
diff --git a/libs/freetdm/src/testsangomaboost.c b/libs/freetdm/src/testsangomaboost.c
index 38eac3c190..85b5332635 100644
--- a/libs/freetdm/src/testsangomaboost.c
+++ b/libs/freetdm/src/testsangomaboost.c
@@ -45,10 +45,14 @@
#include
-#include "freetdm.h"
#include
#include
#include
+#ifdef __linux__
+#define __USE_BSD
+#include
+#endif
+#include "freetdm.h"
/* arbitrary limit for max calls in this sample program */
@@ -338,9 +342,9 @@ int main(int argc, char *argv[])
exit(-1);
}
- if (!strcasecmp(argv[2], "cpe")) {
+ if (!strcmp(argv[2], "cpe")) {
sigtype = "pri_cpe";
- } else if (!strcasecmp(argv[2], "net")) {
+ } else if (!strcmp(argv[2], "net")) {
sigtype = "pri_net";
} else {
fprintf(stderr, "Valid signaling types are cpe and net only\n");
diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h
index 3df9001b0c..13410a00ae 100644
--- a/src/include/private/switch_core_pvt.h
+++ b/src/include/private/switch_core_pvt.h
@@ -135,6 +135,7 @@ struct switch_core_session {
switch_mutex_t *frame_read_mutex;
switch_thread_rwlock_t *rwlock;
+ switch_thread_rwlock_t *io_rwlock;
void *streams[SWITCH_MAX_STREAMS];
int stream_count;
diff --git a/src/include/switch_core.h b/src/include/switch_core.h
index 231b26f269..840a06c204 100644
--- a/src/include/switch_core.h
+++ b/src/include/switch_core.h
@@ -354,6 +354,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void);
///\ingroup core1
///\{
+
+SWITCH_DECLARE(switch_status_t) switch_core_session_io_read_lock(switch_core_session_t *session);
+SWITCH_DECLARE(switch_status_t) switch_core_session_io_write_lock(switch_core_session_t *session);
+SWITCH_DECLARE(switch_status_t) switch_core_session_io_rwunlock(switch_core_session_t *session);
+
#ifdef SWITCH_DEBUG_RWLOCKS
SWITCH_DECLARE(switch_status_t) switch_core_session_perform_read_lock(_In_ switch_core_session_t *session, const char *file, const char *func, int line);
#endif
@@ -882,6 +887,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_exec(_In_ switch_core_sessio
SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flags(_In_ switch_core_session_t *session,
_In_ const char *app, _In_opt_z_ const char *arg, _Out_opt_ int32_t *flags);
+SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_async(switch_core_session_t *session, const char *app, const char *arg);
+
SWITCH_DECLARE(switch_status_t) switch_core_session_get_app_flags(const char *app, int32_t *flags);
/*!
diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h
index 249ac63a58..da366c5b8d 100644
--- a/src/include/switch_ivr.h
+++ b/src/include/switch_ivr.h
@@ -874,6 +874,12 @@ SWITCH_DECLARE(void) switch_ivr_dmachine_set_input_timeout_ms(switch_ivr_dmachin
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear_realm(switch_ivr_dmachine_t *dmachine, const char *realm);
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_set_realm(switch_ivr_dmachine_t *dmachine, const char *realm);
+
+SWITCH_DECLARE(switch_status_t) switch_ivr_get_file_handle(switch_core_session_t *session, switch_file_handle_t **fh);
+SWITCH_DECLARE(switch_status_t) switch_ivr_release_file_handle(switch_core_session_t *session, switch_file_handle_t **fh);
+SWITCH_DECLARE(switch_status_t) switch_ivr_process_fh(switch_core_session_t *session, const char *cmd, switch_file_handle_t *fhp);
+SWITCH_DECLARE(switch_status_t) switch_ivr_insert_file(switch_core_session_t *session, const char *file, const char *insert_file, switch_size_t sample_point);
+
/** @} */
SWITCH_END_EXTERN_C
diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c
index ba4b6d310d..c7edfd5420 100644
--- a/src/mod/applications/mod_commands/mod_commands.c
+++ b/src/mod/applications/mod_commands/mod_commands.c
@@ -3968,6 +3968,47 @@ SWITCH_STANDARD_API(uuid_getvar_function)
return SWITCH_STATUS_SUCCESS;
}
+
+#define FILEMAN_SYNTAX " :"
+SWITCH_STANDARD_API(uuid_fileman_function)
+{
+ switch_core_session_t *psession = NULL;
+ char *mycmd = NULL, *argv[4] = { 0 };
+ int argc = 0;
+
+ if (!zstr(cmd) && (mycmd = strdup(cmd))) {
+ argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+ if (argc >= 2 && !zstr(argv[0])) {
+ char *uuid = argv[0];
+ char *cmd = argv[1];
+
+ if ((psession = switch_core_session_locate(uuid))) {
+ switch_channel_t *channel;
+ switch_file_handle_t *fh = NULL;
+
+ channel = switch_core_session_get_channel(psession);
+
+ if (switch_ivr_get_file_handle(psession, &fh) == SWITCH_STATUS_SUCCESS) {
+ switch_ivr_process_fh(psession, cmd, fh);
+ switch_ivr_release_file_handle(psession, &fh);
+ }
+
+ switch_core_session_rwunlock(psession);
+
+ } else {
+ stream->write_function(stream, "-ERR No Such Channel!\n");
+ }
+ goto done;
+ }
+ }
+
+ stream->write_function(stream, "-USAGE: %s\n", GETVAR_SYNTAX);
+
+ done:
+ switch_safe_free(mycmd);
+ return SWITCH_STATUS_SUCCESS;
+}
+
#define UUID_SEND_DTMF_SYNTAX " "
SWITCH_STANDARD_API(uuid_send_dtmf_function)
{
@@ -4674,6 +4715,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
SWITCH_ADD_API(commands_api_interface, "uuid_display", "change display", uuid_display_function, DISPLAY_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_dump", "uuid_dump", uuid_dump_function, DUMP_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_exists", "see if a uuid exists", uuid_exists_function, EXISTS_SYNTAX);
+ SWITCH_ADD_API(commands_api_interface, "uuid_fileman", "uuid_fileman", uuid_fileman_function, FILEMAN_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_flush_dtmf", "Flush dtmf on a given uuid", uuid_flush_dtmf_function, "");
SWITCH_ADD_API(commands_api_interface, "uuid_getvar", "uuid_getvar", uuid_getvar_function, GETVAR_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_hold", "hold", uuid_hold_function, HOLD_SYNTAX);
@@ -4785,6 +4827,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
switch_console_set_complete("add uuid_display ::console::list_uuid");
switch_console_set_complete("add uuid_dump ::console::list_uuid");
switch_console_set_complete("add uuid_exists ::console::list_uuid");
+ switch_console_set_complete("add uuid_fileman ::console::list_uuid");
switch_console_set_complete("add uuid_flush_dtmf ::console::list_uuid");
switch_console_set_complete("add uuid_getvar ::console::list_uuid");
switch_console_set_complete("add uuid_hold ::console::list_uuid");
diff --git a/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml b/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml
index 45268f304b..79c00516b9 100644
--- a/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml
+++ b/src/mod/endpoints/mod_khomp/Install/files/khomp.conf.xml
@@ -95,16 +95,6 @@ should be opened for the channel. Limited to 25ms min, 500ms max.
-->
-
-
-
-
-
-
-
-
-
-
diff --git a/src/mod/endpoints/mod_khomp/Makefile b/src/mod/endpoints/mod_khomp/Makefile
index 94923c7cda..db1a6fe4e4 100644
--- a/src/mod/endpoints/mod_khomp/Makefile
+++ b/src/mod/endpoints/mod_khomp/Makefile
@@ -1,6 +1,9 @@
MODNAME := mod_khomp
VERBOSE := 1
+#FreeSWITCH source PATH is needed:
+# Set FREESWITCH_PATH
+
ifeq ($(strip $(FREESWITCH_PATH)),)
BASE := ../../../../
else
@@ -11,12 +14,12 @@ curr_dir := $(shell pwd)
versions := -DFS_VERSION_MAJOR=$(shell bash $(curr_dir)/tools/getversion.sh "SWITCH_VERSION_MAJOR" $(BASE)) -DFS_VERSION_MINOR=$(shell bash $(curr_dir)/tools/getversion.sh "SWITCH_VERSION_MINOR" $(BASE)) -DFS_VERSION_MICRO=$(shell bash $(curr_dir)/tools/getversion.sh "SWITCH_VERSION_MICRO" $(BASE))
-LOCAL_CFLAGS = -I./ -I./include -I./commons -I./support -D_REENTRANT -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DK3L_HOSTSYSTEM -DCOMMONS_LIBRARY_USING_FREESWITCH -g -ggdb #-DDEBUG_FLAGS
+LOCAL_CFLAGS = -I./ -I./include -I./commons -I./commons/base -I./support -D_REENTRANT -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DK3L_HOSTSYSTEM -DCOMMONS_LIBRARY_USING_FREESWITCH -g -ggdb #-DDEBUG_FLAGS
LOCAL_CFLAGS += $(versions)
LOCAL_LDFLAGS = -lk3l
-LOCAL_OBJS = ./commons/k3lapi.o ./commons/k3lutil.o ./commons/config_options.o ./commons/format.o ./commons/strings.o ./commons/ringbuffer.o ./commons/verbose.o ./commons/saved_condition.o ./commons/regex.o ./commons/timer.o ./commons/configurator/configfile.o ./commons/configurator/option.o ./commons/configurator/section.o ./commons/configurator/restriction.o
+LOCAL_OBJS = ./commons/base/k3lapi.o ./commons/base/k3lutil.o ./commons/base/config_options.o ./commons/base/format.o ./commons/base/strings.o ./commons/base/ringbuffer.o ./commons/base/verbose.o ./commons/base/saved_condition.o ./commons/base/regex.o ./commons/base/timer.o ./commons/base/configurator/configfile.o ./commons/base/configurator/option.o ./commons/base/configurator/section.o ./commons/base/configurator/restriction.o ./commons/base/verbose_traits.o
LOCAL_OBJS += ./support/klog-config.o ./support/klog-options.o ./support/config_defaults.o
LOCAL_OBJS += ./src/globals.o ./src/opt.o ./src/frame.o ./src/utils.o ./src/lock.o ./src/spec.o ./src/applications.o ./src/khomp_pvt_fxo.o ./src/khomp_pvt_gsm.o ./src/khomp_pvt_kxe1.o ./src/khomp_pvt_passive.o ./src/khomp_pvt.o ./src/logger.o ./src/cli.o
@@ -27,7 +30,20 @@ conf_file_install = $(sysconfdir)/autoload_configs
include $(BASE)/build/modmake.rules
+local_depend:
+ @if test ! -f $(curr_dir)/commons/base/verbose_traits.hpp || test ! -f $(curr_dir)/commons/base/verbose_traits.cpp ; then \
+ echo "Generating verbose_traits" ;\
+ bash $(curr_dir)/commons/tools/generate-verbose-headers.sh commons/base/ include/k3l.h ;\
+ fi;
+
depend_install:
+ @if test "w`kserver --version 2>/dev/null | grep 2.1`" == "w" ; then \
+ echo "###############################################################################" ;\
+ echo "Install k3l from KHOMP." ;\
+ echo "Run: $(curr_dir)/tools/getk3l.sh" ;\
+ echo "###############################################################################" ;\
+ exit 1;\
+ fi;
@echo "Copy $(conf_file_name)"
@if test -d $(conf_file_install) ; then \
if test -f $(conf_file_dir)/$(conf_file_name) ; then \
diff --git a/src/mod/endpoints/mod_khomp/commons/atomic.hpp b/src/mod/endpoints/mod_khomp/commons/base/atomic.hpp
similarity index 90%
rename from src/mod/endpoints/mod_khomp/commons/atomic.hpp
rename to src/mod/endpoints/mod_khomp/commons/base/atomic.hpp
index daa598c9b4..02278b390c 100644
--- a/src/mod/endpoints/mod_khomp/commons/atomic.hpp
+++ b/src/mod/endpoints/mod_khomp/commons/base/atomic.hpp
@@ -64,17 +64,31 @@ namespace Atomic
PunnedType pval; pval.valtype = VAL; \
unsigned long long vexp = *(pexp.podtype); \
unsigned long long vval = *(pval.podtype); \
- unsigned long long res = (unsigned long long)exp; \
+ unsigned long vval32 = (unsigned long)vval; \
unsigned char chg = 0; \
- asm volatile("lock; cmpxchg8b %2; sete %1;" \
+ asm volatile( \
+ "xchgl %%ebx, %4;" \
+ "lock; cmpxchg8b %2; sete %1;" \
+ "movl %4, %%ebx; " \
: "+A" (vexp), /* 0 (result) */ \
- "=q" (chg) /* 1 */ \
+ "=c" (chg) /* 1 */ \
: "m" (*(unsigned char**)(PTR)), /* 2 */ \
- "b" ((unsigned long)(vval)), \
- "c" ((unsigned long)(vval >> 32))); \
+ "c" ((unsigned long)(vval >> 32)), \
+ "m" (vval32)); \
*(pexp.podtype) = vexp; \
return (chg != 0 ? true : false);
+// "movl %%ecx, %4;"
+//
+// "m" (*((unsigned long*)(*(pval.podtype)))),
+// "m" ((unsigned long)(vval >> 32))
+//
+// "m" (*((unsigned long*)(&vval))),
+// "m" ((unsigned long)(vval >> 32))
+//
+// unsigned long long vval = *(pval.podtype);
+// unsigned long long res = (unsigned long long)exp;
+//
// Types used for making CMPXCHG instructions independent from base type.
template < typename ValType, typename PodType >
diff --git a/src/mod/endpoints/mod_khomp/commons/config_commons.hpp b/src/mod/endpoints/mod_khomp/commons/base/config_commons.hpp
similarity index 92%
rename from src/mod/endpoints/mod_khomp/commons/config_commons.hpp
rename to src/mod/endpoints/mod_khomp/commons/base/config_commons.hpp
index de8f327df4..dad16f4e92 100644
--- a/src/mod/endpoints/mod_khomp/commons/config_commons.hpp
+++ b/src/mod/endpoints/mod_khomp/commons/base/config_commons.hpp
@@ -63,7 +63,12 @@
#error Unknown implementation selected. Please define COMMONS_LIBRARY_USING_* correctly.
#endif
-#define COMMONS_INCLUDE(file)
+#define COMMONS_INCLUDE(file)
+
+#define COMMONS_VERSION_MAJOR 1
+#define COMMONS_VERSION_MINOR 1
+
+#define COMMONS_AT_LEAST(x,y) \
+ (COMMONS_VERSION_MAJOR > x || (COMMONS_VERSION_MAJOR == x && COMMONS_VERSION_MINOR >= y))
#endif /* _CONFIG_COMMONS_HPP_ */
-
diff --git a/src/mod/endpoints/mod_khomp/commons/base/config_options.cpp b/src/mod/endpoints/mod_khomp/commons/base/config_options.cpp
new file mode 100644
index 0000000000..7412b4b1a0
--- /dev/null
+++ b/src/mod/endpoints/mod_khomp/commons/base/config_options.cpp
@@ -0,0 +1,302 @@
+/*
+ KHOMP generic endpoint/channel library.
+ Copyright (C) 2007-2009 Khomp Ind. & Com.
+
+ The contents of this file are subject to the Mozilla Public License Version 1.1
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS" basis,
+ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+ the specific language governing rights and limitations under the License.
+
+ Alternatively, the contents of this file may be used under the terms of the
+ "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
+ case the provisions of "LGPL License" are applicable instead of those above.
+
+ If you wish to allow use of your version of this file only under the terms of
+ the LGPL License and not to allow others to use your version of this file under
+ the MPL, indicate your decision by deleting the provisions above and replace them
+ with the notice and other provisions required by the LGPL License. If you do not
+ delete the provisions above, a recipient may use your version of this file under
+ either the MPL or the LGPL License.
+
+ The LGPL header follows below:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+#include
+
+void Config::Restriction::checkRange(const std::string & name, const SIntType value, const Range < SIntType > & range)
+{
+ if (value < range.minimum)
+ throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (too low)") % value % name));
+
+ if (value > range.maximum)
+ throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (too high)") % value % name));
+
+ if (((value - range.minimum) % range.step) != 0)
+ throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (outside allowed step)") % value % name));
+}
+
+void Config::Restriction::checkRange(const std::string & name, const UIntType value, const Range < UIntType > & range)
+{
+ if (value < range.minimum)
+ throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (too low)") % value % name));
+
+ if (value > range.maximum)
+ throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (too high)") % value % name));
+
+ if (((value - range.minimum) % range.step) != 0)
+ throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (outside allowed step)") % value % name));
+}
+
+void Config::Restriction::checkStringSet(const std::string & name, const StringType & value, const StringSet & allowed)
+{
+ if (allowed.empty())
+ return;
+
+ if (allowed.find(value) != allowed.end())
+ return;
+
+ std::string strlist;
+
+ for (StringSet::const_iterator i = allowed.begin(); i != allowed.end(); i++)
+ {
+ strlist += " '";
+ strlist += (*i);
+ strlist += "'";
+ }
+
+ throw Failure(STG(FMT("value '%s' not allowed for option '%s' (allowed values:%s)")
+ % value % name % strlist));
+}
+
+Config::Option::Option(std::string name, Config::Option::StringMemberType value, const StringType defvalue, StringSet & allowed, bool listme)
+: _myname(name), _option(InnerStringType(name, value, defvalue, allowed)), _listme(listme), _values(NULL)
+{};
+
+Config::Option::Option(std::string name, Config::Option::StringMemberType value, const StringType defvalue, bool listme)
+: _myname(name), _option(InnerStringType(name, value, defvalue)), _listme(listme), _values(NULL)
+{};
+
+Config::Option::Option(std::string name, Config::Option::BooleanMemberType value, const BooleanType defvalue, bool listme)
+: _myname(name), _option(InnerBooleanType(name, value, defvalue)), _listme(listme), _values(NULL)
+{};
+
+Config::Option::Option(std::string name, Config::Option::SIntMemberType value, const SIntType defvalue,
+ SIntType min, SIntType max, SIntType step, bool listme)
+: _myname(name), _option(InnerSIntType(name, value, defvalue, min, max, step)), _listme(listme), _values(NULL)
+{};
+
+Config::Option::Option(std::string name, Config::Option::UIntMemberType value, const UIntType defvalue,
+ UIntType min, UIntType max, UIntType step, bool listme)
+: _myname(name), _option(InnerUIntType(name, value, defvalue, min, max, step)), _listme(listme), _values(NULL)
+{};
+
+Config::Option::Option(const Config::Option & o)
+: _myname(o._myname), _option(o._option), _listme(o._listme), _values(o._values)
+{};
+
+Config::Option::Option(std::string name, Config::Option::FunctionMemberType value, const StringType defvalue, StringSet & allowed, bool listme)
+: _myname(name), _option(InnerFunctionType(name, value, defvalue, allowed)), _listme(listme), _values(NULL)
+{};
+
+Config::Option::Option(std::string name, Config::Option::FunctionMemberType value, const StringType defvalue, bool listme)
+: _myname(name), _option(InnerFunctionType(name, value, defvalue)), _listme(listme), _values(NULL)
+{};
+
+Config::Option::~Option(void)
+{
+ if (_values)
+ {
+ for (unsigned int i = 0; _values[i] != NULL; i++)
+ delete _values[i];
+
+ delete[] _values;
+ _values = NULL;
+ }
+};
+
+const char ** Config::Option::values(void)
+{
+ if (_values != NULL)
+ return _values;
+
+ /**/ if (_option.check())
+ {
+ _values = new const char*[3];
+
+ _values[0] = strdup("yes");
+ _values[1] = strdup("no");
+ _values[2] = NULL;
+
+ }
+ else if (_option.check())
+ {
+ const InnerSIntType & tmp = _option.get();
+
+ unsigned int count = ((tmp._range.maximum - tmp._range.minimum) / tmp._range.step) + 1;
+ unsigned int index = 0;
+
+ _values = new const char*[count + 1];
+
+ for (SIntType i = tmp._range.minimum; i <= tmp._range.maximum; i += tmp._range.step, ++index)
+ _values[index] = strdup(STG(FMT("%d") % i).c_str());
+
+ _values[index] = NULL;
+ }
+ else if (_option.check())
+ {
+ const InnerUIntType & tmp = _option.get();
+
+ unsigned int count = ((tmp._range.maximum - tmp._range.minimum) / tmp._range.step) + 1;
+ unsigned int index = 0;
+
+ _values = new const char*[count + 1];
+
+ for (UIntType i = tmp._range.minimum; i <= tmp._range.maximum; i += tmp._range.step, ++index)
+ _values[index] = strdup(STG(FMT("%d") % i).c_str());
+
+ _values[index] = NULL;
+ }
+ else if (_option.check())
+ {
+ const InnerStringType & tmp = _option.get();
+
+ _values = new const char*[ tmp._allowed.size() + 1 ];
+
+ unsigned int index = 0;
+
+ for (StringSet::iterator i = tmp._allowed.begin(); i != tmp._allowed.end(); ++i, ++index)
+ _values[index] = strdup((*i).c_str());
+
+ _values[index] = NULL;
+ }
+ else if (_option.check())
+ {
+ const InnerFunctionType & tmp = _option.get();
+
+ _values = new const char*[ tmp._allowed.size() + 1 ];
+
+ unsigned int index = 0;
+
+ for (StringSet::iterator i = tmp._allowed.begin(); i != tmp._allowed.end(); ++i, ++index)
+ _values[index] = strdup((*i).c_str());
+
+ _values[index] = NULL;
+ }
+ else
+ {
+ throw Failure(STG(FMT("values() not implemented for type used in option '%s'") % _myname));
+ }
+
+ return _values;
+};
+
+/*********************************/
+
+Config::Options::Options(void)
+: _values(NULL)
+{};
+
+Config::Options::~Options()
+{
+ if (_values)
+ {
+ for (unsigned int i = 0; _values[i] != NULL; i++)
+ free((void*)(_values[i]));
+
+ delete[] _values;
+ _values = NULL;
+ }
+};
+
+bool Config::Options::add(Config::Option option)
+{
+ std::pair ret = _map.insert(OptionPair(option.name(), option));
+
+ return ret.second;
+}
+
+bool Config::Options::synonym(std::string equiv_opt, std::string main_opt)
+{
+ std::pair ret = _syn_map.insert(SynOptionPair(equiv_opt, main_opt));
+
+ return ret.second;
+}
+
+Config::StringSet Config::Options::options(void)
+{
+ StringSet res;
+
+ for (OptionMap::iterator i = _map.begin(); i != _map.end(); i++)
+ res.insert(i->first);
+
+ return res;
+}
+
+const char ** Config::Options::values(const char * name)
+{
+ OptionMap::iterator iter = find_option(name);
+
+ if (iter == _map.end())
+ throw Failure(STG(FMT("unknown option '%s'") % name));
+
+ return iter->second.values();
+}
+
+const char ** Config::Options::values(void)
+{
+ if (_values != NULL)
+ return _values;
+
+ unsigned int count = 0;
+
+ for (OptionMap::iterator i = _map.begin(); i != _map.end(); ++i)
+ if (i->second.listme())
+ ++count;
+
+ _values = new const char*[ count + 1 ];
+
+ unsigned int index = 0;
+
+ for (OptionMap::iterator i = _map.begin(); i != _map.end(); ++i)
+ {
+ if (i->second.listme())
+ {
+ _values[index] = strdup(i->first.c_str());
+ ++index;
+ }
+ }
+
+ _values[index] = NULL;
+
+ return _values;
+}
+
+Config::Options::OptionMap::iterator Config::Options::find_option(std::string name)
+{
+ SynOptionMap::iterator syn_iter = _syn_map.find(name);
+
+ if (syn_iter != _syn_map.end())
+ name = syn_iter->second;
+
+ OptionMap::iterator iter = _map.find(name);
+
+ return iter;
+}
diff --git a/src/mod/endpoints/mod_khomp/commons/base/config_options.hpp b/src/mod/endpoints/mod_khomp/commons/base/config_options.hpp
new file mode 100644
index 0000000000..59e381f893
--- /dev/null
+++ b/src/mod/endpoints/mod_khomp/commons/base/config_options.hpp
@@ -0,0 +1,772 @@
+/*
+ KHOMP generic endpoint/channel library.
+ Copyright (C) 2007-2009 Khomp Ind. & Com.
+
+ The contents of this file are subject to the Mozilla Public License Version 1.1
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS" basis,
+ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+ the specific language governing rights and limitations under the License.
+
+ Alternatively, the contents of this file may be used under the terms of the
+ "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
+ case the provisions of "LGPL License" are applicable instead of those above.
+
+ If you wish to allow use of your version of this file only under the terms of
+ the LGPL License and not to allow others to use your version of this file under
+ the MPL, indicate your decision by deleting the provisions above and replace them
+ with the notice and other provisions required by the LGPL License. If you do not
+ delete the provisions above, a recipient may use your version of this file under
+ either the MPL or the LGPL License.
+
+ The LGPL header follows below:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+#ifndef _CONFIG_OPTIONS_HPP_
+#define _CONFIG_OPTIONS_HPP_
+
+#include
+#include