[Freeswitch-svn] [commit] r13989 - in freeswitch/trunk/contrib/mod/endpoints/mod_khomp: . commons
FreeSWITCH SVN
raulfragoso at freeswitch.org
Fri Jun 26 16:20:46 PDT 2009
Author: raulfragoso
Date: Fri Jun 26 18:20:45 2009
New Revision: 13989
Log:
Merge of changes from Khomp plus some minor changes in the code structure
Added:
freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/config_options.cpp
freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/config_options.hpp
freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/format.cpp
freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/format.hpp
freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/k3lapi.hpp
freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/strings.cpp
Modified:
freeswitch/trunk/contrib/mod/endpoints/mod_khomp/Makefile
freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/k3lapi.cpp
freeswitch/trunk/contrib/mod/endpoints/mod_khomp/mod_khomp.cpp
Modified: freeswitch/trunk/contrib/mod/endpoints/mod_khomp/Makefile
==============================================================================
--- freeswitch/trunk/contrib/mod/endpoints/mod_khomp/Makefile (original)
+++ freeswitch/trunk/contrib/mod/endpoints/mod_khomp/Makefile Fri Jun 26 18:20:45 2009
@@ -1,6 +1,8 @@
MODNAME=mod_khomp
-LOCAL_CFLAGS=-I./include -I./commons/include -lk3l -D_REENTRANT -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DK3L_HOSTSYSTEM
+VERBOSE=1
+LOCAL_CFLAGS=-I./include -I./commons -D_REENTRANT -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DK3L_HOSTSYSTEM
+LOCAL_LDFLAGS=-lk3l
+LOCAL_OBJS= ./commons/k3lapi.o ./commons/config_options.o ./commons/format.o ./commons/strings.o
+LOCAL_OBJS+= ./src/globals.o ./src/opt.o ./src/khomp_pvt.o
-LOCAL_OBJS= ./commons/k3lapi.o
-
-include ../../../build/modmake.rules
+include ../../../../build/modmake.rules
Added: freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/config_options.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/config_options.cpp Fri Jun 26 18:20:45 2009
@@ -0,0 +1,665 @@
+#include <config_options.hpp>
+
+config_option::config_option(std::string name, const config_option::string_type & value, const config_option::string_type defvalue, string_allowed_type allowed, bool list_me)
+: _my_name(name), _value_data(new string_data_type(const_cast<string_type &>(value), defvalue, allowed)),
+ _list_me(list_me), _values(NULL), _loaded(false)
+{};
+
+config_option::config_option(std::string name, const config_option::string_type & value, const config_option::string_type defvalue, bool list_me)
+: _my_name(name), _value_data(new string_data_type(const_cast<string_type &>(value), defvalue, string_allowed_type())),
+ _list_me(list_me), _values(NULL), _loaded(false)
+{};
+
+config_option::config_option(std::string name, const config_option::sint_type & value, const config_option::sint_type defvalue,
+ config_option::sint_type min, config_option::sint_type max, config_option::sint_type step, bool list_me)
+: _my_name(name), _value_data(new sint_data_type(const_cast<sint_type &>(value), defvalue, range<sint_type>(min, max, step))),
+ _list_me(list_me), _values(NULL), _loaded(false)
+{};
+
+config_option::config_option(std::string name, const config_option::uint_type & value, const config_option::uint_type defvalue,
+ config_option::uint_type min, config_option::uint_type max, config_option::uint_type step, bool list_me)
+: _my_name(name), _value_data(new uint_data_type(const_cast<uint_type &>(value), defvalue, range<uint_type>(min, max, step))),
+ _list_me(list_me), _values(NULL), _loaded(false)
+{};
+
+config_option::config_option(std::string name, const config_option::bool_type & value, const config_option::bool_type defvalue, bool list_me)
+: _my_name(name), _value_data(new bool_data_type(const_cast<bool_type &>(value), defvalue)),
+ _list_me(list_me), _values(NULL), _loaded(false)
+{};
+
+config_option::config_option(std::string name, config_option::fun_type fun, std::string defvalue, string_allowed_type allowed, bool list_me)
+: _my_name(name), _value_data(new fun_data_type(fun, defvalue, allowed)),
+ _list_me(list_me), _values(NULL), _loaded(false)
+{};
+
+config_option::config_option(std::string name, config_option::fun_type fun, std::string defvalue, bool list_me)
+: _my_name(name), _value_data(new fun_data_type(fun, defvalue, string_allowed_type())),
+ _list_me(list_me), _values(NULL), _loaded(false)
+{};
+
+config_option::~config_option(void)
+{
+ if (_values)
+ {
+ for (unsigned int i = 0; _values[i] != NULL; i++)
+ delete _values[i];
+
+ delete[] _values;
+ }
+};
+
+void config_option::set(config_option::string_type value)
+{
+ switch (_value_data.which())
+ {
+ case ID_STRING:
+ {
+ try
+ {
+ string_data_type & tmp = _value_data.get<string_data_type>();
+
+
+ if (tmp.string_allowed.empty())
+ {
+ tmp.string_val = value;
+ _loaded = true;
+ }
+ else
+ {
+ if (tmp.string_allowed.find(value) != tmp.string_allowed.end())
+ {
+ tmp.string_val = value;
+ _loaded = true;
+ return;
+ }
+
+ std::string allowed_string;
+
+ for (string_allowed_type::iterator i = tmp.string_allowed.begin(); i != tmp.string_allowed.end(); i++)
+ {
+ allowed_string += " '";
+ allowed_string += (*i);
+ allowed_string += "'";
+ }
+
+ throw config_process_failure(STG(FMT("value '%s' not allowed for option '%s' (allowed values:%s)")
+ % value % _my_name % allowed_string));
+ }
+ break;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+ }
+
+ case ID_FUN:
+ {
+ try
+ {
+ fun_data_type & tmp = _value_data.get<fun_data_type>();
+ tmp.fun_val(value);
+ _loaded = true;
+ break;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+
+ }
+
+ default:
+ {
+ throw config_process_failure(STG(FMT("option '%s' is not of type string, nor function defined") % _my_name));
+ }
+ }
+}
+
+void config_option::set(config_option::sint_type value)
+{
+ try
+ {
+ sint_data_type & tmp = _value_data.get<sint_data_type>();
+
+ if (value < tmp.sint_range.minimum)
+ throw config_process_failure(STG(FMT("value '%d' out-of-range for option '%s' (too low)") % value % _my_name));
+
+ if (value > tmp.sint_range.maximum)
+ throw config_process_failure(STG(FMT("value '%d' out-of-range for option '%s' (too high)") % value % _my_name));
+
+ if (((value - tmp.sint_range.minimum) % tmp.sint_range.step) != 0)
+ throw config_process_failure(STG(FMT("value '%d' out-of-range for option '%s' (outside allowed step)") % value % _my_name));
+
+ tmp.sint_val = value;
+ _loaded = true;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+}
+
+void config_option::set(config_option::uint_type value)
+{
+ try
+ {
+ uint_data_type & tmp = _value_data.get<uint_data_type>();
+
+ if (value < tmp.uint_range.minimum)
+ throw config_process_failure(STG(FMT("value '%d' out-of-range for option '%s' (too low)") % value % _my_name));
+
+ if (value > tmp.uint_range.maximum)
+ throw config_process_failure(STG(FMT("value '%d' out-of-range for option '%s' (too high)") % value % _my_name));
+
+ if (((value - tmp.uint_range.minimum) % tmp.uint_range.step) != 0)
+ throw config_process_failure(STG(FMT("value '%d' out-of-range for option '%s' (outside allowed step)") % value % _my_name));
+
+ tmp.uint_val = value;
+ _loaded = true;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+}
+
+void config_option::set(config_option::bool_type value)
+{
+ try
+ {
+ bool_data_type & tmp = _value_data.get<bool_data_type>();
+ tmp.bool_val = value;
+ _loaded = true;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+
+}
+
+std::string & config_option::name(void) { return _my_name; };
+
+config_option::value_id_type config_option::type(void)
+{
+ return (value_id_type) _value_data.which();
+};
+
+const char ** config_option::values(void)
+{
+ if (_values != NULL)
+ return _values;
+
+ switch ((value_id_type) _value_data.which())
+ {
+ case config_option::ID_BOOL:
+ {
+ _values = new const char*[3];
+
+ _values[0] = strdup("yes");
+ _values[1] = strdup("no");
+ _values[2] = NULL;
+
+ return _values;
+ }
+
+ case config_option::ID_SINT:
+ {
+ try
+ {
+ sint_data_type & tmp = _value_data.get<sint_data_type>();
+
+
+ unsigned int count = ((tmp.sint_range.maximum - tmp.sint_range.minimum) / tmp.sint_range.step) + 1;
+ unsigned int index = 0;
+
+ _values = new const char*[count + 1];
+
+ for (sint_type i = tmp.sint_range.minimum; i <= tmp.sint_range.maximum; i += tmp.sint_range.step, index++)
+ _values[index] = strdup(STG(FMT("%d") % i).c_str());
+
+ _values[index] = NULL;
+
+ return _values;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+ }
+
+ case config_option::ID_UINT:
+ {
+ try
+ {
+ uint_data_type & tmp = _value_data.get<uint_data_type>();
+
+ unsigned int count = ((tmp.uint_range.maximum - tmp.uint_range.minimum) / tmp.uint_range.step) + 1;
+ unsigned int index = 0;
+
+ _values = new const char*[count + 1];
+
+ for (uint_type i = tmp.uint_range.minimum; i <= tmp.uint_range.maximum; i += tmp.uint_range.step, index++)
+ _values[index] = strdup(STG(FMT("%d") % i).c_str());
+
+ _values[index] = NULL;
+
+ return _values;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+ }
+
+ case config_option::ID_STRING:
+ {
+ try
+ {
+ string_data_type & tmp = _value_data.get<string_data_type>();
+
+ _values = new const char*[ tmp.string_allowed.size() + 1 ];
+
+ unsigned int index = 0;
+
+ for (string_allowed_type::iterator i = tmp.string_allowed.begin(); i != tmp.string_allowed.end(); i++, index++)
+ _values[index] = strdup((*i).c_str());
+
+ _values[index] = NULL;
+
+ return _values;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+ }
+
+ case config_option::ID_FUN:
+ {
+ try
+ {
+ fun_data_type & tmp = _value_data.get<fun_data_type>();
+
+ _values = new const char*[ tmp.fun_allowed.size() + 1 ];
+
+ unsigned int index = 0;
+
+ for (string_allowed_type::iterator i = tmp.fun_allowed.begin(); i != tmp.fun_allowed.end(); i++, index++)
+ _values[index] = strdup((*i).c_str());
+
+ _values[index] = NULL;
+ return _values;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+
+ }
+
+ default:
+ throw config_process_failure(STG(FMT("unknown type identifier '%d'") % _value_data.which()));
+ }
+};
+
+void config_option::reset(void)
+{
+ _loaded = false;
+};
+
+void config_option::commit(void)
+{
+ if (_loaded)
+ return;
+
+ switch ((value_id_type) _value_data.which())
+ {
+ case config_option::ID_BOOL:
+ {
+ try
+ {
+ bool_data_type & tmp = _value_data.get<bool_data_type>();
+ tmp.bool_val = tmp.bool_default;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+
+ break;
+ }
+
+ case config_option::ID_SINT:
+ {
+ try
+ {
+ sint_data_type & tmp = _value_data.get<sint_data_type>();
+ tmp.sint_val = tmp.sint_default;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+ break;
+ }
+
+ case config_option::ID_UINT:
+ {
+ try
+ {
+ uint_data_type & tmp = _value_data.get<uint_data_type>();
+ tmp.uint_val = tmp.uint_default;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+ break;
+ }
+
+ case config_option::ID_STRING:
+ {
+ try
+ {
+ string_data_type & tmp = _value_data.get<string_data_type>();
+ tmp.string_val = tmp.string_default;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+ break;
+ }
+
+ case config_option::ID_FUN:
+ {
+ try
+ {
+ fun_data_type & tmp = _value_data.get<fun_data_type>();
+ tmp.fun_val(tmp.fun_default);
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+ break;
+ }
+
+ default:
+ throw config_process_failure(STG(FMT("unknown type identifier '%d'") % _value_data.which()));
+ }
+
+ _loaded = true;
+};
+
+void config_option::copy_from(config_option & src)
+{
+ if (src._value_data.which() != _value_data.which())
+ throw config_process_failure(STG(FMT("unable to copy options, source type differs from destination.")));
+
+ if (!src._loaded)
+ return;
+
+ switch ((value_id_type) _value_data.which())
+ {
+ case config_option::ID_BOOL:
+ {
+ try
+ {
+ bool_data_type & stmp = src._value_data.get<bool_data_type>();
+ bool_data_type & dtmp = _value_data.get<bool_data_type>();
+ /* do not copy references, but values.. */
+ bool tmpval = stmp.bool_val;
+ dtmp.bool_val = tmpval;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+
+ break;
+ }
+
+ case config_option::ID_SINT:
+ {
+ try
+ {
+ sint_data_type & stmp = src._value_data.get<sint_data_type>();
+ sint_data_type & dtmp = _value_data.get<sint_data_type>();
+ /* do not copy references, but values.. */
+ int tmpval = stmp.sint_val;
+ dtmp.sint_val = tmpval;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+
+ break;
+ }
+
+ case config_option::ID_UINT:
+ {
+ try
+ {
+ uint_data_type & stmp = src._value_data.get<uint_data_type>();
+ uint_data_type & dtmp = _value_data.get<uint_data_type>();
+ /* do not copy references, but values.. */
+ unsigned int tmpval = stmp.uint_val;
+ dtmp.uint_val = tmpval;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+
+
+ break;
+ }
+
+ case config_option::ID_STRING:
+ {
+ try
+ {
+ string_data_type & stmp = src._value_data.get<string_data_type>();
+ string_data_type & dtmp = _value_data.get<string_data_type>();
+ /* do not copy references, but values.. */
+ std::string tmpval = stmp.string_val;
+ dtmp.string_val = tmpval;
+ }
+ catch(value_type::InvalidType & e)
+ {
+ throw;
+ }
+
+ break;
+ }
+
+ case config_option::ID_FUN:
+ {
+ /* TO IMPLEMENT (NEEDS ANOTHER METHOD ON FUNCTION FOR GETTING VALUE) */
+
+// fun_data_type & tmp = boost::get<fun_data_type>(_value_data);
+//
+// if (!tmp.loaded)
+// {
+// tmp.fun_val(tmp.fun_default);
+// tmp.loaded = true;
+// }
+ break;
+ }
+
+ default:
+ throw config_process_failure(STG(FMT("unknown type identifier '%d'") % _value_data.which()));
+ }
+
+ _loaded = true;
+};
+
+/*********************************/
+
+bool config_options::add(config_option option)
+{
+ //option_map_type::iterator iter2 = _map.begin();
+
+ //boost::tie(iter2, ok2)
+ std::pair<option_map_type::iterator, bool> ret = _map.insert(option_pair_type(option.name(), option));
+
+ return ret.second;
+}
+
+bool config_options::synonym(std::string equiv_opt, std::string main_opt)
+{
+ //syn_option_map_type::iterator iter = _syn_map.begin();
+
+ //boost::tie(iter, ok)
+ std::pair<syn_option_map_type::iterator, bool> ret = _syn_map.insert(syn_option_pair_type(equiv_opt, main_opt));
+
+ return ret.second;
+}
+
+config_options::string_set config_options::options(void)
+{
+ string_set res;
+
+ for (option_map_type::iterator i = _map.begin(); i != _map.end(); i++)
+ res.insert((*i).first);
+
+ return res;
+}
+
+void config_options::process(const char * name, const char * value)
+{
+ option_map_type::iterator iter = find_option(name);
+
+ if (iter == _map.end())
+ throw config_process_failure(STG(FMT("unknown option '%s'") % name));
+
+ try
+ {
+ switch ((*iter).second.type())
+ {
+ case config_option::ID_SINT:
+ set<config_option::sint_type>((*iter).first, Strings::toulong(value));
+ return;
+ case config_option::ID_UINT:
+ set<config_option::uint_type>((*iter).first, Strings::tolong(value));
+ return;
+ case config_option::ID_BOOL:
+ set<config_option::bool_type>((*iter).first, Strings::toboolean(value));
+ return;
+ case config_option::ID_STRING:
+ case config_option::ID_FUN:
+ set<config_option::string_type>((*iter).first, std::string(value));
+ return;
+ default:
+ throw config_process_failure(STG(FMT("unknown type identifier '%d'") % (*iter).second.type()));
+ }
+ }
+ catch (Strings::invalid_value e)
+ {
+ throw config_process_failure(STG(FMT("invalid value '%s' for option '%s'") % value % name));
+ }
+}
+
+const char ** config_options::values(const char * name)
+{
+ option_map_type::iterator iter = find_option(name);
+
+ if (iter == _map.end())
+ throw config_process_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 (option_map_type::iterator i = _map.begin(); i != _map.end(); i++)
+ if ((*i).second.list_me())
+ ++count;
+
+ _values = new const char*[ count + 1 ];
+
+ unsigned int index = 0;
+
+ for (option_map_type::iterator i = _map.begin(); i != _map.end(); i++)
+ {
+ if ((*i).second.list_me())
+ {
+ _values[index] = strdup((*i).first.c_str());
+ ++index;
+ }
+ }
+
+ _values[index] = NULL;
+
+ return _values;
+}
+
+void config_options::reset(void)
+{
+ for (option_map_type::iterator i = _map.begin(); i != _map.end(); i++)
+ (*i).second.reset();
+}
+
+config_options::messages_type config_options::commit(void)
+{
+ messages_type msgs;
+
+ for (option_map_type::iterator i = _map.begin(); i != _map.end(); i++)
+ {
+ try
+ {
+ (*i).second.commit();
+ }
+ catch (config_process_failure e)
+ {
+ msgs.push_back(e.msg);
+ }
+ }
+
+ return msgs;
+}
+
+bool config_options::loaded(std::string name)
+{
+ option_map_type::iterator iter = find_option(name);
+
+ if (iter == _map.end())
+ return false;
+
+ return iter->second.loaded();
+}
+
+void config_options::copy_from(config_options & source, std::string name)
+{
+ option_map_type::iterator iter_src = source.find_option(name);
+ option_map_type::iterator iter_dst = find_option(name);
+
+ if (iter_src == source._map.end())
+ throw config_process_failure(STG(FMT("unknown option '%s' on source") % name));
+
+ if (iter_dst == _map.end())
+ throw config_process_failure(STG(FMT("unknown option '%s' on destination") % name));
+
+ iter_dst->second.copy_from(iter_src->second);
+}
+
+config_options::option_map_type::iterator config_options::find_option(std::string name)
+{
+ syn_option_map_type::iterator syn_iter = _syn_map.find(name);
+
+ if (syn_iter != _syn_map.end())
+ name = syn_iter->second;
+
+ option_map_type::iterator iter = _map.find(name);
+
+ return iter;
+}
Added: freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/config_options.hpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/config_options.hpp Fri Jun 26 18:20:45 2009
@@ -0,0 +1,281 @@
+#include <set>
+#include <map>
+#include <vector>
+
+#include <strings.hpp>
+
+#include <format.hpp>
+
+#ifndef INCLUDED_CONFIG_OPTIONS
+#define INCLUDED_CONFIG_OPTIONS
+
+template < typename base_type >
+struct Variant
+{
+ struct InvalidType {};
+
+ Variant(base_type * value) : _value(value)
+ {
+ _count = new int(1);
+ };
+
+ Variant(const Variant & v) : _value(v._value), _count(v._count)
+ {
+
+ (*_count)++;
+ }
+
+ ~Variant()
+ {
+ (*_count)--;
+ if (_value && !(*_count))
+ {
+ delete _value;
+ delete _count;
+ }
+ };
+
+ template < typename return_type >
+ return_type & get(void)
+ {
+ try
+ {
+ return_type & ret = dynamic_cast < return_type & > (*_value);
+ return ret;
+ }
+ catch (std::bad_cast & e)
+ {
+ throw InvalidType();
+ }
+
+ };
+
+ int which()
+ {
+ return _value->which();
+ }
+
+ protected:
+ base_type * _value;
+ int *_count;
+};
+
+struct config_process_failure
+{
+ config_process_failure(std::string _msg): msg(_msg) {};
+ std::string msg;
+};
+
+struct config_option
+{
+ typedef int sint_type;
+ typedef unsigned int uint_type;
+ typedef bool bool_type;
+
+ typedef std::string string_type;
+ //typedef boost::function1<void, std::string>
+ typedef void (*fun_type)(std::string);
+
+ typedef std::set < string_type > string_allowed_type;
+
+ /* this should reflect 'variant.which()'! */
+ typedef enum
+ {
+ ID_SINT = 0,
+ ID_UINT = 1,
+ ID_BOOL = 2,
+ ID_STRING = 3,
+ ID_FUN = 4,
+ }
+ value_id_type;
+
+ template <typename number_type>
+ struct range
+ {
+ range(number_type _minimum, number_type _maximum, number_type _step)
+ : minimum(_minimum), maximum(_maximum), step(_step) {};
+
+ number_type minimum, maximum, step;
+ };
+
+ struct BaseType
+ {
+ BaseType() {}
+
+ virtual ~BaseType() {}
+
+ virtual int which() = 0;
+ };
+
+ struct sint_data_type : public BaseType
+ {
+ sint_data_type(sint_type & _sint_val, sint_type _sint_default, range<sint_type> _sint_range)
+ : sint_val(_sint_val), sint_default(_sint_default), sint_range(_sint_range) {};
+
+ int which()
+ {
+ return ID_SINT;
+ }
+
+ sint_type & sint_val;
+ sint_type sint_default;
+ range<sint_type> sint_range;
+ };
+
+ struct uint_data_type : public BaseType
+ {
+ uint_data_type(uint_type & _uint_val, uint_type _uint_default, range<uint_type> _uint_range)
+ : uint_val(_uint_val), uint_default(_uint_default), uint_range(_uint_range) {};
+
+ int which()
+ {
+ return ID_UINT;
+ }
+
+ uint_type & uint_val;
+ uint_type uint_default;
+ range<uint_type> uint_range;
+ };
+
+ struct bool_data_type : public BaseType
+ {
+ bool_data_type(bool_type & _bool_val, bool_type _bool_default)
+ : bool_val(_bool_val), bool_default(_bool_default) {};
+
+ int which()
+ {
+ return ID_BOOL;
+ }
+
+ bool_type & bool_val;
+ bool_type bool_default;
+ };
+
+ struct string_data_type : public BaseType
+ {
+ string_data_type(std::string & _string_val, std::string _string_default, string_allowed_type _string_allowed)
+ : string_val(_string_val), string_default(_string_default), string_allowed(_string_allowed) {};
+
+ int which()
+ {
+ return ID_STRING;
+ }
+
+ std::string & string_val;
+ std::string string_default;
+ string_allowed_type string_allowed;
+ };
+
+ struct fun_data_type : public BaseType
+ {
+ fun_data_type(fun_type _fun_val, std::string _fun_default, string_allowed_type _fun_allowed)
+ : fun_val(_fun_val), fun_default(_fun_default), fun_allowed(_fun_allowed) {};
+
+ int which()
+ {
+ return ID_FUN;
+ }
+
+ fun_type fun_val;
+ std::string fun_default;
+ string_allowed_type fun_allowed;
+ };
+
+
+ typedef Variant < BaseType > value_type;
+ //typedef boost::variant < sint_data_type , uint_data_type, bool_data_type, string_data_type, fun_data_type > value_type;
+
+ config_option(std::string, const string_type &, const string_type, string_allowed_type allowed, bool list_me = true);
+ config_option(std::string, const string_type &, const string_type = "", bool list_me = true);
+ config_option(std::string, const sint_type &, const sint_type = 0, sint_type min = -INT_MAX, sint_type max = INT_MAX, sint_type step = 1, bool list_me = true);
+ config_option(std::string, const uint_type &, const uint_type = 0, uint_type min = 0, uint_type max = UINT_MAX, uint_type step = 1, bool list_me = true);
+ config_option(std::string, const bool_type &, const bool_type = false, bool list_me = true);
+ config_option(std::string, fun_type, std::string defvalue, string_allowed_type allowed, bool list_me = true);
+ config_option(std::string, fun_type, std::string defvalue = "", bool list_me = true);
+
+ ~config_option(void);
+
+ void set(string_type value);
+
+ void set(sint_type value);
+ void set(uint_type value);
+ void set(bool_type value);
+
+ std::string & name(void);
+ value_id_type type(void);
+
+ const char ** values(void);
+
+ void reset(void);
+ void commit(void);
+
+ bool list_me(void) { return _list_me; };
+ bool loaded(void) { return _loaded; };
+
+ void copy_from(config_option &);
+
+ protected:
+ std::string _my_name;
+ value_type _value_data;
+
+ bool _list_me;
+ const char ** _values;
+ bool _loaded;
+};
+
+struct config_options
+{
+ typedef std::vector < std::string > messages_type;
+
+ config_options(void): _values(NULL) {};
+
+ typedef std::set < std::string > string_set;
+
+ typedef std::map < std::string, config_option > option_map_type;
+ typedef std::pair < std::string, config_option > option_pair_type;
+
+ typedef std::map < std::string, std::string > syn_option_map_type;
+ typedef std::pair < std::string, std::string > syn_option_pair_type;
+
+ bool add(config_option option);
+
+ /* only valid in "process" (for backwards compatibility config files) */
+ bool synonym(std::string, std::string);
+
+ template <typename value_type>
+ void set(std::string name, value_type value)
+ {
+ option_map_type::iterator iter = _map.find(name);
+
+ if (iter == _map.end())
+ throw config_process_failure(STG(FMT("unknown option: %s") % name));
+
+ (*iter).second.set(value);
+ }
+
+ string_set options(void);
+
+ void process(const char *, const char *); /* process option from file */
+
+ void reset(void); /* reset loaded opts */
+ messages_type commit(void); /* set defaults */
+
+ const char ** values(const char *); /* option value */
+ const char ** values(void); /* values from options */
+
+ bool loaded(std::string); /* return if config was loaded */
+
+ void copy_from(config_options &, std::string);
+
+ protected:
+ option_map_type::iterator find_option(std::string);
+
+ protected:
+ option_map_type _map;
+ syn_option_map_type _syn_map;
+
+ const char ** _values;
+};
+
+#endif /* INCLUDED_CONFIG_OPTIONS */
+
Added: freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/format.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/format.cpp Fri Jun 26 18:20:45 2009
@@ -0,0 +1,208 @@
+#include "format.hpp"
+
+const char * Format::INVALID_MSG = "** Invalid Format **";
+
+
+Format::Format(const char * fmt, bool exception)
+ : _valid(true), _exception(exception)
+{
+ std::string text;
+ std::string arg;
+
+ const char * ptr = fmt;
+
+ while(*ptr != '\0')
+ {
+ if (*ptr != '%')
+ {
+ text += *ptr;
+ ptr++;
+ continue;
+ }
+ else if(*(ptr+1) == '%')
+ {
+ text += *ptr;
+ ptr++;
+ text += *ptr;
+ ptr++;
+ continue;
+ }
+
+ _args.push(new Argument(text, "text"));
+
+ text.clear();
+
+ arg += *ptr;
+
+ bool finished = false;
+
+ ptr++;
+
+ while(*ptr != '\0' && !finished)
+ {
+
+ Argument * argument;
+
+ switch (*ptr)
+ {
+ case ' ':
+ arg += *ptr;
+ _args.push(new Argument(arg, "text"));
+ arg.clear();
+ finished = true;
+ break;
+
+ case '%':
+ _args.push(new Argument(arg, "text"));
+ arg.clear();
+ arg += *ptr;
+ break;
+
+ case 'h':
+ arg += *ptr;
+ break;
+
+ case 'l':
+ arg += *ptr;
+ break;
+
+ case 'd':
+ case 'i':
+ arg += *ptr;
+ argument = new Argument(arg, typeid(int).name());
+ argument->type(typeid(unsigned int).name());
+ _args.push(argument);
+ argument = NULL;
+ arg.clear();
+ finished = true;
+ break;
+
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ arg += *ptr;
+ argument = new Argument(arg, typeid(unsigned int).name());
+ argument->type(typeid(int).name());
+ _args.push(argument);
+ argument = NULL;
+ arg.clear();
+ finished = true;
+ break;
+
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ case 'a':
+ case 'A':
+ arg += *ptr;
+ argument = new Argument(arg, typeid(double).name());
+ argument->type(typeid(float).name());
+ _args.push(argument);
+ argument = NULL;
+ arg.clear();
+ finished = true;
+ break;
+
+ case 'c':
+ arg += *ptr;
+ argument = new Argument(arg, typeid(char).name());
+ argument->type(typeid(unsigned char).name());
+ _args.push(argument);
+ argument = NULL;
+ arg.clear();
+ finished = true;
+ break;
+
+ case 's':
+ arg += *ptr;
+ argument = new Argument(arg, typeid(const char *).name());
+ argument->type(typeid(char *).name());
+ argument->type(typeid(const unsigned char *).name());
+ argument->type(typeid(unsigned char *).name());
+ _args.push(argument);
+ argument = NULL;
+ arg.clear();
+ finished = true;
+ break;
+
+ case 'p':
+ case 'C':
+ case 'S':
+ case 'n':
+ case 'm':
+ arg += *ptr;
+ _args.push(new Argument(arg, ""));
+ arg.clear();
+ finished = true;
+ break;
+ default:
+ arg += *ptr;
+ break;
+ }
+
+ ptr++;
+
+ }
+ }
+
+ if(!text.empty())
+ _args.push(new Argument(text, "text"));
+
+ if(!arg.empty())
+ _args.push(new Argument(arg, "text"));
+
+}
+
+std::string Format::str()
+{
+
+ if(!_valid)
+ {
+ if(_exception)
+ throw InvalidFormat(INVALID_MSG);
+
+ _result.clear();
+ _result += INVALID_MSG;
+ return _result;
+ }
+
+ Argument * top;
+ bool text;
+
+ do
+ {
+ text = false;
+
+ if(_args.empty())
+ return _result;
+
+ top = _args.front();
+ _args.pop();
+
+ if(top->compare("text"))
+ {
+ _result += top->fmts();
+ text = true;
+ free(top);
+ }
+
+ }
+ while(text);
+
+ free(top);
+
+ _valid = false;
+
+ if(_exception)
+ throw InvalidFormat(INVALID_MSG);
+
+ _result.clear();
+ _result += INVALID_MSG;
+ return _result;
+}
+
+
Added: freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/format.hpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/format.hpp Fri Jun 26 18:20:45 2009
@@ -0,0 +1,183 @@
+#ifndef _FORMAT_H_
+#define _FORMAT_H_
+
+#include <string>
+#include <queue>
+#include <set>
+#include <typeinfo>
+#include <cstring>
+#include <cstdlib>
+
+/* macros used for shortening lines and making the code clearer */
+#define STG(x) (x).str()
+#define FMT(x) Format(x)
+
+struct Format
+{
+ static const char * INVALID_MSG;
+
+ struct Argument
+ {
+ typedef std::set < std::string > StringSet;
+
+ Argument(std::string init_fmts, std::string init_type)
+ : _fmts(init_fmts)
+ {
+ _types.insert(init_type);
+ };
+
+ void type(std::string t)
+ {
+ _types.insert(t);
+ }
+
+ bool compare(const char * type)
+ {
+ for(StringSet::iterator it = _types.begin(); it != _types.end(); it++)
+ {
+ if(!strcmp(type, (*it).c_str()))
+ return true;
+ }
+ return false;
+ }
+
+ std::string fmts()
+ {
+ return _fmts;
+ }
+
+ protected:
+ std::string _fmts;
+ StringSet _types;
+ };
+
+ struct InvalidFormat
+ {
+ InvalidFormat(std::string msg) : _msg(msg) {}
+
+ std::string _msg;
+ };
+
+
+ typedef std::queue < Argument *> ArgumentsQueue;
+
+ Format(const char * fmt, bool exception = false);
+
+ std::string str();
+
+ template < typename Type >
+ Format & operator % ( Type value )
+ {
+ Argument * top;
+ bool text;
+
+ do
+ {
+ text = false;
+
+ if(_args.empty()) {
+ _valid = false;
+ if(_exception)
+ throw InvalidFormat(INVALID_MSG);
+ return *this;
+ }
+
+ top = _args.front();
+ _args.pop();
+
+ if(top->compare("text"))
+ {
+ _result += top->fmts();
+ text = true;
+ free(top);
+ }
+
+ }
+ while(text);
+
+ char tmp[1000];
+
+ if(top->compare(""))
+ {
+ snprintf(tmp, 1000, top->fmts().c_str(), value);
+ _result += tmp;
+ }
+ else if (top->compare(typeid(Type).name()))
+ {
+ snprintf(tmp, 1000, top->fmts().c_str(), value);
+ _result += tmp;
+ }
+ else
+ {
+ free(top);
+ _valid = false;
+ if(_exception)
+ throw InvalidFormat(INVALID_MSG);
+ return *this;
+ }
+
+ free(top);
+
+ return *this;
+ }
+
+Format & operator%( std::string & value )
+{
+ Argument * top;
+ bool text;
+
+ do
+ {
+ text = false;
+
+ if(_args.empty()) {
+ _valid = false;
+ if(_exception)
+ throw InvalidFormat(INVALID_MSG);
+ return *this;
+ }
+
+ top = _args.front();
+ _args.pop();
+
+ if(top->compare("text"))
+ {
+ _result += top->fmts();
+ text = true;
+ free(top);
+ }
+
+ }
+ while(text);
+
+ char tmp[1000];
+
+ if (top->compare(typeid(char *).name()))
+ {
+ snprintf(tmp, 1000, top->fmts().c_str(), value.c_str());
+ _result += tmp;
+ }
+ else
+ {
+ free(top);
+ _valid = false;
+ if(_exception)
+ throw InvalidFormat(INVALID_MSG);
+ return *this;
+ }
+
+ free(top);
+
+ return *this;
+}
+
+private:
+ bool _valid;
+ bool _exception;
+ std::string _result;
+ ArgumentsQueue _args;
+
+};
+
+#endif /* _FORMAT_H_ */
+
Modified: freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/k3lapi.cpp
==============================================================================
--- freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/k3lapi.cpp (original)
+++ freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/k3lapi.cpp Fri Jun 26 18:20:45 2009
@@ -7,169 +7,165 @@
K3LAPI::~K3LAPI()
{
- _device_count = 0;
-
- if (_device_type) { delete[] _device_type; _device_type = NULL; }
- if (_device_config) { delete[] _device_config; _device_config = NULL; }
- if (_channel_config) { delete[] _channel_config; _channel_config = NULL; }
- if (_link_config) { delete[] _link_config; _link_config = NULL; }
- if (_channel_count) { delete[] _channel_count; _channel_count = NULL; }
- if (_link_count) { delete[] _link_count; _link_count = NULL; }
+ _device_count = 0;
+
+ if (_device_type) { delete[] _device_type; _device_type = NULL; }
+ if (_device_config) { delete[] _device_config; _device_config = NULL; }
+ if (_channel_config) { delete[] _channel_config; _channel_config = NULL; }
+ if (_link_config) { delete[] _link_config; _link_config = NULL; }
+ if (_channel_count) { delete[] _channel_count; _channel_count = NULL; }
+ if (_link_count) { delete[] _link_count; _link_count = NULL; }
}
/* initialize the whole thing! */
-
+
void K3LAPI::start(void)
{
- /* tie the used k3l to the compiled k3l version */
- char *ret = k3lStart(2, 0, 0); //k3lApiMajorVersion, k3lApiMinorVersion, 0); //k3lApiBuildVersion);
-
- if (ret && *ret)
- throw start_failed(ret);
-
- /* call init automagically */
- init();
+ /* tie the used k3l to the compiled k3l version */
+ char *ret = k3lStart(2, 0, 0); //k3lApiBuildVersion);
+
+ if (ret && *ret)
+ throw start_failed(ret);
+
+ /* call init automagically */
+ init();
}
void K3LAPI::stop(void)
{
- k3lStop();
+ k3lStop();
}
/* envio de comandos para placa */
-
+
void K3LAPI::mixer(int32 dev, int32 obj, byte track, KMixerSource src, int32 index)
{
- KMixerCommand mix;
+ KMixerCommand mix;
mix.Track = track;
- mix.Source = src;
+ mix.Source = src;
mix.SourceIndex = index;
- command(dev, obj, CM_MIXER, (const char *) &mix);
+ command(dev, obj, CM_MIXER, (const char *) &mix);
}
void K3LAPI::mixerCTbus(int32 dev, int32 obj, byte track, KMixerSource src, int32 index)
{
- KMixerCommand mix;
+ KMixerCommand mix;
mix.Track = track;
- mix.Source = src;
+ mix.Source = src;
mix.SourceIndex = index;
- command(dev, obj, CM_MIXER_CTBUS, (const char *) &mix);
+ command(dev, obj, CM_MIXER_CTBUS, (const char *) &mix);
}
void K3LAPI::command(int32 dev, int32 obj, int32 code, std::string & str)
{
- command(dev, obj, code, str.c_str());
+ command(dev, obj, code, str.c_str());
}
void K3LAPI::command (int32 dev, int32 obj, int32 code, const char * parms)
{
K3L_COMMAND cmd;
- cmd.Cmd = code;
+ cmd.Cmd = code;
cmd.Object = obj;
- cmd.Params = (byte *)parms;
+ cmd.Params = (byte *)parms;
- int32 rc = k3lSendCommand(dev, &cmd);
-
- if (rc != ksSuccess)
- throw failed_command(code, dev, obj, rc);
+ int32 rc = k3lSendCommand(dev, &cmd);
+
+ if (rc != ksSuccess)
+ throw failed_command(code, dev, obj, rc);
}
void K3LAPI::raw_command(int32 dev, int32 dsp, std::string & str)
{
- raw_command(dev, dsp, str.data(), str.size());
+ raw_command(dev, dsp, str.data(), str.size());
}
void K3LAPI::raw_command(int32 dev, int32 dsp, const char * cmds, int32 size)
{
std::string str(cmds, size);
- int32 rc = k3lSendRawCommand(dev, dsp, (void *)cmds, size);
+ int32 rc = k3lSendRawCommand(dev, dsp, (void *)cmds, size);
- if (rc != ksSuccess)
- throw failed_raw_command(dev, dsp, rc);
+ if (rc != ksSuccess)
+ throw failed_raw_command(dev, dsp, rc);
}
KLibraryStatus K3LAPI::get_param(K3L_EVENT *ev, const char *name, std::string &res)
{
- char tmp_param[256];
- memset((void*)tmp_param, 0, sizeof(tmp_param));
+ char tmp_param[256];
+ memset((void*)tmp_param, 0, sizeof(tmp_param));
- int32 rc = k3lGetEventParam (ev, (sbyte *)name, (sbyte *)tmp_param, sizeof(tmp_param)-1);
-
- if (rc != ksSuccess)
- return (KLibraryStatus)rc;
+ int32 rc = k3lGetEventParam (ev, (sbyte *)name, (sbyte *)tmp_param, sizeof(tmp_param)-1);
+
+ if (rc != ksSuccess)
+ return (KLibraryStatus)rc;
- res.append(tmp_param, strlen(tmp_param));
- return ksSuccess;
+ res.append(tmp_param, strlen(tmp_param));
+ return ksSuccess;
}
-
+
std::string K3LAPI::get_param(K3L_EVENT *ev, const char *name)
{
- std::string res;
+ std::string res;
- KLibraryStatus rc = get_param(ev, name, res);
+ KLibraryStatus rc = get_param(ev, name, res);
- if (rc != ksSuccess)
- throw get_param_failed(name, rc);
-
- return res;
+ if (rc != ksSuccess)
+ throw get_param_failed(name, rc);
+
+ return res;
}
void K3LAPI::init(void)
{
- if (_device_count != 0) return;
+ if (_device_count != 0) return;
- _device_count = k3lGetDeviceCount();
+ _device_count = k3lGetDeviceCount();
- _device_type = new KDeviceType[_device_count];
- _device_config = new device_conf_type[_device_count];
- _channel_config = new channel_ptr_conf_type[_device_count];
- _KChannel = new KChannel_ptr_t[_device_count];
- _link_config = new link_ptr_conf_type[_device_count];
- _channel_count = new unsigned int[_device_count];
- _link_count = new unsigned int[_device_count];
-
- for (unsigned int dev = 0; dev < _device_count; dev++)
- {
- _device_type[dev] = (KDeviceType) k3lGetDeviceType(dev);
-
- /* caches each device config */
- if (k3lGetDeviceConfig(dev, ksoDevice + dev, &(_device_config[dev]), sizeof(_device_config[dev])) != ksSuccess)
- throw start_failed("k3lGetDeviceConfig(device)");
-
- /* adjust channel/link count for device */
- _channel_count[dev] = _device_config[dev].ChannelCount;
- _link_count[dev] = _device_config[dev].LinkCount;
-
- /* caches each channel config */
- _channel_config[dev] = new channel_conf_type[_channel_count[dev]];
- _KChannel[dev] = new KChannel_t[_channel_count[dev]];
-
- for (unsigned int obj = 0; obj < _channel_count[dev]; obj++)
- {
- if (k3lGetDeviceConfig(dev, ksoChannel + obj, &(_channel_config[dev][obj]),
- sizeof(_channel_config[dev][obj])) != ksSuccess)
- {
- throw start_failed("k3lGetDeviceConfig(channel)");
- }
- }
-
- /* adjust link count for device */
- _link_count[dev] = _device_config[dev].LinkCount;
-
- /* caches each link config */
- _link_config[dev] = new link_conf_type[_link_count[dev]];
-
- for (unsigned int obj = 0; obj < _link_count[dev]; obj++)
- {
- if (k3lGetDeviceConfig(dev, ksoLink + obj, &(_link_config[dev][obj]),
- sizeof(_link_config[dev][obj])) != ksSuccess)
- throw start_failed("k3lGetDeviceConfig(link)");
- }
- }
+ _device_type = new KDeviceType[_device_count];
+ _device_config = new device_conf_type[_device_count];
+ _channel_config = new channel_ptr_conf_type[_device_count];
+ _link_config = new link_ptr_conf_type[_device_count];
+ _channel_count = new unsigned int[_device_count];
+ _link_count = new unsigned int[_device_count];
+
+ for (unsigned int dev = 0; dev < _device_count; dev++)
+ {
+ _device_type[dev] = (KDeviceType) k3lGetDeviceType(dev);
+
+ /* caches each device config */
+ if (k3lGetDeviceConfig(dev, ksoDevice + dev, &(_device_config[dev]), sizeof(_device_config[dev])) != ksSuccess)
+ throw start_failed("k3lGetDeviceConfig(device)");
+
+ /* adjust channel/link count for device */
+ _channel_count[dev] = _device_config[dev].ChannelCount;
+ _link_count[dev] = _device_config[dev].LinkCount;
+
+ /* caches each channel config */
+ _channel_config[dev] = new channel_conf_type[_channel_count[dev]];
+
+ for (unsigned int obj = 0; obj < _channel_count[dev]; obj++)
+ {
+ if (k3lGetDeviceConfig(dev, ksoChannel + obj, &(_channel_config[dev][obj]),
+ sizeof(_channel_config[dev][obj])) != ksSuccess)
+ throw start_failed("k3lGetDeviceConfig(channel)");
+ }
+
+ /* adjust link count for device */
+ _link_count[dev] = _device_config[dev].LinkCount;
+
+ /* caches each link config */
+ _link_config[dev] = new link_conf_type[_link_count[dev]];
+
+ for (unsigned int obj = 0; obj < _link_count[dev]; obj++)
+ {
+ if (k3lGetDeviceConfig(dev, ksoLink + obj, &(_link_config[dev][obj]),
+ sizeof(_link_config[dev][obj])) != ksSuccess)
+ throw start_failed("k3lGetDeviceConfig(link)");
+ }
+ }
}
Added: freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/k3lapi.hpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/k3lapi.hpp Fri Jun 26 18:20:45 2009
@@ -0,0 +1,309 @@
+#include <string>
+
+#include <k3l.h>
+
+/* if using full k3l.h (for softpbx), version already defined. */
+#ifndef k3lApiMajorVersion
+# include <k3lVersion.h>
+#endif
+
+#ifdef __GNUC_PREREQ
+#if __GNUC_PREREQ(4,3)
+#include <cstring>
+#endif
+#endif
+
+#ifndef INCLUDED_K3LAPI_HPP
+#define INCLUDED_K3LAPI_HPP
+
+struct K3LAPI
+{
+ /* exceptions */
+
+ struct start_failed
+ {
+ start_failed(const char * _msg) : msg(_msg) {};
+ std::string msg;
+ };
+
+ struct failed_command
+ {
+ failed_command(int32 _code, unsigned short _dev, unsigned short _obj, int32 _rc)
+ : code(_code), dev(_dev), obj(_obj), rc(_rc) {};
+
+ int32 code;
+ unsigned short dev;
+ unsigned short obj;
+ int32 rc;
+ };
+
+ struct failed_raw_command
+ {
+ failed_raw_command(unsigned short _dev, unsigned short _dsp, int32 _rc)
+ : dev(_dev), dsp(_dsp), rc(_rc) {};
+
+ unsigned short dev;
+ unsigned short dsp;
+ int32 rc;
+ };
+
+ struct invalid_session
+ {
+ invalid_session(unsigned int _device, unsigned int _channel)
+ : device(_device), channel(_channel) {};
+
+ unsigned int device;
+ unsigned int channel;
+ };
+
+ struct invalid_device
+ {
+ invalid_device(int32 _device)
+ : device(_device) {};
+
+ int32 device;
+ };
+
+ struct invalid_channel
+ {
+ invalid_channel(int32 _device, int32 _channel)
+ : device(_device), channel(_channel) {};
+
+ int32 device, channel;
+ };
+
+ struct invalid_link
+ {
+ invalid_link(unsigned int _device, unsigned int _link)
+ : device(_device), link(_link) {};
+
+ int32 device, link;
+ };
+
+ struct get_param_failed
+ {
+ get_param_failed(std::string _name, int32 _rc)
+ : name(_name), rc((KLibraryStatus)_rc) {};
+
+ std::string name;
+ KLibraryStatus rc;
+ };
+
+ typedef K3L_DEVICE_CONFIG device_conf_type;
+ typedef K3L_CHANNEL_CONFIG channel_conf_type;
+ typedef K3L_CHANNEL_CONFIG * channel_ptr_conf_type;
+ typedef K3L_LINK_CONFIG link_conf_type;
+ typedef K3L_LINK_CONFIG * link_ptr_conf_type;
+
+ /* constructors/destructors */
+
+ K3LAPI();
+ ~K3LAPI();
+
+ /* (init|final)ialize the whole thing! */
+
+ void start(void);
+ void stop(void);
+
+ /* verificacao de intervalos */
+
+ inline bool valid_device(int32 dev)
+ {
+ return (dev >= 0 && dev < ((int32)_device_count));
+ }
+
+ inline bool valid_channel(int32 dev, int32 obj)
+ {
+ return (valid_device(dev) && obj >= 0 && obj < ((int32)_channel_count[dev]));
+ }
+
+ inline bool valid_link(int32 dev, int32 obj)
+ {
+ return (valid_device(dev) && obj >= 0 && obj < ((int32)_link_count[dev]));
+ }
+
+ /* identificadores alto-nivel de objectos */
+ struct target
+ {
+ typedef enum { DEVICE, CHANNEL, MIXER, LINK } target_type;
+
+ target(K3LAPI & k3lapi, target_type type_init, int32 device_value, int32 object_value)
+ : type(type_init),
+ device((unsigned short)device_value),
+ object((unsigned short)object_value)
+ {
+ switch (type_init)
+ {
+ case DEVICE:
+ if (!k3lapi.valid_device(device))
+ throw invalid_device(device);
+ break;
+
+ case CHANNEL:
+ case MIXER:
+ if (!k3lapi.valid_channel(device, object))
+ throw invalid_channel(device, object);
+ break;
+
+ case LINK:
+ if (!k3lapi.valid_link(device, object))
+ throw invalid_link(device, object);
+ break;
+ }
+
+ };
+
+ target_type type;
+
+ unsigned short device;
+ unsigned short object;
+ };
+
+ /* envio de comandos para placa (geral) */
+
+ void raw_command(int32 dev, int32 dsp, std::string & str);
+ void raw_command(int32 dev, int32 dsp, const char * cmds, int32 size);
+
+ /* obter dados 'cacheados' (geral) */
+
+ inline unsigned int device_count(void)
+ {
+ return _device_count;
+ }
+
+ /* envio de comandos para placa (sem identificadores) */
+
+ void mixer(int32 dev, int32 obj, byte track, KMixerSource src, int32 index);
+ void mixerCTbus(int32 dev, int32 obj, byte track, KMixerSource src, int32 index);
+
+ void command (int32 dev, int32 obj, int32 code, std::string & str);
+ void command (int32 dev, int32 obj, int32 code, const char * parms = NULL);
+
+ /* obter dados 'cacheados' (sem identificadores) */
+
+ inline unsigned int channel_count(int32 dev)
+ {
+ if (!valid_device(dev))
+ throw invalid_device(dev);
+
+ return _channel_count[dev];
+ }
+
+ inline unsigned int link_count(int32 dev)
+ {
+ if (!valid_device(dev))
+ throw invalid_device(dev);
+
+ return _link_count[dev];
+ }
+
+ KDeviceType device_type(int32 dev)
+ {
+ if (!valid_device(dev))
+ throw invalid_device(dev);
+
+ return _device_type[dev];
+ }
+
+
+ K3L_DEVICE_CONFIG & device_config(int32 dev)
+ {
+ if (!valid_device(dev))
+ throw invalid_device(dev);
+
+ return _device_config[dev];
+ }
+
+ K3L_CHANNEL_CONFIG & channel_config(int32 dev, int32 obj)
+ {
+ if (!valid_channel(dev, obj))
+ throw invalid_channel(dev, obj);
+
+ return _channel_config[dev][obj];
+ }
+
+ K3L_LINK_CONFIG & link_config(int32 dev, int32 obj)
+ {
+ if (!valid_channel(dev, obj))
+ throw invalid_channel(dev, obj);
+
+ return _link_config[dev][obj];
+ }
+
+ /* envio de comandos para placa (com identificadores) */
+
+ void mixer(target & tgt, byte track, KMixerSource src, int32 index)
+ {
+ mixer((int32)tgt.device, (int32)tgt.object, track, src, index);
+ }
+
+ void mixerCTbus(target & tgt, byte track, KMixerSource src, int32 index)
+ {
+ mixerCTbus((int32)tgt.device, (int32)tgt.object, track, src, index);
+ }
+
+ void command (target & tgt, int32 code, std::string & str)
+ {
+ command((int32)tgt.device, (int32)tgt.object, code, str);
+ };
+
+ void command (target & tgt, int32 code, const char * parms = NULL)
+ {
+ command((int32)tgt.device, (int32)tgt.object, code, parms);
+ };
+
+ /* obter dados 'cacheados' (com indentificadores) */
+
+ inline unsigned int channel_count(target & tgt)
+ {
+ return _channel_count[tgt.device];
+ }
+
+ inline unsigned int link_count(target & tgt)
+ {
+ return _link_count[tgt.device];
+ }
+
+ KDeviceType device_type(target & tgt)
+ {
+ return _device_type[tgt.device];
+ }
+
+
+ K3L_DEVICE_CONFIG & device_config(target & tgt)
+ {
+ return _device_config[tgt.device];
+ }
+
+ K3L_CHANNEL_CONFIG & channel_config(target & tgt)
+ {
+ return _channel_config[tgt.device][tgt.object];
+ }
+
+ K3L_LINK_CONFIG & link_config(target & tgt)
+ {
+ return _link_config[tgt.device][tgt.object];
+ }
+
+ /* pega valores em strings de eventos */
+
+ KLibraryStatus get_param(K3L_EVENT *ev, const char *name, std::string &res);
+ std::string get_param(K3L_EVENT *ev, const char *name);
+
+ /* inicializa valores em cache */
+
+ void init(void);
+
+ protected:
+
+ unsigned int _device_count;
+ unsigned int * _channel_count;
+ unsigned int * _link_count;
+
+ device_conf_type * _device_config;
+ channel_ptr_conf_type * _channel_config;
+ link_ptr_conf_type * _link_config;
+ KDeviceType * _device_type;
+};
+
+#endif /* INCLUDED_K3LAPI_HPP */
Added: freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/strings.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/contrib/mod/endpoints/mod_khomp/commons/strings.cpp Fri Jun 26 18:20:45 2009
@@ -0,0 +1,153 @@
+#include <strings.hpp>
+
+void Strings::Merger::add(std::string s)
+{
+ _list.push_back(s);
+};
+
+std::string Strings::Merger::merge(const std::string & sep)
+{
+ list_type::iterator i = _list.begin();
+
+ std::string res;
+
+ if (i != _list.end())
+ {
+ res += (*i);
+ ++i;
+ };
+
+ while (i != _list.end())
+ {
+ res += sep;
+ res += (*i);
+ ++i;
+ }
+
+ return res;
+};
+
+std::string Strings::Merger::merge(const char *sep)
+{
+ std::string ssep(sep);
+ return merge(ssep);
+}
+
+void Strings::tokenize(const std::string & str, Strings::vector_type & tokens,
+ const std::string & delims, long int max_tokens)
+{
+ std::string::size_type init = str.find_first_not_of(delims, 0);
+ std::string::size_type fini = str.find_first_of(delims, init);
+
+ long int cur_token = 1;
+
+ while (std::string::npos != init)
+ {
+ if (std::string::npos != fini && cur_token < max_tokens)
+ {
+ tokens.push_back(str.substr(init, fini - init));
+ ++cur_token;
+ }
+ else
+ {
+ tokens.push_back(str.substr(init, str.size() - init));
+ break;
+ }
+
+ init = str.find_first_not_of(delims, fini);
+ fini = str.find_first_of(delims, init);
+ }
+}
+
+bool Strings::toboolean(std::string str)
+{
+ std::string tmp(str);
+
+ Strings::lower(tmp);
+
+ if ((tmp == "true") || (tmp == "yes")) return true;
+ if ((tmp == "false") || (tmp == "no")) return false;
+
+ throw invalid_value(str);
+}
+
+long Strings::tolong(std::string str, int base)
+{
+ char *str_end = 0;
+
+ unsigned long value = strtol(str.c_str(), &str_end, base);
+
+ if (str_end && *str_end == 0)
+ return value;
+
+ throw invalid_value(str);
+}
+
+unsigned long Strings::toulong(std::string str, int base)
+{
+ char *str_end = 0;
+
+ unsigned long value = strtoul(str.c_str(), &str_end, base);
+
+ if (str_end && *str_end == 0)
+ return value;
+
+ throw invalid_value(str);
+}
+
+unsigned long long Strings::toulonglong(std::string str, int base)
+{
+#if defined(_WINDOWS) || defined(_Windows) || defined(_WIN32) || defined(WIN32)
+ throw not_implemented();
+#else
+ char *str_end = 0;
+
+ unsigned long long value = strtoull(str.c_str(), &str_end, base);
+
+ if (str_end && *str_end == 0)
+ return value;
+
+ throw invalid_value(str);
+#endif
+}
+
+std::string Strings::fromboolean(bool value)
+{
+ if (value) return "true";
+ else return "false";
+}
+
+std::string Strings::lower(std::string str)
+{
+ std::string res;
+
+ for (std::string::iterator i = str.begin(); i != str.end(); i++)
+ res += tolower((*i));
+
+ return res;
+}
+
+std::string Strings::hexadecimal(std::string value)
+{
+ std::string result;
+
+ for (std::string::iterator i = value.begin(); i != value.end(); i++)
+ {
+ if (i != value.begin())
+ result += " ";
+
+ result += STG(FMT("%2x") % (unsigned int)(*i));
+ }
+
+ return result;
+}
+
+std::string Strings::trim(const std::string& str, const std::string& trim_chars)
+{
+ std::string result(str);
+
+ result.erase( result.find_last_not_of( trim_chars ) + 1 );
+ result.erase( 0, result.find_first_not_of( trim_chars ) );
+
+ return result;
+}
Modified: freeswitch/trunk/contrib/mod/endpoints/mod_khomp/mod_khomp.cpp
==============================================================================
--- freeswitch/trunk/contrib/mod/endpoints/mod_khomp/mod_khomp.cpp (original)
+++ freeswitch/trunk/contrib/mod/endpoints/mod_khomp/mod_khomp.cpp Fri Jun 26 18:20:45 2009
@@ -29,156 +29,144 @@
* mod_khomp.c -- Khomp board Endpoint Module
*
*/
-
+
#define KHOMP_SYNTAX "khomp show [info|links|channels]"
-/* Our includes */
-#include "k3lapi.hpp"
+#include "mod_khomp.h"
+
+/* Handles callbacks and events from the boards */
+static int32 Kstdcall khomp_event_callback(int32 obj, K3L_EVENT * e);
+static void Kstdcall khomp_audio_listener(int32 deviceid, int32 objectid, byte * read_buffer, int32 read_size);
-extern "C"
+typedef enum
{
- #include <switch.h>
- #include "k3l.h"
+ TFLAG_IO = (1 << 0),
+ TFLAG_INBOUND = (1 << 1),
+ TFLAG_OUTBOUND = (1 << 2),
+ TFLAG_DTMF = (1 << 3),
+ TFLAG_VOICE = (1 << 4),
+ TFLAG_HANGUP = (1 << 5),
+ TFLAG_LINEAR = (1 << 6),
+ TFLAG_CODEC = (1 << 7),
+ TFLAG_BREAK = (1 << 8)
}
+TFLAGS;
+/* Module management routines */
SWITCH_MODULE_LOAD_FUNCTION(mod_khomp_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_khomp_shutdown);
-//SWITCH_MODULE_RUNTIME_FUNCTION(mod_khomp_runtime);
-SWITCH_MODULE_DEFINITION(mod_khomp, mod_khomp_load, mod_khomp_shutdown, NULL); //mod_khomp_runtime);
+SWITCH_MODULE_DEFINITION(mod_khomp, mod_khomp_load, mod_khomp_shutdown, NULL);
+/* State handlers for FreeSWITCH */
+static switch_status_t channel_on_init(switch_core_session_t *session);
+static switch_status_t channel_on_routing(switch_core_session_t *session);
+static switch_status_t channel_on_execute(switch_core_session_t *session);
+static switch_status_t channel_on_hangup(switch_core_session_t *session);
+static switch_status_t channel_on_exchange_media(
+ switch_core_session_t *session);
+static switch_status_t channel_on_soft_execute(switch_core_session_t *session);
-switch_endpoint_interface_t *khomp_endpoint_interface;
-static switch_memory_pool_t *module_pool = NULL;
-static int running = 1;
-
-static K3LAPI * k3l;
-
-
-typedef enum {
- TFLAG_IO = (1 << 0),
- TFLAG_INBOUND = (1 << 1),
- TFLAG_OUTBOUND = (1 << 2),
- TFLAG_DTMF = (1 << 3),
- TFLAG_VOICE = (1 << 4),
- TFLAG_HANGUP = (1 << 5),
- TFLAG_LINEAR = (1 << 6),
- TFLAG_CODEC = (1 << 7),
- TFLAG_BREAK = (1 << 8)
-} TFLAGS;
-
-typedef enum {
- GFLAG_MY_CODEC_PREFS = (1 << 0)
-} GFLAGS;
-
-
-static struct {
- int debug;
- char *ip;
- int port;
- char *dialplan;
- char *codec_string;
- char *codec_order[SWITCH_MAX_CODECS];
- int codec_order_last;
- char *codec_rates_string;
- char *codec_rates[SWITCH_MAX_CODECS];
- int codec_rates_last;
- unsigned int flags;
- int calls;
- switch_mutex_t *mutex;
-} globals;
-
-struct private_object {
- unsigned int flags;
- switch_codec_t read_codec;
- switch_codec_t write_codec;
- switch_frame_t read_frame;
- unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
- switch_core_session_t *session;
- switch_caller_profile_t *caller_profile;
- switch_mutex_t *mutex;
- switch_mutex_t *flag_mutex;
- //switch_thread_cond_t *cond;
- unsigned int KDeviceId; // Represent de board we are making the call from
- unsigned int KChannel; // Represent the channel we are making the call from
+switch_state_handler_table_t khomp_state_handlers = {
+ /*.on_init */ channel_on_init,
+ /*.on_routing */ channel_on_routing,
+ /*.on_execute */ channel_on_execute,
+ /*.on_hangup */ channel_on_hangup,
+ /*.on_exchange_media */ channel_on_exchange_media,
+ /*.on_soft_execute */ channel_on_soft_execute
};
-typedef struct private_object private_t;
+/* Callbacks for FreeSWITCH */
+static switch_call_cause_t channel_outgoing_channel(
+ switch_core_session_t *session,
+ switch_event_t *var_event,
+ switch_caller_profile_t *outbound_profile,
+ switch_core_session_t **new_session,
+ switch_memory_pool_t **pool,
+ switch_originate_flag_t flags);
+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 switch_status_t channel_send_dtmf(switch_core_session_t *session,
+ const switch_dtmf_t *dtmf);
+static switch_status_t channel_receive_message(switch_core_session_t *session,
+ switch_core_session_message_t *msg);
+static switch_status_t channel_receive_event(switch_core_session_t *session,
+ switch_event_t *event);
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan);
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string);
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_rates_string, globals.codec_rates_string);
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_ip, globals.ip);
+switch_io_routines_t khomp_io_routines = {
+ /*.outgoing_channel */ channel_outgoing_channel,
+ /*.read_frame */ channel_read_frame,
+ /*.write_frame */ channel_write_frame,
+ /*.kill_channel */ channel_kill_channel,
+ /*.send_dtmf */ channel_send_dtmf,
+ /*.receive_message */ channel_receive_message,
+ /*.receive_event */ channel_receive_event
+};
/* Macros to define specific API functions */
SWITCH_STANDARD_API(khomp);
-
-static switch_status_t channel_on_init(switch_core_session_t *session);
-static switch_status_t channel_on_hangup(switch_core_session_t *session);
-static switch_status_t channel_on_routing(switch_core_session_t *session);
-static switch_status_t channel_on_exchange_media(switch_core_session_t *session);
-static switch_status_t channel_on_soft_execute(switch_core_session_t *session);
-static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
- switch_caller_profile_t *outbound_profile,
- switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags);
-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);
-
/* Helper function prototypes */
static void printSystemSummary(switch_stream_handle_t* stream);
-static void printLinks(switch_stream_handle_t* stream, unsigned int device, unsigned int link);
-static void printChannels(switch_stream_handle_t* stream, unsigned int device, unsigned int link);
-/* Handles callbacks and events from the boards */
-static int32 Kstdcall khomp_event_callback(int32 obj, K3L_EVENT * e);
-KLibraryStatus khomp_channel_from_event(unsigned int KDeviceId, unsigned int KChannel, K3L_EVENT * event);
-/* Callback for receiving audio buffers from the boards */
-static void Kstdcall khomp_audio_listener (int32 deviceid, int32 mixer, byte * read_buffer, int32 read_size);
+static void printLinks(switch_stream_handle_t* stream, unsigned int device,
+ unsigned int link);
+static void printChannels(switch_stream_handle_t* stream, unsigned int device,
+ unsigned int link);
/* Will init part of our private structure and setup all the read/write buffers */
-static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *session)
+static switch_status_t tech_init(KhompPvt *tech_pvt, switch_core_session_t *session)
{
- tech_pvt->read_frame.data = tech_pvt->databuf;
- tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
- switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
- switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
- switch_core_session_set_private(session, tech_pvt);
- tech_pvt->session = session;
-
- if (switch_core_codec_init(&tech_pvt->read_codec,
- "PCMA",
- NULL,
- 8000,
- 20,
- 1,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
- return SWITCH_STATUS_GENERR;
- } else {
- if (switch_core_codec_init(&tech_pvt->write_codec,
- "PCMA",
- NULL,
- 8000,
- 20,
- 1,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
- switch_core_codec_destroy(&tech_pvt->read_codec);
- return SWITCH_STATUS_GENERR;
- }
- }
-
- switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
- switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);
- switch_set_flag_locked(tech_pvt, TFLAG_CODEC);
- tech_pvt->read_frame.codec = &tech_pvt->read_codec;
- switch_set_flag_locked(tech_pvt, TFLAG_IO);
+ tech_pvt->_read_frame.data = tech_pvt->_databuf;
+ tech_pvt->_read_frame.buflen = sizeof(tech_pvt->_databuf);
+ switch_mutex_init(&tech_pvt->_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
+
+ switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
+ switch_core_session_set_private(session, tech_pvt);
+ tech_pvt->_session = session;
+
+ if (switch_core_codec_init(&tech_pvt->_read_codec,
+ "PCMA",
+ NULL,
+ 8000,
+ 20,
+ 1,
+ SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
+ NULL, switch_core_session_get_pool(tech_pvt->_session)) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
+ return SWITCH_STATUS_GENERR;
+ } else {
+ if (switch_core_codec_init(&tech_pvt->_write_codec,
+ "PCMA",
+ NULL,
+ 8000,
+ 20,
+ 1,
+ SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
+ NULL, switch_core_session_get_pool(tech_pvt->_session)) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
+ switch_core_codec_destroy(&tech_pvt->_read_codec);
+ return SWITCH_STATUS_GENERR;
+ }
+ }
- return SWITCH_STATUS_SUCCESS;
+ switch_core_session_set_read_codec(tech_pvt->_session, &tech_pvt->_read_codec);
+ switch_core_session_set_write_codec(tech_pvt->_session, &tech_pvt->_write_codec);
+ switch_set_flag_locked(tech_pvt, TFLAG_CODEC);
+
+ tech_pvt->_read_frame.codec = &tech_pvt->_read_codec;
+
+ switch_set_flag_locked(tech_pvt, TFLAG_IO);
+
+ return SWITCH_STATUS_SUCCESS;
}
@@ -189,311 +177,299 @@
*/
static switch_status_t channel_on_init(switch_core_session_t *session)
{
- switch_channel_t *channel;
- private_t *tech_pvt = NULL;
+ KhompPvt * tech_pvt = static_cast< KhompPvt* >(switch_core_session_get_private(session));
+ assert(tech_pvt != NULL);
+
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
- tech_pvt = static_cast< private_t* >(switch_core_session_get_private(session));
- assert(tech_pvt != NULL);
+ switch_set_flag_locked(tech_pvt, TFLAG_IO);
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
- switch_set_flag_locked(tech_pvt, TFLAG_IO);
-
- /* Move channel's state machine to ROUTING. This means the call is trying
- to get from the initial start where the call because, to the point
- where a destination has been identified. If the channel is simply
- left in the initial state, nothing will happen. */
- switch_channel_set_state(channel, CS_ROUTING);
- switch_mutex_lock(globals.mutex);
- globals.calls++;
- switch_mutex_unlock(globals.mutex);
+ /* Move channel's state machine to ROUTING. This means the call is trying
+ to get from the initial start where the call because, to the point
+ where a destination has been identified. If the channel is simply
+ left in the initial state, nothing will happen. */
+ switch_channel_set_state(channel, CS_ROUTING);
- return SWITCH_STATUS_SUCCESS;
+ switch_mutex_lock(Globals::_mutex);
+ Globals::_calls++;
+ switch_mutex_unlock(Globals::_mutex);
+
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_on_routing(switch_core_session_t *session)
{
- switch_channel_t *channel = NULL;
- private_t *tech_pvt = NULL;
+ switch_channel_t *channel = NULL;
+ KhompPvt *tech_pvt = NULL;
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
- tech_pvt = static_cast<private_t *>(switch_core_session_get_private(session));
- assert(tech_pvt != NULL);
+ tech_pvt = static_cast<KhompPvt *>(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));
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel));
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_on_execute(switch_core_session_t *session)
{
- switch_channel_t *channel = NULL;
- private_t *tech_pvt = NULL;
+ switch_channel_t *channel = NULL;
+ KhompPvt *tech_pvt = NULL;
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
- tech_pvt = static_cast<private_t*>(switch_core_session_get_private(session));
- assert(tech_pvt != NULL);
+ tech_pvt = static_cast<KhompPvt*>(switch_core_session_get_private(session));
+ assert(tech_pvt != NULL);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel));
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel));
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_on_hangup(switch_core_session_t *session)
{
- switch_channel_t *channel = NULL;
- private_t *tech_pvt = NULL;
+ switch_channel_t *channel = NULL;
+ KhompPvt *tech_pvt = NULL;
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
- tech_pvt = static_cast<private_t*>(switch_core_session_get_private(session));
- assert(tech_pvt != NULL);
+ tech_pvt = static_cast<KhompPvt*>(switch_core_session_get_private(session));
+ assert(tech_pvt != NULL);
- switch_clear_flag_locked(tech_pvt, TFLAG_IO);
- switch_clear_flag_locked(tech_pvt, TFLAG_VOICE);
- //switch_thread_cond_signal(tech_pvt->cond);
-
- if (tech_pvt->read_codec.implementation) {
- switch_core_codec_destroy(&tech_pvt->read_codec);
- }
-
- if (tech_pvt->write_codec.implementation) {
- switch_core_codec_destroy(&tech_pvt->write_codec);
- }
+ switch_clear_flag_locked(tech_pvt, TFLAG_IO);
+ switch_clear_flag_locked(tech_pvt, TFLAG_VOICE);
+ //switch_thread_cond_signal(tech_pvt->_cond);
- try {
- k3l->command(tech_pvt->KDeviceId, tech_pvt->KChannel, CM_DISCONNECT, NULL);
- }
- catch(K3LAPI::failed_command & e)
- {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "WE COULD NOT HANGUP THE CHANNEL! rc:%d\n", e.rc);
- return SWITCH_STATUS_TERM;
+ if (tech_pvt->_read_codec.implementation) {
+ switch_core_codec_destroy(&tech_pvt->_read_codec);
}
+ if (tech_pvt->_write_codec.implementation) {
+ switch_core_codec_destroy(&tech_pvt->_write_codec);
+ }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s Originator Hangup.\n", switch_channel_get_name(channel));
- switch_mutex_lock(globals.mutex);
- globals.calls--;
- if (globals.calls < 0) {
- globals.calls = 0;
- }
- switch_mutex_unlock(globals.mutex);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s Originator Hangup.\n", switch_channel_get_name(channel));
+ switch_mutex_lock(Globals::_mutex);
+ Globals::_calls--;
+ if (Globals::_calls < 0) {
+ Globals::_calls = 0;
+ }
+ switch_mutex_unlock(Globals::_mutex);
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig)
{
- switch_channel_t *channel = NULL;
- private_t *tech_pvt = NULL;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = static_cast<private_t*>(switch_core_session_get_private(session));
- assert(tech_pvt != NULL);
-
- switch (sig) {
- case SWITCH_SIG_KILL:
- switch_clear_flag_locked(tech_pvt, TFLAG_IO);
- switch_clear_flag_locked(tech_pvt, TFLAG_VOICE);
- switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
- //switch_thread_cond_signal(tech_pvt->cond);
- break;
- case SWITCH_SIG_BREAK:
- switch_set_flag_locked(tech_pvt, TFLAG_BREAK);
- break;
- default:
- break;
- }
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL KILL\n");
+ switch_channel_t *channel = NULL;
+ KhompPvt *tech_pvt = NULL;
+
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
+
+ tech_pvt = static_cast<KhompPvt*>(switch_core_session_get_private(session));
+ assert(tech_pvt != NULL);
+
+ switch (sig) {
+ case SWITCH_SIG_KILL:
+ switch_clear_flag_locked(tech_pvt, TFLAG_IO);
+ switch_clear_flag_locked(tech_pvt, TFLAG_VOICE);
+ switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+ //switch_thread_cond_signal(tech_pvt->_cond);
+ break;
+ case SWITCH_SIG_BREAK:
+ switch_set_flag_locked(tech_pvt, TFLAG_BREAK);
+ break;
+ default:
+ break;
+ }
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_on_exchange_media(switch_core_session_t *session)
{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL LOOPBACK\n");
- return SWITCH_STATUS_SUCCESS;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL LOOPBACK\n");
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_on_soft_execute(switch_core_session_t *session)
{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL TRANSMIT\n");
- return SWITCH_STATUS_SUCCESS;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL TRANSMIT\n");
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
{
- private_t *tech_pvt = static_cast<private_t*>(switch_core_session_get_private(session));
- switch_assert(tech_pvt != NULL);
+ KhompPvt *tech_pvt = static_cast<KhompPvt*>(switch_core_session_get_private(session));
+ switch_assert(tech_pvt != NULL);
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
{
- switch_channel_t *channel = NULL;
- private_t *tech_pvt = NULL;
- //switch_time_t started = switch_time_now();
- //unsigned int elapsed;
- switch_byte_t *data;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = static_cast<private_t*>(switch_core_session_get_private(session));
- assert(tech_pvt != NULL);
- tech_pvt->read_frame.flags = SFF_NONE;
- *frame = NULL;
-
-
- while (switch_test_flag(tech_pvt, TFLAG_IO)) {
-
- if (switch_test_flag(tech_pvt, TFLAG_BREAK)) {
- switch_clear_flag(tech_pvt, TFLAG_BREAK);
- goto cng;
- }
-
- if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
- return SWITCH_STATUS_FALSE;
- }
-
- //if (switch_test_flag(tech_pvt, TFLAG_IO) && switch_test_flag(tech_pvt, TFLAG_VOICE)) {
- // switch_clear_flag_locked(tech_pvt, TFLAG_VOICE);
- if (!tech_pvt->read_frame.datalen) {
- continue;
- }
- *frame = &tech_pvt->read_frame;
+ switch_channel_t *channel = NULL;
+ KhompPvt *tech_pvt = NULL;
+ //switch_time_t started = switch_time_now();
+ //unsigned int elapsed;
+ switch_byte_t *data;
+
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
+
+ tech_pvt = static_cast<KhompPvt*>(switch_core_session_get_private(session));
+ assert(tech_pvt != NULL);
+ tech_pvt->_read_frame.flags = SFF_NONE;
+ *frame = NULL;
+
+
+ while (switch_test_flag(tech_pvt, TFLAG_IO)) {
+
+ if (switch_test_flag(tech_pvt, TFLAG_BREAK)) {
+ switch_clear_flag(tech_pvt, TFLAG_BREAK);
+ goto cng;
+ }
+
+ if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ switch_clear_flag_locked(tech_pvt, TFLAG_VOICE);
+ if (!tech_pvt->_read_frame.datalen) {
+ continue;
+ }
+ *frame = &tech_pvt->_read_frame;
#ifdef BIGENDIAN
- if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) {
- switch_swap_linear((*frame)->data, (int) (*frame)->datalen / 2);
- }
+ if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) {
+ switch_swap_linear((*frame)->data, (int) (*frame)->datalen / 2);
+ }
#endif
- return SWITCH_STATUS_SUCCESS;
- //}
+ return SWITCH_STATUS_SUCCESS;
- switch_cond_next();
- }
+ switch_cond_next();
+ }
- return SWITCH_STATUS_FALSE;
+ return SWITCH_STATUS_FALSE;
cng:
- data = (switch_byte_t *) tech_pvt->read_frame.data;
- data[0] = 65;
- data[1] = 0;
- tech_pvt->read_frame.datalen = 2;
- tech_pvt->read_frame.flags = SFF_CNG;
- *frame = &tech_pvt->read_frame;
- return SWITCH_STATUS_SUCCESS;
+ data = (switch_byte_t *) tech_pvt->_read_frame.data;
+ data[0] = 65;
+ data[1] = 0;
+ tech_pvt->_read_frame.datalen = 2;
+ tech_pvt->_read_frame.flags = SFF_CNG;
+ *frame = &tech_pvt->_read_frame;
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
{
- switch_channel_t *channel = NULL;
- private_t *tech_pvt = NULL;
- //switch_frame_t *pframe;
-
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
-
- tech_pvt = static_cast<private_t*>(switch_core_session_get_private(session));
- assert(tech_pvt != NULL);
-
- if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
- return SWITCH_STATUS_FALSE;
- }
+ switch_channel_t *channel = NULL;
+ KhompPvt *tech_pvt = NULL;
+ //switch_frame_t *pframe;
+
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
+
+ tech_pvt = static_cast<KhompPvt*>(switch_core_session_get_private(session));
+ assert(tech_pvt != NULL);
+
+ if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
+ return SWITCH_STATUS_FALSE;
+ }
#ifdef BIGENDIAN
- if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) {
- switch_swap_linear(frame->data, (int) frame->datalen / 2);
- }
+ if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) {
+ switch_swap_linear(frame->data, (int) frame->datalen / 2);
+ }
#endif
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_answer_channel(switch_core_session_t *session)
{
- private_t *tech_pvt;
- switch_channel_t *channel = NULL;
+ KhompPvt *tech_pvt;
+ switch_channel_t *channel = NULL;
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
- tech_pvt = static_cast<private_t*>(switch_core_session_get_private(session));
- assert(tech_pvt != NULL);
+ tech_pvt = static_cast<KhompPvt*>(switch_core_session_get_private(session));
+ assert(tech_pvt != NULL);
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
{
- switch_channel_t *channel;
- private_t *tech_pvt;
+ switch_channel_t *channel;
+ KhompPvt *tech_pvt;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "When the fuck is this called?.\n");
- channel = switch_core_session_get_channel(session);
- assert(channel != NULL);
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
- tech_pvt = (private_t *) switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
+ tech_pvt = (KhompPvt *) switch_core_session_get_private(session);
+ assert(tech_pvt != NULL);
- switch (msg->message_id) {
- case SWITCH_MESSAGE_INDICATE_ANSWER:
- {
- channel_answer_channel(session);
- }
- break;
- default:
- break;
- }
+ switch (msg->message_id) {
+ case SWITCH_MESSAGE_INDICATE_ANSWER:
+ {
+ channel_answer_channel(session);
+ }
+ break;
+ default:
+ break;
+ }
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
/* 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!
*/
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
- switch_caller_profile_t *outbound_profile,
- switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags)
+ switch_caller_profile_t *outbound_profile,
+ switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags)
{
- char *argv[3] = { 0 };
- int argc = 0;
+ char *argv[3] = { 0 };
+ int argc = 0;
- if ((*new_session = switch_core_session_request(khomp_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, pool)) != 0) {
- private_t *tech_pvt;
- switch_channel_t *channel;
- switch_caller_profile_t *caller_profile;
-
- switch_core_session_add_stream(*new_session, NULL);
- if ((tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) != 0) {
- channel = switch_core_session_get_channel(*new_session);
- tech_init(tech_pvt, *new_session);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
- switch_core_session_destroy(new_session);
- return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
- }
+ if ((*new_session = switch_core_session_request(Globals::_khomp_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, pool)) != 0) {
+ KhompPvt *tech_pvt;
+ switch_channel_t *channel;
+ switch_caller_profile_t *caller_profile;
+
+ switch_core_session_add_stream(*new_session, NULL);
+ if ((tech_pvt = (KhompPvt *) switch_core_session_alloc(*new_session, sizeof(KhompPvt))) != 0) {
+ channel = switch_core_session_get_channel(*new_session);
+ tech_init(tech_pvt, *new_session);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
+ switch_core_session_destroy(new_session);
+ return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+ }
- if (outbound_profile) {
- char name[128];
+ if (outbound_profile) {
+ char name[128];
- snprintf(name, sizeof(name), "Khomp/%s", outbound_profile->destination_number);
- switch_channel_set_name(channel, name);
+ snprintf(name, sizeof(name), "Khomp/%s", outbound_profile->destination_number);
+ switch_channel_set_name(channel, name);
/* Let's setup our own vars on tech_pvt */
if ((argc = switch_separate_string(outbound_profile->destination_number, '/', argv, (sizeof(argv) / sizeof(argv[0])))) < 3)
@@ -503,220 +479,148 @@
}
else
{
- tech_pvt->KDeviceId = atoi(argv[0]);
- tech_pvt->KChannel = atoi(argv[1]);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Dialing to %s out from Board:%u, Channel:%u.\n",
- argv[2],
- tech_pvt->KDeviceId,
- tech_pvt->KChannel);
+// usar algoritmo de busca de canais (spec.*).
+// tech_pvt->_KDeviceId = atoi(argv[0]);
+// tech_pvt->_KChannel = atoi(argv[1]);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Dialing to %s out\n",// from Board:%u, Channel:%u.\n",
+ argv[2]
+ //, tech_pvt->_KDeviceId, tech_pvt->_KChannel
+ );
}
- caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
- switch_channel_set_caller_profile(channel, caller_profile);
- tech_pvt->caller_profile = caller_profile;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Doh! no caller profile\n");
- switch_core_session_destroy(new_session);
+ caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
+ switch_channel_set_caller_profile(channel, caller_profile);
+ tech_pvt->_caller_profile = caller_profile;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Doh! no caller profile\n");
+ switch_core_session_destroy(new_session);
/* Destroy the channel session */
- k3l->setSession(tech_pvt->KDeviceId, tech_pvt->KChannel, NULL);
- return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
- }
+ // Globals::_k3lapi.setSession(tech_pvt->_KDeviceId, tech_pvt->_KChannel, NULL);
+ return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+ }
- switch_channel_set_flag(channel, CF_OUTBOUND);
- switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
- switch_channel_set_state(channel, CS_INIT);
+ switch_channel_set_flag(channel, CF_OUTBOUND);
+ switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
+ switch_channel_set_state(channel, CS_INIT);
try {
/* Lets make the call! */
char params[ 255 ];
- sprintf(params, "dest_addr=\"%s\" orig_addr=\"%s\"", argv[2], outbound_profile->caller_id_number);
+ sprintf(params, "dest_addr=\"%s\"", argv[2]);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "We are calling with params: %s.\n", params);
- k3l->command(tech_pvt->KDeviceId,tech_pvt->KChannel, CM_MAKE_CALL, params);
+ //Globals::_k3lapi.command(tech_pvt->_KDeviceId,tech_pvt->_KChannel, CM_MAKE_CALL, params);
}
catch(K3LAPI::failed_command & e)
{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not place call! Cause: code%x and rc%d.\n", e.code, e.rc);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not place call! Cause: code%x and rc%d.\n", e.code, e.rc);
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
/* Add the new session the the channel's info */
- k3l->setSession(tech_pvt->KDeviceId, tech_pvt->KChannel, *new_session);
+ //Globals::_k3lapi.setSession(tech_pvt->_KDeviceId, tech_pvt->_KChannel, *new_session);
- return SWITCH_CAUSE_SUCCESS;
- }
+ return SWITCH_CAUSE_SUCCESS;
+ }
- return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+ return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event)
{
- struct private_object *tech_pvt = static_cast<private_t*>(switch_core_session_get_private(session));
- char *body = switch_event_get_body(event);
- switch_assert(tech_pvt != NULL);
-
- if (!body) {
- body = "";
- }
+ struct KhompPvt *tech_pvt = static_cast<KhompPvt*>(switch_core_session_get_private(session));
+ char *body = switch_event_get_body(event);
+ switch_assert(tech_pvt != NULL);
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-
-switch_state_handler_table_t khomp_state_handlers = {
- /*.on_init */ channel_on_init,
- /*.on_routing */ channel_on_routing,
- /*.on_execute */ channel_on_execute,
- /*.on_hangup */ channel_on_hangup,
- /*.on_exchange_media */ channel_on_exchange_media,
- /*.on_soft_execute */ channel_on_soft_execute
-};
-
-switch_io_routines_t khomp_io_routines = {
- /*.outgoing_channel */ channel_outgoing_channel,
- /*.read_frame */ channel_read_frame,
- /*.write_frame */ channel_write_frame,
- /*.kill_channel */ channel_kill_channel,
- /*.send_dtmf */ channel_send_dtmf,
- /*.receive_message */ channel_receive_message,
- /*.receive_event */ channel_receive_event
-};
+ if (!body) {
+ body = (char *)"";
+ }
-static switch_status_t load_config(void)
-{
- const char *cf = "khomp.conf";
- switch_xml_t cfg, xml, settings, param;
+ return SWITCH_STATUS_SUCCESS;
+}
- memset(&globals, 0, sizeof(globals));
- switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool);
- if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
- return SWITCH_STATUS_TERM;
- }
-
- if ((settings = switch_xml_child(cfg, "settings"))) {
- for (param = switch_xml_child(settings, "param"); param; param = param->next) {
- char *var = (char *) switch_xml_attr_soft(param, "name");
- char *val = (char *) switch_xml_attr_soft(param, "value");
-
- if (!strcmp(var, "debug")) {
- globals.debug = atoi(val);
- } else if (!strcmp(var, "port")) {
- globals.port = atoi(val);
- } else if (!strcmp(var, "ip")) {
- set_global_ip(val);
- } else if (!strcmp(var, "codec-master")) {
- if (!strcasecmp(val, "us")) {
- switch_set_flag(&globals, GFLAG_MY_CODEC_PREFS);
- }
- } else if (!strcmp(var, "dialplan")) {
- set_global_dialplan(val);
- } else if (!strcmp(var, "codec-prefs")) {
- set_global_codec_string(val);
- globals.codec_order_last = switch_separate_string(globals.codec_string, ',', globals.codec_order, SWITCH_MAX_CODECS);
- } else if (!strcmp(var, "codec-rates")) {
- set_global_codec_rates_string(val);
- globals.codec_rates_last = switch_separate_string(globals.codec_rates_string, ',', globals.codec_rates, SWITCH_MAX_CODECS);
- }
- }
- }
-
- if (!globals.dialplan) {
- set_global_dialplan("default");
- }
-
- if (!globals.port) {
- globals.port = 4569;
- }
- switch_xml_free(xml);
- return SWITCH_STATUS_SUCCESS;
-}
SWITCH_MODULE_LOAD_FUNCTION(mod_khomp_load)
{
- module_pool = pool;
+ Globals::_module_pool = pool;
- memset(&globals, 0, sizeof(globals));
-
- load_config();
+ /* start config system! */
+ Opt::initialize();
+
+ Opt::obtain();
- switch_api_interface_t *api_interface;
+ //load_config();
- *module_interface = switch_loadable_module_create_module_interface(pool, "mod_khomp");
- khomp_endpoint_interface = static_cast<switch_endpoint_interface_t*>(switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE));
- khomp_endpoint_interface->interface_name = "khomp";
- khomp_endpoint_interface->io_routines = &khomp_io_routines;
- khomp_endpoint_interface->state_handler = &khomp_state_handlers;
/*
Spawn our k3l global var that will be used along the module
for sending info to the boards
*/
- k3lSetGlobalParam (klpResetFwOnStartup, 1);
- k3lSetGlobalParam (klpDisableInternalVoIP, 1);
-
- k3l = new K3LAPI();
/* Start the API and connect to KServer */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Starting K3L...\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Starting K3L...\n");
try {
- k3l->start();
+ Globals::_k3lapi.start();
} catch (K3LAPI::start_failed & e) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "K3L not started. Reason:%s.\n", e.msg.c_str());
return SWITCH_STATUS_TERM;
}
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "K3L started.\n");
-
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "K3L started.\n");
+
k3lRegisterEventHandler( khomp_event_callback );
- k3lRegisterAudioListener (NULL, khomp_audio_listener);
+ k3lRegisterAudioListener (NULL, khomp_audio_listener);
+
+ *module_interface = switch_loadable_module_create_module_interface(pool, "mod_khomp");
+ Globals::_khomp_endpoint_interface = static_cast<switch_endpoint_interface_t*>(switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE));
+ Globals::_khomp_endpoint_interface->interface_name = "khomp";
+ Globals::_khomp_endpoint_interface->io_routines = &khomp_io_routines;
+ Globals::_khomp_endpoint_interface->state_handler = &khomp_state_handlers;
/* Add all the specific API functions */
- SWITCH_ADD_API(api_interface, "khomp", "Khomp Menu", khomp, KHOMP_SYNTAX);
+ SWITCH_ADD_API(Globals::_api_interface, "khomp", "Khomp Menu", khomp, KHOMP_SYNTAX);
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
+ /* indicate that the module should continue to be loaded */
+ return SWITCH_STATUS_SUCCESS;
}
/*
SWITCH_MODULE_RUNTIME_FUNCTION(mod_khomp_runtime)
{
- return SWITCH_STATUS_TERM;
+ return SWITCH_STATUS_TERM;
}
*/
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_khomp_shutdown)
{
- int x = 0;
+ int x = 0;
- running = -1;
+ Globals::_running = -1;
- while (running) {
- if (x++ > 100) {
- break;
- }
- switch_yield(20000);
- }
-
- /* Free dynamically allocated strings */
- switch_safe_free(globals.dialplan);
- switch_safe_free(globals.codec_string);
- switch_safe_free(globals.codec_rates_string);
- switch_safe_free(globals.ip);
-
- /* Finnish him! */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Stopping K3L...\n");
- k3l->stop();
- delete k3l;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "the K3L API has been stopped!\n");
-
- return SWITCH_STATUS_SUCCESS;
+ while (Globals::_running) {
+ if (x++ > 100) {
+ break;
+ }
+ switch_yield(20000);
+ }
+
+ /* Free dynamically allocated strings */
+ switch_safe_free(Opt::_dialplan);
+ switch_safe_free(Opt::_codec_string);
+ switch_safe_free(Opt::_codec_rates_string);
+ switch_safe_free(Opt::_ip);
+
+ /* Finnish him! */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Stopping K3L...\n");
+ Globals::_k3lapi.stop();
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "the K3L API has been stopped!\n");
+
+ return SWITCH_STATUS_SUCCESS;
}
/*
@@ -725,27 +629,27 @@
*/
SWITCH_STANDARD_API(khomp)
{
- char *argv[10] = { 0 };
- int argc = 0;
- void *val;
- char *myarg = NULL;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
+ char *argv[10] = { 0 };
+ int argc = 0;
+ void *val;
+ char *myarg = NULL;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
/* We should not ever get a session here */
- if (session) return status;
+ if (session) return status;
- if (switch_strlen_zero(cmd) || !(myarg = strdup(cmd))) {
- stream->write_function(stream, "USAGE: %s\n", KHOMP_SYNTAX);
- return SWITCH_STATUS_FALSE;
- }
-
- if ((argc = switch_separate_string(myarg, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) < 1) {
- stream->write_function(stream, "USAGE: %s\n", KHOMP_SYNTAX);
- goto done;
- }
+ if (switch_strlen_zero(cmd) || !(myarg = strdup(cmd))) {
+ stream->write_function(stream, "USAGE: %s\n", KHOMP_SYNTAX);
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if ((argc = switch_separate_string(myarg, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) < 1) {
+ stream->write_function(stream, "USAGE: %s\n", KHOMP_SYNTAX);
+ goto done;
+ }
/* Below show ... */
- if (argv[0] && !strncasecmp(argv[0], "show", 4)) {
+ if (argv[0] && !strncasecmp(argv[0], "show", 4)) {
/* Show the API summary and information */
if (argv[1] && !strncasecmp(argv[1], "info", 4)) {
printSystemSummary(stream);
@@ -761,13 +665,13 @@
printChannels(stream, NULL, NULL);
}
- } else {
- stream->write_function(stream, "USAGE: %s\n", KHOMP_SYNTAX);
- }
+ } else {
+ stream->write_function(stream, "USAGE: %s\n", KHOMP_SYNTAX);
+ }
done:
- switch_safe_free(myarg);
- return status;
+ switch_safe_free(myarg);
+ return status;
}
@@ -775,13 +679,13 @@
static void printChannels(switch_stream_handle_t* stream, unsigned int device, unsigned int link) {
if (!device) {
// Print all channels from all boards and links
- stream->write_function(stream, "|--------- Khomp ----------|\n");
- stream->write_function(stream, "| Board | Channel | Status |\n");
- for (int board=0 ; board < k3l->device_count() ; board++) {
- for (int channel=0 ; channel < k3l->channel_count(board) ; channel++) {
+ stream->write_function(stream, "|--------- Khomp ----------|\n");
+ stream->write_function(stream, "| Board | Channel | Status |\n");
+ for (int board=0 ; board < Globals::_k3lapi.device_count() ; board++) {
+ for (int channel=0 ; channel < Globals::_k3lapi.channel_count(board) ; channel++) {
try {
K3L_CHANNEL_CONFIG channelConfig;
- channelConfig = k3l->channel_config( board, channel );
+ channelConfig = Globals::_k3lapi.channel_config( board, channel );
}
catch (...){
stream->write_function(stream, "OOOPSS. Something went wrong, cleanup this mess!\n");
@@ -821,12 +725,12 @@
// We want to see all links from all devices
if (!device) {
- for(int device=0 ; device < k3l->device_count() ; device++)
+ for(int device=0 ; device < Globals::_k3lapi.device_count() ; device++)
{
- K3L_LINK_CONFIG & config = k3l->link_config(device, link);
+ K3L_LINK_CONFIG & config = Globals::_k3lapi.link_config(device, link);
K3L_LINK_STATUS status;
- for(int link=0 ; link < k3l->link_count(device) ; link++)
+ for(int link=0 ; link < Globals::_k3lapi.link_count(device) ; link++)
{
const char * E1Status = "";
if (k3lGetDeviceStatus (device, link + ksoLink, &status, sizeof(status)) == ksSuccess)
@@ -922,13 +826,13 @@
, apiCfg.VpdVersionNeeded , apiCfg.StrVersion);
}
- for (unsigned int i = 0; i < k3l->device_count(); i++)
+ for (unsigned int i = 0; i < Globals::_k3lapi.device_count(); i++)
{
- K3L_DEVICE_CONFIG & devCfg = k3l->device_config(i);
+ K3L_DEVICE_CONFIG & devCfg = Globals::_k3lapi.device_config(i);
stream->write_function(stream, " ------------------------------------------------------------------\n");
- switch (k3l->device_type(i))
+ switch (Globals::_k3lapi.device_type(i))
{
/* E1 boards */
case kdtE1:
@@ -1001,7 +905,7 @@
}
default:
stream->write_function(stream, "| [[ %02d ]] Unknown type '%02d'! Please contact Khomp support for help! |\n"
- , i , k3l->device_type(i));
+ , i , Globals::_k3lapi.device_type(i));
break;
}
}
@@ -1010,120 +914,17 @@
}
/* End of helper functions */
-/* Create a new channel on incoming call */
-KLibraryStatus khomp_channel_from_event(unsigned int KDeviceId, unsigned int KChannel, K3L_EVENT * event)
-{
- switch_core_session_t *session = NULL;
- private_t *tech_pvt = NULL;
- switch_channel_t *channel = NULL;
- char name[128];
-
- if (!(session = switch_core_session_request(khomp_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, NULL))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Initilization Error!\n");
- return ksFail;
- }
-
- switch_core_session_add_stream(session, NULL);
-
- tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t));
- assert(tech_pvt != NULL);
- channel = switch_core_session_get_channel(session);
- if (tech_init(tech_pvt, session) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Initilization Error!\n");
- switch_core_session_destroy(&session);
- return ksFail;
- }
-
-
- /* Get all data from event */
- std::string cidNum;
- std::string destination_number;
- try
- {
- cidNum = k3l->get_param(event, "orig_addr");
- destination_number = k3l->get_param(event, "dest_addr");
- }
- catch ( K3LAPI::get_param_failed & err )
- {
- // TODO: Can we set NULL variables? What should we do if this fails?
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not get param %s on channel %u, board %u.\n", err.name.c_str(), KChannel, KDeviceId);
- }
-
- /*if (switch_strlen_zero(sigmsg->channel->caller_data.cid_num.digits)) {
- if (!switch_strlen_zero(sigmsg->channel->caller_data.ani.digits)) {
- switch_set_string(sigmsg->channel->caller_data.cid_num.digits, sigmsg->channel->caller_data.ani.digits);
- } else {
- switch_set_string(sigmsg->channel->caller_data.cid_num.digits, sigmsg->channel->chan_number);
- }
- }
- */
-
- /* Set the caller profile - Look at documentation */
- tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
- "Khomp",
- "XML", // TODO: Dialplan module to use?
- NULL,
- NULL,
- NULL,
- cidNum.c_str(),
- NULL,
- NULL,
- (char *) modname,
- "default", // TODO: Context to look for on the dialplan?
- destination_number.c_str());
-
- assert(tech_pvt->caller_profile != NULL);
- /* END */
-
- /* WHAT??? - Look at documentation */
- //switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_NONE);
- /* END */
-
- /* */
- snprintf(name, sizeof(name), "Khomp/%u/%u/%s", KDeviceId, KChannel, tech_pvt->caller_profile->destination_number);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect inbound channel %s\n", name);
- switch_channel_set_name(channel, name);
- switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
- /* END */
-
-
- switch_channel_set_state(channel, CS_INIT);
- if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
- switch_core_session_destroy(&session);
- return ksFail;
- }
-
- /* WHAT?
- if (zap_channel_add_token(sigmsg->channel, switch_core_session_get_uuid(session), 0) != ZAP_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding token\n");
- switch_core_session_destroy(&session);
- return ZAP_FAIL;
- }
- */
-
- /* Set the session to the channel */
- k3l->setSession(KDeviceId, KChannel, session);
-
- return ksSuccess;
-}
-
static int32 Kstdcall khomp_event_callback(int32 obj, K3L_EVENT * e)
-{
+{
/* TODO: How do we make sure channels inside FreeSWITCH only change to valid states on K3L? */
switch(e->Code)
{
case EV_NEW_CALL:
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "New call on %u to %s. [EV_NEW_CALL]\n", obj, k3l->get_param(e, "dest_addr").c_str());
- if (khomp_channel_from_event(e->DeviceId, obj, e) != ksSuccess )
- {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Something bad happened while getting channel session. Device:%u/Channel:%u. [EV_CONNECT]\n", e->DeviceId, obj);
- return ksFail;
- }
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "New call on %u to %s. [EV_NEW_CALL]\n", obj, Globals::_k3lapi.get_param(e, "dest_addr").c_str());
try {
- k3l->command(e->DeviceId, obj, CM_RINGBACK, NULL);
- k3l->command(e->DeviceId, obj, CM_CONNECT, NULL);
+ Globals::_k3lapi.command(e->DeviceId, obj, CM_RINGBACK, NULL);
+ Globals::_k3lapi.command(e->DeviceId, obj, CM_CONNECT, NULL);
}
catch (K3LAPI::failed_command & err)
{
@@ -1131,43 +932,31 @@
}
break;
case EV_DISCONNECT:
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Called party dropped the call on: %u. Releasing channel. [EV_DISCONNECT]\n", obj);
+ if (channel_on_hangup(KhompPvt::khompPvt(e->DeviceId, obj)->session()) != SWITCH_STATUS_SUCCESS)
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not hangup channel: %u on board %u. Releasing board channel anyway. [EV_DISCONNECT]\n", obj, e->DeviceId);
+ try
{
- switch_core_session_t * session = NULL;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Called party dropped the call on: %u. Releasing channel. [EV_DISCONNECT]\n", obj);
- try
- {
- session = k3l->getSession(e->DeviceId, obj);
- }
- catch(K3LAPI::invalid_channel & err)
- {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Session does not exist on channel: %u on board %u. Releasing board channel anyway. [EV_DISCONNECT]\n", obj, e->DeviceId);
- }
- if (channel_on_hangup(session) != SWITCH_STATUS_SUCCESS)
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not hangup channel: %u on board %u. Releasing board channel anyway. [EV_DISCONNECT]\n", obj, e->DeviceId);
- try
- {
- k3l->setSession(e->DeviceId, obj, NULL);
- }
- catch(K3LAPI::invalid_channel & err)
- {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "We are trying to set session on an non existent channel: %u on board %u. Releasing channel. [EV_DISCONNECT]\n", obj, e->DeviceId);
- }
- /* Do we need to release on the board? */
- k3l->command(e->DeviceId, obj, CM_DISCONNECT, NULL);
+ Globals::_k3lapi.command(e->DeviceId, obj, CM_DISCONNECT, NULL);
+ KhompPvt::khompPvt(e->DeviceId, obj)->session(NULL);
+ }
+ catch(K3LAPI::invalid_channel & err)
+ {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not send CM_DISCONNECT!\n");
}
break;
case EV_CONNECT:
- switch_core_session_t* session;
+ switch_core_session_t* session;
try
{
- session = k3l->getSession(e->DeviceId ,obj);
+ session = KhompPvt::khompPvt(e->DeviceId, obj)->session();
switch_channel_t *channel;
channel = switch_core_session_get_channel(session);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Call will be answered on board %u, channel %u. [EV_CONNECT]\n", e->DeviceId, obj);
switch_channel_mark_answered(channel);
/* Start listening for audio */
const size_t buffer_size = 16;
- k3l->command(e->DeviceId, obj, CM_LISTEN, (const char *) &buffer_size);
+ Globals::_k3lapi.command(e->DeviceId, obj, CM_LISTEN, (const char *) &buffer_size);
}
catch (K3LAPI::invalid_session & err)
{
@@ -1229,7 +1018,7 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Channel %u on board %u reported failure. [EV_CHANNEL_FAIL]\n", obj, e->DeviceId);
break;
case EV_LINK_STATUS:
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Link %u on board %u changed. [EV_LINK_STATUS]\n", e->DeviceId, obj);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Link %u on board %u changed. [EV_LINK_STATUS]\n", e->DeviceId, obj);
break;
case EV_PHYSICAL_LINK_DOWN:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Link %u on board %u is DOWN. [EV_PHYSICAL_LINK_DOWN]\n", e->DeviceId, obj);
@@ -1275,14 +1064,12 @@
default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "New Event has just arrived on %u with untreated code: %x\n", obj, e->Code);
}
-
+
return ksSuccess;
}
-
static void Kstdcall khomp_audio_listener (int32 deviceid, int32 mixer, byte * read_buffer, int32 read_size)
{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "New audio buffer for deviceid %d, mixer %d, with size %d\n", deviceid, mixer, read_size);
}
/* For Emacs:
More information about the Freeswitch-svn
mailing list