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