diff --git a/Freeswitch.2010.sln b/Freeswitch.2010.sln
index 4f48314f5b..186969891a 100644
--- a/Freeswitch.2010.sln
+++ b/Freeswitch.2010.sln
@@ -964,9 +964,7 @@ Global
{692F6330-4D87-4C82-81DF-40DB5892636E}.Release|Win32.ActiveCfg = Release|Win32
{692F6330-4D87-4C82-81DF-40DB5892636E}.Release|x64.ActiveCfg = Release|x64
{692F6330-4D87-4C82-81DF-40DB5892636E}.Release|x64 Setup.ActiveCfg = Release|x64
- {692F6330-4D87-4C82-81DF-40DB5892636E}.Release|x64 Setup.Build.0 = Release|x64
{692F6330-4D87-4C82-81DF-40DB5892636E}.Release|x86 Setup.ActiveCfg = Release|Win32
- {692F6330-4D87-4C82-81DF-40DB5892636E}.Release|x86 Setup.Build.0 = Release|Win32
{D3EC0AFF-76FC-4210-A825-9A17410660A3}.All|Win32.ActiveCfg = Release|x64
{D3EC0AFF-76FC-4210-A825-9A17410660A3}.All|x64.ActiveCfg = Release|x64
{D3EC0AFF-76FC-4210-A825-9A17410660A3}.All|x64.Build.0 = Release|x64
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/freetdm.2008.sln b/libs/freetdm/freetdm.2008.sln
index c7207a6216..0e374545eb 100644
--- a/libs/freetdm/freetdm.2008.sln
+++ b/libs/freetdm/freetdm.2008.sln
@@ -162,7 +162,6 @@ Global
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.ActiveCfg = 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/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/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c
index 3e4cce676d..cde3c245cf 100644
--- a/libs/freetdm/src/ftdm_io.c
+++ b/libs/freetdm/src/ftdm_io.c
@@ -426,43 +426,43 @@ static ftdm_status_t ftdm_set_caller_data(ftdm_span_t *span, ftdm_caller_data_t
return FTDM_FAIL;
}
- if (caller_data->dnis.plan == FTDM_NPI_INVALID) {
+ if (caller_data->dnis.plan >= FTDM_NPI_INVALID) {
caller_data->dnis.plan = span->default_caller_data.dnis.plan;
}
- if (caller_data->dnis.type == FTDM_TON_INVALID) {
+ if (caller_data->dnis.type >= FTDM_TON_INVALID) {
caller_data->dnis.type = span->default_caller_data.dnis.type;
}
- if (caller_data->cid_num.plan == FTDM_NPI_INVALID) {
+ if (caller_data->cid_num.plan >= FTDM_NPI_INVALID) {
caller_data->cid_num.plan = span->default_caller_data.cid_num.plan;
}
- if (caller_data->cid_num.type == FTDM_TON_INVALID) {
+ if (caller_data->cid_num.type >= FTDM_TON_INVALID) {
caller_data->cid_num.type = span->default_caller_data.cid_num.type;
}
- if (caller_data->ani.plan == FTDM_NPI_INVALID) {
+ if (caller_data->ani.plan >= FTDM_NPI_INVALID) {
caller_data->ani.plan = span->default_caller_data.ani.plan;
}
- if (caller_data->ani.type == FTDM_TON_INVALID) {
+ if (caller_data->ani.type >= FTDM_TON_INVALID) {
caller_data->ani.type = span->default_caller_data.ani.type;
}
- if (caller_data->rdnis.plan == FTDM_NPI_INVALID) {
+ if (caller_data->rdnis.plan >= FTDM_NPI_INVALID) {
caller_data->rdnis.plan = span->default_caller_data.rdnis.plan;
}
- if (caller_data->rdnis.type == FTDM_NPI_INVALID) {
+ if (caller_data->rdnis.type >= FTDM_NPI_INVALID) {
caller_data->rdnis.type = span->default_caller_data.rdnis.type;
}
- if (caller_data->bearer_capability == FTDM_INVALID_INT_PARM) {
+ if (caller_data->bearer_capability >= FTDM_INVALID_INT_PARM) {
caller_data->bearer_capability = span->default_caller_data.bearer_capability;
}
- if (caller_data->bearer_layer1 == FTDM_INVALID_INT_PARM) {
+ if (caller_data->bearer_layer1 >= FTDM_INVALID_INT_PARM) {
caller_data->bearer_layer1 = span->default_caller_data.bearer_layer1;
}
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 99d256655a..95002e3e70 100644
--- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c
+++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c
@@ -341,8 +341,8 @@ static void send_caller_id(ftdm_channel_t *ftdmchan)
static void analog_dial(ftdm_channel_t *ftdmchan, uint32_t *state_counter, uint32_t *dial_timeout)
{
if (ftdm_strlen_zero(ftdmchan->caller_data.dnis.digits)) {
- ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "No Digits to send!\n");
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
+ ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No digits to send, moving to UP!\n");
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
} else {
if (ftdm_channel_command(ftdmchan, FTDM_COMMAND_SEND_DTMF, ftdmchan->caller_data.dnis.digits) != FTDM_SUCCESS) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Send Digits Failed [%s]\n", ftdmchan->last_error);
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_r2/ftmod_r2.2010.vcxproj b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2010.vcxproj
index f66f5afc0d..9b893b3527 100644
--- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2010.vcxproj
+++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2010.vcxproj
@@ -5,10 +5,18 @@
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_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_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_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
index b9b4eee28b..16b22a5da1 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
@@ -33,6 +33,7 @@
*/
#include "ftmod_sangoma_isdn.h"
+ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn);
/* Remote side transmit a SETUP */
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
@@ -350,33 +351,15 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd);
get_facility_ie(ftdmchan, &cnStEvnt->facilityStr);
- 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 */
- case 18: /* No User responding */
- case 19: /* User alerting, no answer */
- case 21: /* Call rejected, the called party does not with to accept this call */
- case 27: /* Destination out of order */
- case 31: /* Normal, unspecified */
- case 34: /* Circuit/Channel congestion */
- case 41: /* Temporary failure */
- case 42: /* Switching equipment is experiencing a period of high traffic */
- case 47: /* Resource unavailable */
- case 58: /* Bearer Capability not available */
- case 63: /* Service or option not available */
- case 65: /* Bearer Cap not implemented, not supported */
- case 79: /* Service or option not implemented, unspecified */
- ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Cause requires disconnect (cause:%d)\n", cnStEvnt->causeDgn[0].causeVal.val);
- ftdmchan->caller_data.hangup_cause = cnStEvnt->causeDgn[0].causeVal.val;
+ if (sngisdn_cause_val_requires_disconnect(ftdmchan, &cnStEvnt->causeDgn[0]) == FTDM_SUCCESS) {
+ ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Cause requires disconnect (cause:%d)\n", cnStEvnt->causeDgn[0].causeVal.val);
+ ftdmchan->caller_data.hangup_cause = cnStEvnt->causeDgn[0].causeVal.val;
- sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC);
- ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
- goto sngisdn_process_cnst_ind_end;
- }
+ sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC);
+ ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
+ goto sngisdn_process_cnst_ind_end;
}
-
+
switch(ftdmchan->state) {
case FTDM_CHANNEL_STATE_DIALING:
case FTDM_CHANNEL_STATE_PROCEED:
@@ -1100,8 +1083,44 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
(evntType == IN_LNK_DWN)?"LNK_DOWN":
(evntType == IN_LNK_UP)?"LNK_UP":
(evntType == IN_INDCHAN)?"b-channel":
- (evntType == IN_LNK_DWN_DM_RLS)?"Nfas service procedures":
+ (evntType == IN_LNK_DWN_DM_RLS)?"NFAS service procedures":
(evntType == IN_SWCHD_BU_DCHAN)?"NFAS switchover to backup":"Unknown");
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
return;
}
+
+ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn)
+{
+ sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
+
+ if (signal_data->ignore_cause_value == SNGISDN_OPT_TRUE) {
+ return FTDM_FAIL;
+ }
+
+ /* By default, we only evaluate cause value on 5ESS switches */
+ if (signal_data->ignore_cause_value == SNGISDN_OPT_DEFAULT &&
+ signal_data->switchtype != SNGISDN_SWITCH_5ESS) {
+
+ return FTDM_FAIL;
+ }
+
+ /* ignore_cause_value = SNGISDN_OPT_FALSE or switchtype == 5ESS */
+ switch(causeDgn->causeVal.val) {
+ case 17: /* User Busy */
+ case 18: /* No User responding */
+ case 19: /* User alerting, no answer */
+ case 21: /* Call rejected, the called party does not with to accept this call */
+ case 27: /* Destination out of order */
+ case 31: /* Normal, unspecified */
+ case 34: /* Circuit/Channel congestion */
+ case 41: /* Temporary failure */
+ case 42: /* Switching equipment is experiencing a period of high traffic */
+ case 47: /* Resource unavailable */
+ case 58: /* Bearer Capability not available */
+ case 63: /* Service or option not available */
+ case 65: /* Bearer Cap not implemented, not supported */
+ case 79: /* Service or option not implemented, unspecified */
+ return FTDM_SUCCESS;
+ }
+ return FTDM_FAIL;
+}
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 6fd99adbc3..37d2938353 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
@@ -401,10 +401,19 @@ ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
cgPtyNmb->presInd0.val = caller_data->pres;
cgPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
- cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan;
+ if (caller_data->cid_num.plan >= FTDM_NPI_INVALID) {
+ cgPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
+ } else {
+ cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan;
+ }
cgPtyNmb->typeNmb1.pres = PRSNT_NODEF;
- cgPtyNmb->typeNmb1.val = caller_data->cid_num.type;
+
+ if (caller_data->cid_num.type >= FTDM_TON_INVALID) {
+ cgPtyNmb->typeNmb1.val = FTDM_TON_UNKNOWN;
+ } else {
+ cgPtyNmb->typeNmb1.val = caller_data->cid_num.type;
+ }
cgPtyNmb->nmbDigits.pres = PRSNT_NODEF;
cgPtyNmb->nmbDigits.len = len;
@@ -425,14 +434,14 @@ ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb)
cdPtyNmb->eh.pres = PRSNT_NODEF;
cdPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
- if (caller_data->dnis.plan == FTDM_NPI_INVALID) {
+ if (caller_data->dnis.plan >= FTDM_NPI_INVALID) {
cdPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
} else {
cdPtyNmb->nmbPlanId.val = caller_data->dnis.plan;
}
cdPtyNmb->typeNmb0.pres = PRSNT_NODEF;
- if (caller_data->dnis.type == FTDM_TON_INVALID) {
+ if (caller_data->dnis.type >= FTDM_TON_INVALID) {
cdPtyNmb->typeNmb0.val = FTDM_TON_UNKNOWN;
} else {
cdPtyNmb->typeNmb0.val = caller_data->dnis.type;
@@ -457,14 +466,14 @@ ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb)
redirNmb->eh.pres = PRSNT_NODEF;
redirNmb->nmbPlanId.pres = PRSNT_NODEF;
- if (caller_data->rdnis.plan == FTDM_NPI_INVALID) {
+ if (caller_data->rdnis.plan >= FTDM_NPI_INVALID) {
redirNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
} else {
redirNmb->nmbPlanId.val = caller_data->rdnis.plan;
}
redirNmb->typeNmb.pres = PRSNT_NODEF;
- if (caller_data->rdnis.type == FTDM_TON_INVALID) {
+ if (caller_data->rdnis.type >= FTDM_TON_INVALID) {
redirNmb->typeNmb.val = FTDM_TON_UNKNOWN;
} else {
redirNmb->typeNmb.val = caller_data->rdnis.type;
diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h
index d277bd030f..da366c5b8d 100644
--- a/src/include/switch_ivr.h
+++ b/src/include/switch_ivr.h
@@ -878,6 +878,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_set_realm(switch_ivr_dmachin
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);
/** @} */
diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c b/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c
index 005924194f..f576b7dd01 100644
--- a/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c
+++ b/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c
@@ -495,7 +495,7 @@ switch_status_t callprogress_detector_stop(switch_core_session_t *session)
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_media_bug_t *bug = switch_channel_get_private(channel, TONE_PRIVATE);
if (bug) {
- switch_core_media_bug_close(&bug);
+ switch_core_media_bug_remove(session, &bug);
switch_channel_set_private(channel, TONE_PRIVATE, NULL);
}
return SWITCH_STATUS_SUCCESS;
diff --git a/src/mod/endpoints/mod_h323/changes.txt b/src/mod/endpoints/mod_h323/changes.txt
index 19aca46dc8..4f75aef8b4 100644
--- a/src/mod/endpoints/mod_h323/changes.txt
+++ b/src/mod/endpoints/mod_h323/changes.txt
@@ -1,3 +1,6 @@
+Adds an extra switch_rtp_destroy or switch_rtp_release_port when a session ends
+ - to make sure the port is returned to FS. thx to Peter Olsson.
+fix issues with Progress message type if pre_answer enabled
fix crashes on FSH323Connection calls in on_hangup routine in different threads.
move PTrace level set to FSH323EndPoint::Initialise
partially apply patch from from Peter Olsson, Remove UnLock() when TryLock() failed and DEBUG_RTP_PACKETS directive.
diff --git a/src/mod/endpoints/mod_h323/mod_h323.cpp b/src/mod/endpoints/mod_h323/mod_h323.cpp
index 142506dd92..74fb6ae11a 100644
--- a/src/mod/endpoints/mod_h323/mod_h323.cpp
+++ b/src/mod/endpoints/mod_h323/mod_h323.cpp
@@ -343,7 +343,7 @@ PString GetH245CodecName(const H323Capability* cap)
}
FSProcess::FSProcess()
- : PLibraryProcess("Test", "mod_h323", 1, 0, AlphaCode, 1)
+ : PLibraryProcess("FreeSWITCH", "mod_h323", 1, 0, AlphaCode, 1)
, m_h323endpoint(NULL){
}
@@ -742,6 +742,14 @@ FSH323Connection::~FSH323Connection()
switch_core_session_unlock_codec_write(m_fsSession);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"------------->switch_core_session_unlock_codec_write [%p]\n",m_fsSession);
}
+
+ if (tech_pvt->rtp_session) {
+ switch_rtp_destroy(&tech_pvt->rtp_session);
+ tech_pvt->rtp_session = NULL;
+ } else if (m_RTPlocalPort) {
+ switch_rtp_release_port((const char *)m_RTPlocalIP.AsString(), m_RTPlocalPort);
+ }
+
tech_pvt->me = NULL;
// switch_mutex_unlock(tech_pvt->h323_mutex);
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"------------->h323_mutex_unlock\n");
@@ -1148,7 +1156,7 @@ void FSH323Connection::AnsweringCall(AnswerCallResponse response)
if (!mediaWaitForConnect) {
// create a new facility PDU if doing AnswerDeferredWithMedia
H323SignalPDU want245PDU;
- //H225_Progress_UUIE & prog = want245PDU.BuildProgress(*this);
+ want245PDU.BuildProgress(*this);
PBoolean sendPDU = TRUE;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,"mediaWaitForConnect = FALSE\n");
/* if (SendFastStartAcknowledge(prog.m_fastStart)){
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