Merge pull request #2724 from signalwire/khomp
[mod_khomp] Remove from tree
This commit is contained in:
commit
0bcc789a47
12
LICENSE
12
LICENSE
|
@ -1484,18 +1484,6 @@ Copyright: 2010 Ilnitskiy Mixim (max.h323@gmail.com)
|
||||||
2010 Georgiewskiy Yuriy (bottleman@icf.org.ru)
|
2010 Georgiewskiy Yuriy (bottleman@icf.org.ru)
|
||||||
License: MPL-1.1
|
License: MPL-1.1
|
||||||
|
|
||||||
Files: src/mod/endpoints/mod_khomp/*
|
|
||||||
Copyright: 2007-2010 Khomp Ind. & Com.
|
|
||||||
License: MPL-1.1 or LGPL-2.1+
|
|
||||||
|
|
||||||
Files: src/mod/endpoints/mod_khomp/mod_khomp.cpp
|
|
||||||
Copyright: 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
|
|
||||||
License: MPL-1.1
|
|
||||||
|
|
||||||
Files: src/mod/endpoints/mod_khomp/commons/base/atomic.hpp
|
|
||||||
Copyright: 1998 Doug Rabson
|
|
||||||
License: BSD-2-clause
|
|
||||||
|
|
||||||
Files: src/mod/languages/mod_java/modjava.c
|
Files: src/mod/languages/mod_java/modjava.c
|
||||||
Copyright: 2007, Damjan Jovanovic <d a m j a n d o t j o v a t g m a i l d o t c o m>
|
Copyright: 2007, Damjan Jovanovic <d a m j a n d o t j o v a t g m a i l d o t c o m>
|
||||||
License: MPL-1.1
|
License: MPL-1.1
|
||||||
|
|
|
@ -71,7 +71,6 @@ dialplans/mod_dialplan_xml
|
||||||
#directories/mod_ldap
|
#directories/mod_ldap
|
||||||
#endpoints/mod_alsa
|
#endpoints/mod_alsa
|
||||||
#endpoints/mod_h323
|
#endpoints/mod_h323
|
||||||
#endpoints/mod_khomp
|
|
||||||
endpoints/mod_loopback
|
endpoints/mod_loopback
|
||||||
#endpoints/mod_opal
|
#endpoints/mod_opal
|
||||||
endpoints/mod_rtc
|
endpoints/mod_rtc
|
||||||
|
|
|
@ -70,7 +70,6 @@ dialplans/mod_dialplan_xml
|
||||||
directories/mod_ldap
|
directories/mod_ldap
|
||||||
#endpoints/mod_alsa
|
#endpoints/mod_alsa
|
||||||
#endpoints/mod_h323
|
#endpoints/mod_h323
|
||||||
#endpoints/mod_khomp
|
|
||||||
endpoints/mod_loopback
|
endpoints/mod_loopback
|
||||||
#endpoints/mod_opal
|
#endpoints/mod_opal
|
||||||
endpoints/mod_rtc
|
endpoints/mod_rtc
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
<!-- <load module="mod_woomera"/> -->
|
<!-- <load module="mod_woomera"/> -->
|
||||||
<!-- <load module="mod_freetdm"/> -->
|
<!-- <load module="mod_freetdm"/> -->
|
||||||
<!-- <load module="mod_skinny"/> -->
|
<!-- <load module="mod_skinny"/> -->
|
||||||
<!-- <load module="mod_khomp"/> -->
|
|
||||||
<load module="mod_rtc"/>
|
<load module="mod_rtc"/>
|
||||||
<!-- <load module="mod_rtmp"/> -->
|
<!-- <load module="mod_rtmp"/> -->
|
||||||
<load module="mod_verto"/>
|
<load module="mod_verto"/>
|
||||||
|
|
|
@ -1079,7 +1079,7 @@ if test "x${ax_cv_c_compiler_vendor}" = "xclang" ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Tested and fixed lot of modules, but some are untested. Will be added back when the core team decide it ready
|
# Tested and fixed lot of modules, but some are untested. Will be added back when the core team decide it ready
|
||||||
# Untested modules : mod_osp mod_opal mod_h323 mod_khomp
|
# Untested modules : mod_osp mod_opal mod_h323
|
||||||
# mod_erlang_event mod_snmp mod_perl mod_java mod_managed
|
# mod_erlang_event mod_snmp mod_perl mod_java mod_managed
|
||||||
#
|
#
|
||||||
#saved_CFLAGS="$CFLAGS"
|
#saved_CFLAGS="$CFLAGS"
|
||||||
|
@ -2160,7 +2160,6 @@ AC_CONFIG_FILES([Makefile
|
||||||
src/mod/directories/mod_ldap/Makefile
|
src/mod/directories/mod_ldap/Makefile
|
||||||
src/mod/endpoints/mod_alsa/Makefile
|
src/mod/endpoints/mod_alsa/Makefile
|
||||||
src/mod/endpoints/mod_h323/Makefile
|
src/mod/endpoints/mod_h323/Makefile
|
||||||
src/mod/endpoints/mod_khomp/Makefile
|
|
||||||
src/mod/endpoints/mod_loopback/Makefile
|
src/mod/endpoints/mod_loopback/Makefile
|
||||||
src/mod/endpoints/mod_opal/Makefile
|
src/mod/endpoints/mod_opal/Makefile
|
||||||
src/mod/endpoints/mod_reference/Makefile
|
src/mod/endpoints/mod_reference/Makefile
|
||||||
|
|
|
@ -43,7 +43,6 @@ avoid_mods=(
|
||||||
codecs/mod_siren
|
codecs/mod_siren
|
||||||
codecs/mod_skel_codec
|
codecs/mod_skel_codec
|
||||||
endpoints/mod_h323
|
endpoints/mod_h323
|
||||||
endpoints/mod_khomp
|
|
||||||
endpoints/mod_opal
|
endpoints/mod_opal
|
||||||
endpoints/mod_reference
|
endpoints/mod_reference
|
||||||
event_handlers/mod_smpp
|
event_handlers/mod_smpp
|
||||||
|
|
|
@ -365,10 +365,6 @@ Description: mod_h323
|
||||||
Adds mod_h323.
|
Adds mod_h323.
|
||||||
Build-Depends: libopenh323-dev | libh323plus-dev, libpt-dev
|
Build-Depends: libopenh323-dev | libh323plus-dev, libpt-dev
|
||||||
|
|
||||||
Module: endpoints/mod_khomp
|
|
||||||
Description: mod_khomp
|
|
||||||
Adds mod_khomp.
|
|
||||||
|
|
||||||
Module: endpoints/mod_loopback
|
Module: endpoints/mod_loopback
|
||||||
Description: mod_loopback
|
Description: mod_loopback
|
||||||
Adds mod_loopback.
|
Adds mod_loopback.
|
||||||
|
|
|
@ -1484,18 +1484,6 @@ Copyright: 2010 Ilnitskiy Mixim (max.h323@gmail.com)
|
||||||
2010 Georgiewskiy Yuriy (bottleman@icf.org.ru)
|
2010 Georgiewskiy Yuriy (bottleman@icf.org.ru)
|
||||||
License: MPL-1.1
|
License: MPL-1.1
|
||||||
|
|
||||||
Files: src/mod/endpoints/mod_khomp/*
|
|
||||||
Copyright: 2007-2010 Khomp Ind. & Com.
|
|
||||||
License: MPL-1.1 or LGPL-2.1+
|
|
||||||
|
|
||||||
Files: src/mod/endpoints/mod_khomp/mod_khomp.cpp
|
|
||||||
Copyright: 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
|
|
||||||
License: MPL-1.1
|
|
||||||
|
|
||||||
Files: src/mod/endpoints/mod_khomp/commons/base/atomic.hpp
|
|
||||||
Copyright: 1998 Doug Rabson
|
|
||||||
License: BSD-2-clause
|
|
||||||
|
|
||||||
Files: src/mod/languages/mod_java/modjava.c
|
Files: src/mod/languages/mod_java/modjava.c
|
||||||
Copyright: 2007, Damjan Jovanovic <d a m j a n d o t j o v a t g m a i l d o t c o m>
|
Copyright: 2007, Damjan Jovanovic <d a m j a n d o t j o v a t g m a i l d o t c o m>
|
||||||
License: MPL-1.1
|
License: MPL-1.1
|
||||||
|
|
|
@ -149,18 +149,6 @@ Rules:
|
||||||
Matches: const\schar\s\*\scopyright\s;
|
Matches: const\schar\s\*\scopyright\s;
|
||||||
Copyright: 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
|
Copyright: 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||||
Justification: prevent false-psitive copyright detection
|
Justification: prevent false-psitive copyright detection
|
||||||
-
|
|
||||||
Glob: src/mod/endpoints/mod_khomp/*
|
|
||||||
Matches: The\scontents\sof\sthis\sfile\sare\ssubject\sto\sthe\sMozilla\sPublic\sLicense\sVersion\s1.1
|
|
||||||
Matches: Alternatively,\sthe\scontents\sof\sthis\sfile\smay\sbe\sused\sunder\sthe\sterms\sof\sthe
|
|
||||||
Matches: GNU\sLesser\sGeneral\sPublic\sLicense\s2\.1.\slicense\s\(the\s.LGPL.\sLicense\),\sin\swhich
|
|
||||||
Matches: version\s2\.1\sof\sthe\sLicense,\sor\s\(at\syour\soption\)\sany\slater\sversion.
|
|
||||||
License: MPL-1.1 or LGPL-2.1+
|
|
||||||
-
|
|
||||||
Glob: src/mod/endpoints/mod_khomp/commons/base/atomic.hpp
|
|
||||||
Matches: Original\scopyright\sfollows[:]
|
|
||||||
Matches: Copyright\s\(c\)\s1998\sDoug\sRabson
|
|
||||||
Copyright: 1998 Doug Rabson
|
|
||||||
-
|
-
|
||||||
Glob: libs/esl/getopt/getopt_long.c
|
Glob: libs/esl/getopt/getopt_long.c
|
||||||
Matches: This\scode\sis\sderived\sfrom\ssoftware\scontributed\sto\sThe\sNetBSD\sFoundation
|
Matches: This\scode\sis\sderived\sfrom\ssoftware\scontributed\sto\sThe\sNetBSD\sFoundation
|
||||||
|
|
|
@ -747,14 +747,6 @@ PostgreSQL native support for FreeSWITCH.
|
||||||
#%description endpoint-h323
|
#%description endpoint-h323
|
||||||
#H.323 endpoint support for FreeSWITCH open source telephony platform
|
#H.323 endpoint support for FreeSWITCH open source telephony platform
|
||||||
|
|
||||||
#%package endpoint-khomp
|
|
||||||
#Summary: khomp endpoint support for FreeSWITCH open source telephony platform
|
|
||||||
#Group: System/Libraries
|
|
||||||
#Requires: %{name} = %{version}-%{release}
|
|
||||||
#
|
|
||||||
#%description endpoint-khomp
|
|
||||||
#Khomp hardware endpoint support for FreeSWITCH open source telephony platform.
|
|
||||||
|
|
||||||
%package endpoint-rtmp
|
%package endpoint-rtmp
|
||||||
Summary: RTPM Endpoint support for FreeSWITCH open source telephony platform
|
Summary: RTPM Endpoint support for FreeSWITCH open source telephony platform
|
||||||
Group: System/Libraries
|
Group: System/Libraries
|
||||||
|
@ -1300,7 +1292,7 @@ ENDPOINTS_MODULES=" \
|
||||||
endpoints/mod_loopback endpoints/mod_rtmp \
|
endpoints/mod_loopback endpoints/mod_rtmp \
|
||||||
endpoints/mod_skinny endpoints/mod_verto endpoints/mod_rtc endpoints/mod_sofia"
|
endpoints/mod_skinny endpoints/mod_verto endpoints/mod_rtc endpoints/mod_sofia"
|
||||||
|
|
||||||
## DISABLED MODULES DUE TO BUILD ISSUES endpoints/mod_h323 endpoints/mod_khomp
|
## DISABLED MODULES DUE TO BUILD ISSUES endpoints/mod_h323
|
||||||
|
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
#
|
#
|
||||||
|
@ -2009,9 +2001,6 @@ fi
|
||||||
#%files endpoint-h323
|
#%files endpoint-h323
|
||||||
#%{MODINSTDIR}/mod_h323.so*
|
#%{MODINSTDIR}/mod_h323.so*
|
||||||
|
|
||||||
#%files endpoint-khomp
|
|
||||||
#%{MODINSTDIR}/mod_khomp.so*
|
|
||||||
|
|
||||||
%files endpoint-rtmp
|
%files endpoint-rtmp
|
||||||
%{MODINSTDIR}/mod_rtmp.so*
|
%{MODINSTDIR}/mod_rtmp.so*
|
||||||
|
|
||||||
|
|
|
@ -1,511 +0,0 @@
|
||||||
<configuration name="khomp.conf" description="Khomp Configuration">
|
|
||||||
<!-- Config for all boards -->
|
|
||||||
<settings>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;; This is the configuration file for the Khomp ;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Endpoint 1.0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
-->
|
|
||||||
|
|
||||||
<channels>
|
|
||||||
<!-- Section for main configurations about channels. -->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Name of the dialplan module in use.
|
|
||||||
(default = XML)
|
|
||||||
|
|
||||||
<param name="dialplan" value="XML"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Enable/disable generalized echo cancellation in the channel, for calls
|
|
||||||
passing inside FreeSWITCH (disabled for bridged calls).
|
|
||||||
(default = yes)
|
|
||||||
|
|
||||||
<param name="echo-canceller" value="yes"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Enable/disable AGC (auto gain control). Should be used carefully, as it
|
|
||||||
can make line noise really loud.
|
|
||||||
(default = yes)
|
|
||||||
|
|
||||||
<param name="auto-gain-control" value="yes"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Enable/disable sending DTMFs out-band as a way to pass detected DTMFs to
|
|
||||||
FreeSWITCH. Needed if FreeSWITCH generates digits for us in bridge application
|
|
||||||
or is being used for IVR ("URA", in pt_BR).
|
|
||||||
(default = yes)
|
|
||||||
|
|
||||||
<param name="out-of-band-dtmfs" value="yes"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Enable/disable DTMF suppression delay. WARNING: if you disable this, DTMFs
|
|
||||||
will not be suppressed anymore! You should only use this option if
|
|
||||||
"out-of-band-dtmfs" is "no".
|
|
||||||
(default = yes)
|
|
||||||
|
|
||||||
<param name="suppression-delay" value="yes"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Adjust connection automagically if a FAX tone is detected.
|
|
||||||
(default = yes)
|
|
||||||
|
|
||||||
<param name="auto-fax-adjustment" value="yes"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Time (is seconds) since connection, when we may detect FAX tone and perform
|
|
||||||
automagical adjustment. After this, FAX tone detection is ignored.
|
|
||||||
Possible values: 0 - 9999
|
|
||||||
(default = 30).
|
|
||||||
|
|
||||||
<param name="fax-adjustment-timeout" value="30"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Enable/disable pulse detection (reported as DTMF digits).
|
|
||||||
(default = yes)
|
|
||||||
|
|
||||||
<param name="pulse-forwarding" value="yes"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Enable correct standard following for R2/MFC protocol. Disabled by default,
|
|
||||||
as using FreeSWITCH behind a PBX may timeout all outgoing calls without this.
|
|
||||||
However, you can set this to "yes" if FreeSWITCH is directly connected to a
|
|
||||||
CO (central office) or to a fast signaling PBX, and have a correct
|
|
||||||
behaviour for condition obtaining/reporting.
|
|
||||||
(default = no)
|
|
||||||
|
|
||||||
<param name="r2-strict-behaviour" value="no"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Set the delay (in ms) after sending ringback condition where audio stream
|
|
||||||
should be opened for the channel. Limited to 25ms min, 500ms max.
|
|
||||||
(default = 250)
|
|
||||||
|
|
||||||
<param name="r2-preconnect-wait" value="250"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Defines the incoming context for calls on E1 channels. Some wildcards are
|
|
||||||
accepted, and described in the bottom of this file.
|
|
||||||
(default = khomp-DD-LL)
|
|
||||||
|
|
||||||
<param name="context-digital" value="khomp-DD-LL"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Defines the incoming context for calls on FXS channels. Some wildcards are
|
|
||||||
accepted, and described in the bottom of this file.
|
|
||||||
(default = khomp-DD-CC)
|
|
||||||
|
|
||||||
<param name="context-fxs" value="khomp-DD-CC"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Defines the incoming context for calls on FXO channels. Some wildcards are
|
|
||||||
accepted, and described in the bottom of this file.
|
|
||||||
(default = khomp-DD-CC)
|
|
||||||
|
|
||||||
<param name="context-fxo" value="khomp-DD-CC"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Defines the incoming context for calls on GSM channels. Some wildcards are
|
|
||||||
accepted, and described in the bottom of this file.
|
|
||||||
(default = khomp-DD-CC)
|
|
||||||
|
|
||||||
<param name="context-gsm-call" value="khomp-DD-CC"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Defines the incoming context for messages on GSM channels. Some wildcards are
|
|
||||||
accepted, and described in the bottom of this file.
|
|
||||||
(default = khomp-sms-DD-CC)
|
|
||||||
|
|
||||||
<param name="context-gsm-sms" value="khomp-sms-DD-CC"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Defines the incoming context for calls on Passive Record boards (KPR). Some
|
|
||||||
wildcards are accepted, and described in the bottom of this file.
|
|
||||||
(default = khomp-DD-CC)
|
|
||||||
|
|
||||||
<param name="context-pr" value="khomp-DD-CC"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Set the logging of messages to console. Possible values (to set more than one,
|
|
||||||
separate the values with comma):
|
|
||||||
|
|
||||||
errors - Error messages, when something goes really wrong.
|
|
||||||
warnings - Warnings, used when something might not be going as expected.
|
|
||||||
messages - Generic messages, used to indicate some information.
|
|
||||||
events - Show received K3L events as console messages.
|
|
||||||
commands - Show sent K3L commands as console messages.
|
|
||||||
audio - Enable messages for K3L audio events (very verbose!).
|
|
||||||
modem - Enable messages for data received from KGSM modems.
|
|
||||||
link - Enable logging of link status changes.
|
|
||||||
standard - Special, enable default messages (RECOMMENDED).
|
|
||||||
all - Special, enable ALL messages (should not be used naively).
|
|
||||||
|
|
||||||
(default = standard)
|
|
||||||
|
|
||||||
<param name="log-to-console" value="standard"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Set the logging of messages to disk. Possible values (to set more than one,
|
|
||||||
separate the values with comma):
|
|
||||||
|
|
||||||
errors - Error messages, when something goes really wrong.
|
|
||||||
warnings - Warnings, used when something might not be going as expected.
|
|
||||||
messages - Generic messages, used to indicate some information.
|
|
||||||
events - Record received K3L events as log messages.
|
|
||||||
commands - Record sent K3L commands as log messages.
|
|
||||||
audio - Enable messages for K3L audio events (very verbose!).
|
|
||||||
modem - Enable messages for data received from KGSM modems.
|
|
||||||
link - Enable logging of link status changes.
|
|
||||||
functions - Enable debugging for functions. Should not be used naively!).
|
|
||||||
threads - Enable debugging for threads. Should not be used naively!).
|
|
||||||
locks - Enable debugging for locks. Should not be used naively!).
|
|
||||||
streams - Enable debugging for streams. Should not be used naively!).
|
|
||||||
standard - Special, enable default messages (RECOMMENDED).
|
|
||||||
debugging - Special, enable debug messages (should not be used naively).
|
|
||||||
all - Special, enable ALL messages (DO NOT USE THIS!).
|
|
||||||
|
|
||||||
(default = standard)
|
|
||||||
|
|
||||||
<param name="log-to-disk" value="standard"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Set the low level tracing. DO NOT USE THIS UNLESS YOU WERE ADVISED TO DO SO.
|
|
||||||
Possible values (to set more than one, separate the values with comma):
|
|
||||||
|
|
||||||
k3l - Enable the low level tracing of board's API.
|
|
||||||
If you are using 'kserver', this option will take no effect. For
|
|
||||||
the k3l tracing to proceed, you will need to (re)start kserver
|
|
||||||
with 'debug' option. E.g. '#> kserver start -debug'.
|
|
||||||
rdsi - Enable ISDN low level debugging.
|
|
||||||
r2 - Enable r2 protocol low level debugging.
|
|
||||||
|
|
||||||
(default = <empty>)
|
|
||||||
|
|
||||||
<param name="trace" value=""/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Set output volume level. Possible values:
|
|
||||||
|
|
||||||
* '+ N' = increase N times;
|
|
||||||
* '- N' = decrease N times.
|
|
||||||
* '0' = leave default.
|
|
||||||
|
|
||||||
(default = 0)
|
|
||||||
|
|
||||||
<param name="output-volume" value="0"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Set input volume level. Can only be used if AGC (and not pulse detection)
|
|
||||||
is enabled on the board configuration. Possible values:
|
|
||||||
|
|
||||||
* '+ N' = increase N times;
|
|
||||||
* '- N' = decrease N times.
|
|
||||||
* '0' = leave default.
|
|
||||||
|
|
||||||
(default = 0)
|
|
||||||
|
|
||||||
<param name="input-volume" value="0"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Sets the account code for calls placed on the channel. The account code may
|
|
||||||
be any alphanumeric string
|
|
||||||
default = <empty>)
|
|
||||||
|
|
||||||
<param name="accountcode" value=""/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Set the language of the channel (useful for selecting audio messages of a
|
|
||||||
specific language on answer).
|
|
||||||
|
|
||||||
(default = <empty>)
|
|
||||||
|
|
||||||
<param name="language" value="pt_BR"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Sets the global orig (CALLERID) base for FXS boards. This number is added
|
|
||||||
to a sequencial number, which is incremented for each FXS board and FXS
|
|
||||||
channel in the system.
|
|
||||||
(default = 0)
|
|
||||||
|
|
||||||
<param name="fxs-global-orig" value="0"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Sets the numbers (separated by comma) in which the 'pbx-dialtone' from
|
|
||||||
FXS boards will be changed to 'co-dialtone' (public tone), when they are
|
|
||||||
pressed.
|
|
||||||
(default = <empty>)
|
|
||||||
|
|
||||||
<param name="fxs-co-dialtone" value="0,90"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Enable or disable sending number of A throught BINA DTMF signalization to
|
|
||||||
a FXS branch.
|
|
||||||
(default = yes)
|
|
||||||
|
|
||||||
<param name="fxs-bina" value="yes"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Enables/disables the use of sharp (#) as an end-of-number digit on FXS
|
|
||||||
channels for instant dialing. This does not affect special numbers which
|
|
||||||
start on sharp, like #8 or #1.
|
|
||||||
(default = yes)
|
|
||||||
|
|
||||||
<param name="fxs-sharp-dial" value="yes" />
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
This is the delay time to really disconnect a channel after the disconnect
|
|
||||||
event arrive. If a connect event comes up in this interval, then the
|
|
||||||
disconnection is ignored and the call keeps going on. Values in ms.
|
|
||||||
(default = 0)
|
|
||||||
|
|
||||||
<param name="disconnect-delay" value="0"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
This timer controls the delay associated with ringback generation in the
|
|
||||||
Khomp channel, when the other side *does not send audio* - in other words,
|
|
||||||
this is used when calling peers located at VoIP channels.
|
|
||||||
Values are in milliseconds.
|
|
||||||
(default = 1500)
|
|
||||||
|
|
||||||
<param name="delay-ringback-co" value="1500"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
This timer controls the delay associated with ringback generation in the
|
|
||||||
Khomp channel when the other side report a continuous stream of audio in
|
|
||||||
silence - in other words, this is used when the audio is present but does
|
|
||||||
not have any tone. Values are in milliseconds.
|
|
||||||
(default = 2500)
|
|
||||||
|
|
||||||
<param name="delay-ringback-pbx" value="2500"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Defines if the channel should ignore some uncommon DTMF digits detected by
|
|
||||||
the board (A, B, C and D). This reduces the number of false positives which
|
|
||||||
may happen sometimes, without affecting correctness on traditional
|
|
||||||
scenarios. However, if you need to pass those digits througth the board,
|
|
||||||
you may need to set this option to 'no'.
|
|
||||||
(default = yes)
|
|
||||||
|
|
||||||
<param name="ignore-letter-dtmfs" value="yes"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
When there is a request to indicate busy for an incoming KFXO call, the
|
|
||||||
ringing channel is taken off hook and then placed on hook, so it now goes
|
|
||||||
to answered state and we can send audio throught the line.
|
|
||||||
|
|
||||||
If the off/on hook time interval is too short, the PSTN may ignore it, and
|
|
||||||
keep the line in a ringing state. If it is too long, the call may be charged.
|
|
||||||
The option below defines the delay between the line being answered and being
|
|
||||||
disconnected, in miliseconds (from 50ms to 90000ms).
|
|
||||||
|
|
||||||
(default = 1250)
|
|
||||||
|
|
||||||
<param name="fxo-busy-disconnection" value="1250"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
For KFXO series boards, defines if audio will be allowed being sent into
|
|
||||||
outgoing calls before it has been connected.
|
|
||||||
(default = yes)
|
|
||||||
|
|
||||||
<param name="fxo-send-pre-audio" value="yes"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Defines the timeout, in seconds, between digits of a FXS board's extension.
|
|
||||||
(default = 7)
|
|
||||||
|
|
||||||
<param name="fxs-digit-timeout" value="7"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Enables/Disables the action of dropping collect calls. If enabled, all
|
|
||||||
collect calls will be dropped no matter what KDropCollectCall is set to.
|
|
||||||
(default = no)
|
|
||||||
|
|
||||||
<param name="drop-collect-call" value="no"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Defines if the activation and deactivation of Kommuter is done automatically by the channel,
|
|
||||||
or manually by the user. Possible values:
|
|
||||||
|
|
||||||
auto - Khomp channel driver starts all kommuter devices at initialization and stops them if the module is unloaded.
|
|
||||||
manual - The user must explicity call the CLI command < khomp kommuter on/off >, that starts or stops the kommuter devices connected to this machine.
|
|
||||||
(default = auto)
|
|
||||||
|
|
||||||
<param name="kommuter-activation" value="auto"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Defines the default value for the Kommuter watchdog in seconds.
|
|
||||||
All kommuters conected to this machine will be initialized with this value,
|
|
||||||
and will commute the links after reaching this time with no response of the channel.
|
|
||||||
The minimum is 0 (will never commute the links), and maximum value is 255 seconds.
|
|
||||||
(default = 10)
|
|
||||||
|
|
||||||
<param name="kommuter-timeout" value="10"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
When adjusted to some DTMF digit sequence, it will define those as the digits
|
|
||||||
to be used to initialize a call transfer using PBX-to-PBX signaling.
|
|
||||||
(default = empty)
|
|
||||||
|
|
||||||
<param name="user-transfer-digits" value="#2"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Defines the digits to be sent when the flash is detected.
|
|
||||||
|
|
||||||
<param name="flash-to-digits" value="*1"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
;;;;;;;;;;;;;;;;;;;; CONTEXTS WILDCARDS ;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
For incoming contexts, you can use the following wildcards:
|
|
||||||
|
|
||||||
'DD' (device number): the sequence number of the board on the
|
|
||||||
system (can be checked using "khomp summary", valid for all
|
|
||||||
board models);
|
|
||||||
|
|
||||||
'LL' (link number): the sequence number of link where the call
|
|
||||||
has arrived on the board. valid only for E1 boards.
|
|
||||||
|
|
||||||
'SSSS' (serial number): the serial number of the board (can
|
|
||||||
be checked using "khomp summary", and it's valid for all
|
|
||||||
board models);
|
|
||||||
|
|
||||||
'CC' (channel number): the channel number on which the call
|
|
||||||
or message has arrived (valid for FXO, FXS and GSM boards);
|
|
||||||
|
|
||||||
'CCC' (channel number): same as above, but valid only for E1
|
|
||||||
channels;
|
|
||||||
-->
|
|
||||||
|
|
||||||
</channels>
|
|
||||||
|
|
||||||
<!-- Section for configuring allocation groups. -->
|
|
||||||
<groups>
|
|
||||||
<!--
|
|
||||||
In this section, you should define options using the following syntax:
|
|
||||||
|
|
||||||
<groupname> = <allocation-string>[:<context>]
|
|
||||||
|
|
||||||
<param name="pstn" value="b0l0 + b1c38"/>
|
|
||||||
<param name="pstn" value="b0l0 + b1c38:from-pstn"/>
|
|
||||||
|
|
||||||
You may define your own groups. In the example above, the group
|
|
||||||
called pstn can be used in the bridge string as <action application="brigde" data="Khomp/Gpstn/..." />
|
|
||||||
or <action application="brigde" data="Khomp/Gpstn/..." />. As a result, the allocation string will be
|
|
||||||
replaced with the one associated with the group "pstn". This is the same
|
|
||||||
of doing <action application="brigde" data="Khomp/b0l0 + b1c38/... />.
|
|
||||||
In the second example, a context is also defined which can be used in
|
|
||||||
extensions.conf for inbound calls on that allocation string's range.
|
|
||||||
-->
|
|
||||||
</groups>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Section for configuring cadences used on FXS boards and the whole
|
|
||||||
channel (fast busy, ringback tones, etc).
|
|
||||||
-->
|
|
||||||
<cadences>
|
|
||||||
<!--
|
|
||||||
Default value for cadences. You may define your own cadences, and
|
|
||||||
also use them in the bridge arguments as "cadence=your_cadence_name".
|
|
||||||
|
|
||||||
"0,0" means a continuous dialtone.
|
|
||||||
|
|
||||||
(default as defined below)
|
|
||||||
<param name="fast-busy" value="100,100" />
|
|
||||||
<param name="ringback" value="1000,4000" />
|
|
||||||
<param name="pbx-dialtone" value="1000,100" />
|
|
||||||
<param name="vm-dialtone " value="1000,100,100,100" />
|
|
||||||
<param name="co-dialtone " value="0,0" />
|
|
||||||
-->
|
|
||||||
</cadences>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Section for configuring CALLERID's associated with FXS boards. -->
|
|
||||||
<fxs-branches>
|
|
||||||
<!--
|
|
||||||
In this section, you should define options using the following syntax:
|
|
||||||
|
|
||||||
'orig_prefix = serial number 0, serial number 1, ...'
|
|
||||||
|
|
||||||
ex: <param name="880" value="111,222"/>
|
|
||||||
|
|
||||||
In the example above (assuming KFXS-SPX boards 1234 and 4535), the
|
|
||||||
branches will be numbered from 800 to 829 in board 1234, and from
|
|
||||||
830 to 859 in board 4535.
|
|
||||||
-->
|
|
||||||
</fxs-branches>
|
|
||||||
|
|
||||||
<!-- Section for configuring FXS hotlines. -->
|
|
||||||
<fxs-hotlines>
|
|
||||||
<!--
|
|
||||||
In this section, you should define options using the following syntax:
|
|
||||||
|
|
||||||
'orig_prefix = destination_number'
|
|
||||||
|
|
||||||
ex: <param name="804" value="32332933" />
|
|
||||||
|
|
||||||
In the example above, the branch numbered 804 will call the number
|
|
||||||
3233-2933 (Khomp support number) every time the FXS branch goes off hook.
|
|
||||||
-->
|
|
||||||
</fxs-hotlines>
|
|
||||||
|
|
||||||
<!-- Section for configuring specific options for FXS branches. -->
|
|
||||||
<fxs-options>
|
|
||||||
<!--
|
|
||||||
In this section, you should define options using the following syntax:
|
|
||||||
|
|
||||||
orig_prefix = option1:value | option2:value | option3:value ...
|
|
||||||
|
|
||||||
ex: <param name="804" value="output-volume:+2" />
|
|
||||||
|
|
||||||
In the example above, the branch numbered 804 will have specific
|
|
||||||
configuration for default output volume set to +2.
|
|
||||||
|
|
||||||
Possible values to options is:
|
|
||||||
context, input-volume, output-volume, language,
|
|
||||||
accountcode, calleridnum, calleridname, flash-to-digits.
|
|
||||||
-->
|
|
||||||
</fxs-options>
|
|
||||||
|
|
||||||
</settings>
|
|
||||||
</configuration>
|
|
|
@ -1,51 +0,0 @@
|
||||||
include $(top_srcdir)/build/modmake.rulesam
|
|
||||||
MODNAME=mod_khomp
|
|
||||||
mod_LTLIBRARIES = mod_khomp.la
|
|
||||||
mod_khomp_la_SOURCES = mod_khomp.cpp
|
|
||||||
mod_khomp_la_CFLAGS = $(AM_CFLAGS)
|
|
||||||
mod_khomp_la_CFLAGS += -I./ -I./include -I./commons -I./commons/base -I./support
|
|
||||||
mod_khomp_la_CFLAGS += -D_REENTRANT -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DK3L_HOSTSYSTEM -DCOMMONS_LIBRARY_USING_FREESWITCH
|
|
||||||
mod_khomp_la_CFLAGS += -DFS_VERSION_MAJOR=`./tools/getversion.sh "SWITCH_VERSION_MAJOR" $(switch_srcdir)`
|
|
||||||
mod_khomp_la_CFLAGS += -DFS_VERSION_MINOR=`./tools/getversion.sh "SWITCH_VERSION_MINOR" $(switch_srcdir)`
|
|
||||||
mod_khomp_la_CFLAGS += -DFS_VERSION_MICRO=`./tools/getversion.sh "SWITCH_VERSION_MICRO" $(switch_srcdir)`
|
|
||||||
mod_khomp_la_LIBADD = $(switch_builddir)/libfreeswitch.la
|
|
||||||
mod_khomp_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lk3l
|
|
||||||
KHOMP_MODDIR=$(switch_srcdir)/src/mod/endpoints/mod_khomp
|
|
||||||
TOOLS_DIR=$(KHOMP_MODDIR)/commons/tools
|
|
||||||
|
|
||||||
mod_khomp_la_SOURCES += ./commons/base/k3lapi.cpp ./commons/base/k3lutil.cpp ./commons/base/config_options.cpp ./commons/base/format.cpp ./commons/base/strings.cpp ./commons/base/ringbuffer.cpp ./commons/base/verbose.cpp ./commons/base/saved_condition.cpp ./commons/base/regex.cpp ./commons/base/timer.cpp ./commons/base/configurator/configfile.cpp ./commons/base/configurator/option.cpp ./commons/base/configurator/section.cpp ./commons/base/configurator/restriction.cpp ./commons/base/verbose_traits.cpp
|
|
||||||
mod_khomp_la_SOURCES += ./support/klog-config.cpp ./support/klog-options.cpp ./support/config_defaults.cpp
|
|
||||||
mod_khomp_la_SOURCES += ./src/globals.cpp ./src/opt.cpp ./src/frame.cpp ./src/utils.cpp ./src/lock.cpp ./src/spec.cpp ./src/applications.cpp ./src/khomp_pvt_fxo.cpp ./src/khomp_pvt_gsm.cpp ./src/khomp_pvt_kxe1.cpp ./src/khomp_pvt_passive.cpp ./src/khomp_pvt.cpp ./src/logger.cpp ./src/cli.cpp
|
|
||||||
|
|
||||||
conf_file_name = khomp.conf.xml
|
|
||||||
conf_file_dir = ./Install/files
|
|
||||||
conf_file_dir_alt = ./conf
|
|
||||||
conf_file_install = $(sysconfdir)/autoload_configs
|
|
||||||
|
|
||||||
BUILT_SOURCES=verbose_traits.hpp verbose_traits.cpp
|
|
||||||
|
|
||||||
verbose_traits.hpp verbose_traits.cpp:
|
|
||||||
@if test ! -f $(KHOMP_MODDIR)/commons/base/verbose_traits.hpp || test ! -f $(KHOMP_MODDIR)/commons/base/verbose_traits.cpp ; then \
|
|
||||||
echo "Generating verbose_traits" ;\
|
|
||||||
bash $(TOOLS_DIR)/generate-verbose-headers.sh $(KHOMP_MODDIR)/commons/base/ include/k3l.h ;\
|
|
||||||
fi;
|
|
||||||
|
|
||||||
install-data-local:
|
|
||||||
@if test "w`kserver --version 2>/dev/null | grep 2.1`" == "w" ; then \
|
|
||||||
echo "###############################################################################" ;\
|
|
||||||
echo "Install k3l from KHOMP." ;\
|
|
||||||
echo "Run: ./tools/getk3l.sh" ;\
|
|
||||||
echo "###############################################################################" ;\
|
|
||||||
exit 1;\
|
|
||||||
fi;
|
|
||||||
@echo "Copy $(conf_file_name)"
|
|
||||||
@if test -d $(conf_file_install) ; then \
|
|
||||||
if test -f $(conf_file_dir)/$(conf_file_name) ; then \
|
|
||||||
cp $(conf_file_dir)/$(conf_file_name) $(conf_file_install)/$(conf_file_name).new ;\
|
|
||||||
else \
|
|
||||||
cp $(conf_file_dir_alt)/$(conf_file_name) $(conf_file_install)/$(conf_file_name).new ;\
|
|
||||||
fi; \
|
|
||||||
if test ! -f "$(conf_file_install)/$(conf_file_name)" ; then \
|
|
||||||
mv $(conf_file_install)/$(conf_file_name).new $(conf_file_install)/$(conf_file_name) ;\
|
|
||||||
fi; \
|
|
||||||
fi;
|
|
|
@ -1,203 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
|
|
||||||
This code was based on FreeBSD 7.X SVN (sys/i386/include/atomic.h),
|
|
||||||
with changes regarding optimizations and generalizations, and a
|
|
||||||
remake of the interface to fit use C++ features.
|
|
||||||
|
|
||||||
Code is distributed under original license.
|
|
||||||
Original copyright follows:
|
|
||||||
|
|
||||||
* Copyright (c) 1998 Doug Rabson
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _ATOMIC_HPP_
|
|
||||||
#define _ATOMIC_HPP_
|
|
||||||
|
|
||||||
namespace Atomic
|
|
||||||
{
|
|
||||||
// Macros used to insert compare and exchange instructions easily into functions.
|
|
||||||
|
|
||||||
#define MAKE_CMPXCHG_FUNCTION(INS, PTR, EXP, VAL, TYPE) \
|
|
||||||
PunnedType pexp; pexp.valtype = EXP; \
|
|
||||||
PunnedType pval; pval.valtype = VAL; \
|
|
||||||
TYPE vexp = *(pexp.podtype); \
|
|
||||||
TYPE vval = *(pval.podtype); \
|
|
||||||
TYPE res; \
|
|
||||||
unsigned char chg = 0; \
|
|
||||||
asm volatile("lock;" INS "sete %1;" \
|
|
||||||
: "=a" (res), /* 0 */ \
|
|
||||||
"=q" (chg), /* 1 */ \
|
|
||||||
"=m" (*(unsigned char **)(PTR)) /* 2 */ \
|
|
||||||
: "r" (vval), /* 3 */ \
|
|
||||||
"a" (vexp), /* 4 */ \
|
|
||||||
"m" (*(unsigned char **)(PTR)) /* 5 */ \
|
|
||||||
: "memory"); \
|
|
||||||
*(pexp.podtype) = res; \
|
|
||||||
return (chg != 0 ? true : false);
|
|
||||||
|
|
||||||
#define MAKE_CMPXCHG8B_FUNCTION(PTR,EXP,VAL) \
|
|
||||||
PunnedType pexp; pexp.valtype = EXP; \
|
|
||||||
PunnedType pval; pval.valtype = VAL; \
|
|
||||||
unsigned long long vexp = *(pexp.podtype); \
|
|
||||||
unsigned long long vval = *(pval.podtype); \
|
|
||||||
unsigned long vval32 = (unsigned long)vval; \
|
|
||||||
unsigned char chg = 0; \
|
|
||||||
asm volatile( \
|
|
||||||
"xchgl %%ebx, %4;" \
|
|
||||||
"lock; cmpxchg8b %2; sete %1;" \
|
|
||||||
"movl %4, %%ebx; " \
|
|
||||||
: "+A" (vexp), /* 0 (result) */ \
|
|
||||||
"=c" (chg) /* 1 */ \
|
|
||||||
: "m" (*(unsigned char**)(PTR)), /* 2 */ \
|
|
||||||
"c" ((unsigned long)(vval >> 32)), \
|
|
||||||
"m" (vval32)); \
|
|
||||||
*(pexp.podtype) = vexp; \
|
|
||||||
return (chg != 0 ? true : false);
|
|
||||||
|
|
||||||
// "movl %%ecx, %4;"
|
|
||||||
//
|
|
||||||
// "m" (*((unsigned long*)(*(pval.podtype)))),
|
|
||||||
// "m" ((unsigned long)(vval >> 32))
|
|
||||||
//
|
|
||||||
// "m" (*((unsigned long*)(&vval))),
|
|
||||||
// "m" ((unsigned long)(vval >> 32))
|
|
||||||
//
|
|
||||||
// unsigned long long vval = *(pval.podtype);
|
|
||||||
// unsigned long long res = (unsigned long long)exp;
|
|
||||||
//
|
|
||||||
// Types used for making CMPXCHG instructions independent from base type.
|
|
||||||
|
|
||||||
template < typename ValType, typename PodType >
|
|
||||||
union PunnedTypeTemplate
|
|
||||||
{
|
|
||||||
ValType * valtype;
|
|
||||||
PodType * podtype;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < int SizeOfType, typename ReturnType >
|
|
||||||
struct HelperCreateCAS;
|
|
||||||
|
|
||||||
template < typename ValType >
|
|
||||||
struct HelperCreateCAS<4, ValType>
|
|
||||||
{
|
|
||||||
#if !defined(__LP64__) && !defined(__LP64)
|
|
||||||
typedef unsigned long BaseType;
|
|
||||||
#else
|
|
||||||
typedef unsigned int BaseType;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef PunnedTypeTemplate< ValType, BaseType > PunnedType;
|
|
||||||
|
|
||||||
inline static bool apply(volatile void *p, ValType * exp, ValType now)
|
|
||||||
{
|
|
||||||
#if !defined(__LP64__) && !defined(__LP64)
|
|
||||||
MAKE_CMPXCHG_FUNCTION("cmpxchgl %3,%5;", p, exp, &now, BaseType);
|
|
||||||
#else
|
|
||||||
MAKE_CMPXCHG_FUNCTION("cmpxchgl %k3,%5;", p, exp, &now, BaseType);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename ValType >
|
|
||||||
struct HelperCreateCAS<8, ValType>
|
|
||||||
{
|
|
||||||
#if !defined(__LP64__) && !defined(__LP64)
|
|
||||||
typedef unsigned long long BaseType;
|
|
||||||
#else
|
|
||||||
typedef unsigned long BaseType;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef PunnedTypeTemplate< ValType, BaseType > PunnedType;
|
|
||||||
|
|
||||||
inline static volatile ValType apply(volatile void *p, ValType * exp, ValType now)
|
|
||||||
{
|
|
||||||
#if !defined(__LP64__) && !defined(__LP64)
|
|
||||||
MAKE_CMPXCHG8B_FUNCTION(p, exp, &now);
|
|
||||||
#else
|
|
||||||
MAKE_CMPXCHG_FUNCTION("cmpxchgq %3,%5;", p, exp, &now, BaseType);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// The CAS function itself.
|
|
||||||
|
|
||||||
template < typename ValType >
|
|
||||||
inline bool doCAS(volatile ValType * p, ValType * o, ValType n)
|
|
||||||
{
|
|
||||||
return HelperCreateCAS<sizeof(ValType), ValType>::apply(static_cast<volatile void *>(p), o, n);
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename ValType >
|
|
||||||
inline bool doCAS(volatile ValType * p, ValType o, ValType n)
|
|
||||||
{
|
|
||||||
return HelperCreateCAS<sizeof(ValType), ValType>::apply(static_cast<volatile void *>(p), &o, n);
|
|
||||||
};
|
|
||||||
|
|
||||||
#undef MAKE_CMPXCHG_32_FUNCTION
|
|
||||||
#undef MAKE_CMPXCHG_64_FUNCTION
|
|
||||||
|
|
||||||
#define MAKE_LOCKED_TEMPLATE(NAME) \
|
|
||||||
template < typename ValType > inline void do##NAME(volatile ValType * p, ValType v); \
|
|
||||||
template < typename ValType > inline void do##NAME(volatile ValType * p);
|
|
||||||
|
|
||||||
#define MAKE_LOCKED_FUNCTION(NAME, TYPE, INS, CONS, VAL) \
|
|
||||||
template < > inline void do##NAME < TYPE > (volatile TYPE * p, TYPE v){ asm volatile("lock;" INS : "=m" (*p) : CONS (VAL), "m" (*p)); } \
|
|
||||||
template < > inline void do##NAME < TYPE > (volatile TYPE * p) { asm volatile("lock;" INS : "=m" (*p) : CONS (1), "m" (*p)); }
|
|
||||||
|
|
||||||
#define MAKE_LOCKED_FUNCTIONS(NAME, TYPE, INS, CONS, VAL) \
|
|
||||||
MAKE_LOCKED_FUNCTION(NAME, TYPE, INS, CONS, VAL) \
|
|
||||||
MAKE_LOCKED_FUNCTION(NAME, unsigned TYPE, INS, CONS, VAL)
|
|
||||||
|
|
||||||
MAKE_LOCKED_TEMPLATE(Add);
|
|
||||||
MAKE_LOCKED_TEMPLATE(Sub);
|
|
||||||
MAKE_LOCKED_TEMPLATE(SetBits);
|
|
||||||
MAKE_LOCKED_TEMPLATE(ClearBits);
|
|
||||||
|
|
||||||
MAKE_LOCKED_FUNCTIONS(Add, int, "addl %1,%0", "ir", v);
|
|
||||||
MAKE_LOCKED_FUNCTIONS(Sub, int, "subl %1,%0", "ir", v);
|
|
||||||
MAKE_LOCKED_FUNCTIONS(SetBits, int, "orl %1,%0", "ir", v);
|
|
||||||
MAKE_LOCKED_FUNCTIONS(ClearBits, int, "andl %1,%0", "ir", ~v);
|
|
||||||
|
|
||||||
#if !defined(__LP64__) && !defined(__LP64)
|
|
||||||
|
|
||||||
MAKE_LOCKED_FUNCTIONS(Add, long, "addl %1,%0", "ir", v);
|
|
||||||
MAKE_LOCKED_FUNCTIONS(Sub, long, "subl %1,%0", "ir", v);
|
|
||||||
MAKE_LOCKED_FUNCTIONS(SetBits, long, "orl %1,%0", "ir", v);
|
|
||||||
MAKE_LOCKED_FUNCTIONS(ClearBits, long, "andl %1,%0", "ir", ~v);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
MAKE_LOCKED_FUNCTIONS(Add, long, "addq %1,%0", "ir", v);
|
|
||||||
MAKE_LOCKED_FUNCTIONS(Sub, long, "subq %1,%0", "ir", v);
|
|
||||||
MAKE_LOCKED_FUNCTIONS(SetBits, long, "orq %1,%0", "ir", v);
|
|
||||||
MAKE_LOCKED_FUNCTIONS(ClearBits, long, "andq %1,%0", "ir", ~v);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _ATOMIC_HPP_ */
|
|
|
@ -1,74 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CONFIG_COMMONS_HPP_
|
|
||||||
#define _CONFIG_COMMONS_HPP_
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/* ASTERISK */
|
|
||||||
#if defined(COMMONS_LIBRARY_USING_ASTERISK)
|
|
||||||
#define COMMONS_IMPLEMENTATION asterisk
|
|
||||||
/****************************************************************************/
|
|
||||||
/* CALLWEAVER */
|
|
||||||
#elif defined(COMMONS_LIBRARY_USING_CALLWEAVER)
|
|
||||||
#define COMMONS_IMPLEMENTATION callweaver
|
|
||||||
/****************************************************************************/
|
|
||||||
/* FREESWITCH */
|
|
||||||
#elif defined(COMMONS_LIBRARY_USING_FREESWITCH)
|
|
||||||
#define COMMONS_IMPLEMENTATION freeswitch
|
|
||||||
/****************************************************************************/
|
|
||||||
/* GNU/LINUX (generic) */
|
|
||||||
#elif defined(COMMONS_LIBRARY_USING_GNU_LINUX)
|
|
||||||
#define COMMONS_IMPLEMENTATION gnulinux
|
|
||||||
/****************************************************************************/
|
|
||||||
#else
|
|
||||||
#error Unknown implementation selected. Please define COMMONS_LIBRARY_USING_* correctly.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define COMMONS_INCLUDE(file) <system/COMMONS_IMPLEMENTATION/file>
|
|
||||||
|
|
||||||
#define COMMONS_VERSION_MAJOR 1
|
|
||||||
#define COMMONS_VERSION_MINOR 1
|
|
||||||
|
|
||||||
#define COMMONS_AT_LEAST(x,y) \
|
|
||||||
((COMMONS_VERSION_MAJOR > x) || (COMMONS_VERSION_MAJOR == x && COMMONS_VERSION_MINOR >= y))
|
|
||||||
|
|
||||||
#endif /* _CONFIG_COMMONS_HPP_ */
|
|
|
@ -1,302 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config_options.hpp>
|
|
||||||
|
|
||||||
void Config::Restriction::checkRange(const std::string & name, const SIntType value, const Range < SIntType > & range)
|
|
||||||
{
|
|
||||||
if (value < range.minimum)
|
|
||||||
throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (too low)") % value % name));
|
|
||||||
|
|
||||||
if (value > range.maximum)
|
|
||||||
throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (too high)") % value % name));
|
|
||||||
|
|
||||||
if (((value - range.minimum) % range.step) != 0)
|
|
||||||
throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (outside allowed step)") % value % name));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Config::Restriction::checkRange(const std::string & name, const UIntType value, const Range < UIntType > & range)
|
|
||||||
{
|
|
||||||
if (value < range.minimum)
|
|
||||||
throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (too low)") % value % name));
|
|
||||||
|
|
||||||
if (value > range.maximum)
|
|
||||||
throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (too high)") % value % name));
|
|
||||||
|
|
||||||
if (((value - range.minimum) % range.step) != 0)
|
|
||||||
throw Failure(STG(FMT("value '%d' out-of-range for option '%s' (outside allowed step)") % value % name));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Config::Restriction::checkStringSet(const std::string & name, const StringType & value, const StringSet & allowed)
|
|
||||||
{
|
|
||||||
if (allowed.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (allowed.find(value) != allowed.end())
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string strlist;
|
|
||||||
|
|
||||||
for (StringSet::const_iterator i = allowed.begin(); i != allowed.end(); i++)
|
|
||||||
{
|
|
||||||
strlist += " '";
|
|
||||||
strlist += (*i);
|
|
||||||
strlist += "'";
|
|
||||||
}
|
|
||||||
|
|
||||||
throw Failure(STG(FMT("value '%s' not allowed for option '%s' (allowed values:%s)")
|
|
||||||
% value % name % strlist));
|
|
||||||
}
|
|
||||||
|
|
||||||
Config::Option::Option(std::string name, Config::Option::StringMemberType value, const StringType defvalue, StringSet & allowed, bool listme)
|
|
||||||
: _myname(name), _option(InnerStringType(name, value, defvalue, allowed)), _listme(listme), _values(NULL)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Config::Option::Option(std::string name, Config::Option::StringMemberType value, const StringType defvalue, bool listme)
|
|
||||||
: _myname(name), _option(InnerStringType(name, value, defvalue)), _listme(listme), _values(NULL)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Config::Option::Option(std::string name, Config::Option::BooleanMemberType value, const BooleanType defvalue, bool listme)
|
|
||||||
: _myname(name), _option(InnerBooleanType(name, value, defvalue)), _listme(listme), _values(NULL)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Config::Option::Option(std::string name, Config::Option::SIntMemberType value, const SIntType defvalue,
|
|
||||||
SIntType min, SIntType max, SIntType step, bool listme)
|
|
||||||
: _myname(name), _option(InnerSIntType(name, value, defvalue, min, max, step)), _listme(listme), _values(NULL)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Config::Option::Option(std::string name, Config::Option::UIntMemberType value, const UIntType defvalue,
|
|
||||||
UIntType min, UIntType max, UIntType step, bool listme)
|
|
||||||
: _myname(name), _option(InnerUIntType(name, value, defvalue, min, max, step)), _listme(listme), _values(NULL)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Config::Option::Option(const Config::Option & o)
|
|
||||||
: _myname(o._myname), _option(o._option), _listme(o._listme), _values(o._values)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Config::Option::Option(std::string name, Config::Option::FunctionMemberType value, const StringType defvalue, StringSet & allowed, bool listme)
|
|
||||||
: _myname(name), _option(InnerFunctionType(name, value, defvalue, allowed)), _listme(listme), _values(NULL)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Config::Option::Option(std::string name, Config::Option::FunctionMemberType value, const StringType defvalue, bool listme)
|
|
||||||
: _myname(name), _option(InnerFunctionType(name, value, defvalue)), _listme(listme), _values(NULL)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Config::Option::~Option(void)
|
|
||||||
{
|
|
||||||
if (_values)
|
|
||||||
{
|
|
||||||
for (unsigned int i = 0; _values[i] != NULL; i++)
|
|
||||||
delete _values[i];
|
|
||||||
|
|
||||||
delete[] _values;
|
|
||||||
_values = NULL;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const char ** Config::Option::values(void)
|
|
||||||
{
|
|
||||||
if (_values != NULL)
|
|
||||||
return _values;
|
|
||||||
|
|
||||||
/**/ if (_option.check<InnerBooleanType>())
|
|
||||||
{
|
|
||||||
_values = new const char*[3];
|
|
||||||
|
|
||||||
_values[0] = strdup("yes");
|
|
||||||
_values[1] = strdup("no");
|
|
||||||
_values[2] = NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (_option.check<InnerSIntType>())
|
|
||||||
{
|
|
||||||
const InnerSIntType & tmp = _option.get<InnerSIntType>();
|
|
||||||
|
|
||||||
unsigned int count = ((tmp._range.maximum - tmp._range.minimum) / tmp._range.step) + 1;
|
|
||||||
unsigned int index = 0;
|
|
||||||
|
|
||||||
_values = new const char*[count + 1];
|
|
||||||
|
|
||||||
for (SIntType i = tmp._range.minimum; i <= tmp._range.maximum; i += tmp._range.step, ++index)
|
|
||||||
_values[index] = strdup(STG(FMT("%d") % i).c_str());
|
|
||||||
|
|
||||||
_values[index] = NULL;
|
|
||||||
}
|
|
||||||
else if (_option.check<InnerUIntType>())
|
|
||||||
{
|
|
||||||
const InnerUIntType & tmp = _option.get<InnerUIntType>();
|
|
||||||
|
|
||||||
unsigned int count = ((tmp._range.maximum - tmp._range.minimum) / tmp._range.step) + 1;
|
|
||||||
unsigned int index = 0;
|
|
||||||
|
|
||||||
_values = new const char*[count + 1];
|
|
||||||
|
|
||||||
for (UIntType i = tmp._range.minimum; i <= tmp._range.maximum; i += tmp._range.step, ++index)
|
|
||||||
_values[index] = strdup(STG(FMT("%d") % i).c_str());
|
|
||||||
|
|
||||||
_values[index] = NULL;
|
|
||||||
}
|
|
||||||
else if (_option.check<InnerStringType>())
|
|
||||||
{
|
|
||||||
const InnerStringType & tmp = _option.get<InnerStringType>();
|
|
||||||
|
|
||||||
_values = new const char*[ tmp._allowed.size() + 1 ];
|
|
||||||
|
|
||||||
unsigned int index = 0;
|
|
||||||
|
|
||||||
for (StringSet::iterator i = tmp._allowed.begin(); i != tmp._allowed.end(); ++i, ++index)
|
|
||||||
_values[index] = strdup((*i).c_str());
|
|
||||||
|
|
||||||
_values[index] = NULL;
|
|
||||||
}
|
|
||||||
else if (_option.check<InnerFunctionType>())
|
|
||||||
{
|
|
||||||
const InnerFunctionType & tmp = _option.get<InnerFunctionType>();
|
|
||||||
|
|
||||||
_values = new const char*[ tmp._allowed.size() + 1 ];
|
|
||||||
|
|
||||||
unsigned int index = 0;
|
|
||||||
|
|
||||||
for (StringSet::iterator i = tmp._allowed.begin(); i != tmp._allowed.end(); ++i, ++index)
|
|
||||||
_values[index] = strdup((*i).c_str());
|
|
||||||
|
|
||||||
_values[index] = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw Failure(STG(FMT("values() not implemented for type used in option '%s'") % _myname));
|
|
||||||
}
|
|
||||||
|
|
||||||
return _values;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*********************************/
|
|
||||||
|
|
||||||
Config::Options::Options(void)
|
|
||||||
: _values(NULL)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Config::Options::~Options()
|
|
||||||
{
|
|
||||||
if (_values)
|
|
||||||
{
|
|
||||||
for (unsigned int i = 0; _values[i] != NULL; i++)
|
|
||||||
free((void*)(_values[i]));
|
|
||||||
|
|
||||||
delete[] _values;
|
|
||||||
_values = NULL;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool Config::Options::add(Config::Option option)
|
|
||||||
{
|
|
||||||
std::pair<OptionMap::iterator, bool> ret = _map.insert(OptionPair(option.name(), option));
|
|
||||||
|
|
||||||
return ret.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Config::Options::synonym(std::string equiv_opt, std::string main_opt)
|
|
||||||
{
|
|
||||||
std::pair<SynOptionMap::iterator, bool> ret = _syn_map.insert(SynOptionPair(equiv_opt, main_opt));
|
|
||||||
|
|
||||||
return ret.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
Config::StringSet Config::Options::options(void)
|
|
||||||
{
|
|
||||||
StringSet res;
|
|
||||||
|
|
||||||
for (OptionMap::iterator i = _map.begin(); i != _map.end(); i++)
|
|
||||||
res.insert(i->first);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char ** Config::Options::values(const char * name)
|
|
||||||
{
|
|
||||||
OptionMap::iterator iter = find_option(name);
|
|
||||||
|
|
||||||
if (iter == _map.end())
|
|
||||||
throw Failure(STG(FMT("unknown option '%s'") % name));
|
|
||||||
|
|
||||||
return iter->second.values();
|
|
||||||
}
|
|
||||||
|
|
||||||
const char ** Config::Options::values(void)
|
|
||||||
{
|
|
||||||
if (_values != NULL)
|
|
||||||
return _values;
|
|
||||||
|
|
||||||
unsigned int count = 0;
|
|
||||||
|
|
||||||
for (OptionMap::iterator i = _map.begin(); i != _map.end(); ++i)
|
|
||||||
if (i->second.listme())
|
|
||||||
++count;
|
|
||||||
|
|
||||||
_values = new const char*[ count + 1 ];
|
|
||||||
|
|
||||||
unsigned int index = 0;
|
|
||||||
|
|
||||||
for (OptionMap::iterator i = _map.begin(); i != _map.end(); ++i)
|
|
||||||
{
|
|
||||||
if (i->second.listme())
|
|
||||||
{
|
|
||||||
_values[index] = strdup(i->first.c_str());
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_values[index] = NULL;
|
|
||||||
|
|
||||||
return _values;
|
|
||||||
}
|
|
||||||
|
|
||||||
Config::Options::OptionMap::iterator Config::Options::find_option(std::string name)
|
|
||||||
{
|
|
||||||
SynOptionMap::iterator syn_iter = _syn_map.find(name);
|
|
||||||
|
|
||||||
if (syn_iter != _syn_map.end())
|
|
||||||
name = syn_iter->second;
|
|
||||||
|
|
||||||
OptionMap::iterator iter = _map.find(name);
|
|
||||||
|
|
||||||
return iter;
|
|
||||||
}
|
|
|
@ -1,798 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CONFIG_OPTIONS_HPP_
|
|
||||||
#define _CONFIG_OPTIONS_HPP_
|
|
||||||
|
|
||||||
#include <set>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include <strings.hpp>
|
|
||||||
#include <format.hpp>
|
|
||||||
#include <tagged_union.hpp>
|
|
||||||
#include <function.hpp>
|
|
||||||
#include <variable.hpp>
|
|
||||||
|
|
||||||
namespace Config
|
|
||||||
{
|
|
||||||
/* exceptions */
|
|
||||||
|
|
||||||
struct Failure: public std::runtime_error
|
|
||||||
{
|
|
||||||
Failure(const std::string & msg) : std::runtime_error(msg) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EmptyValue: public std::runtime_error
|
|
||||||
{
|
|
||||||
EmptyValue(): std::runtime_error("accessed option still not loaded from configuration") {};
|
|
||||||
};
|
|
||||||
|
|
||||||
/* types */
|
|
||||||
|
|
||||||
typedef int SIntType;
|
|
||||||
typedef unsigned int UIntType;
|
|
||||||
typedef bool BooleanType;
|
|
||||||
typedef std::string StringType;
|
|
||||||
|
|
||||||
template < typename Type >
|
|
||||||
struct Value;
|
|
||||||
|
|
||||||
template < typename Type >
|
|
||||||
struct InnerOptionBase;
|
|
||||||
|
|
||||||
template < typename Type >
|
|
||||||
struct InnerOption;
|
|
||||||
|
|
||||||
struct Option;
|
|
||||||
|
|
||||||
/* here we go! */
|
|
||||||
|
|
||||||
template < typename Type >
|
|
||||||
struct Range
|
|
||||||
{
|
|
||||||
Range(const Type _minimum, const Type _maximum, const Type _step)
|
|
||||||
: minimum(_minimum), maximum(_maximum), step(_step) {};
|
|
||||||
|
|
||||||
const Type minimum, maximum, step;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::set < std::string > StringSet;
|
|
||||||
|
|
||||||
template < typename Type >
|
|
||||||
struct Value: COUNTER_SUPER(Value < Type >)
|
|
||||||
{
|
|
||||||
friend class COUNTER_CLASS(Value < Type >);
|
|
||||||
friend class InnerOptionBase< Type >;
|
|
||||||
friend class InnerOption < Type >;
|
|
||||||
friend class Option;
|
|
||||||
|
|
||||||
Value()
|
|
||||||
: _tmpval(0), _stored(0), _loaded(false), _inited(false)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Value(const Value & o)
|
|
||||||
: COUNTER_REFER(o, Value < Type >),
|
|
||||||
_tmpval(o._tmpval), _stored(o._stored),
|
|
||||||
_loaded(o._loaded), _inited(o._inited)
|
|
||||||
{};
|
|
||||||
|
|
||||||
const Type & operator()(void) const
|
|
||||||
{
|
|
||||||
if (!_inited)
|
|
||||||
throw EmptyValue();
|
|
||||||
|
|
||||||
if (!_stored)
|
|
||||||
return *_tmpval;
|
|
||||||
|
|
||||||
return *_stored;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Type & get(void) const { return operator()(); };
|
|
||||||
bool loaded(void) const { return _loaded; };
|
|
||||||
|
|
||||||
void store(const Type val)
|
|
||||||
{
|
|
||||||
if (_tmpval)
|
|
||||||
{
|
|
||||||
delete _tmpval;
|
|
||||||
_tmpval = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_tmpval = new Type(val);
|
|
||||||
|
|
||||||
_loaded = true;
|
|
||||||
_inited = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void unreference(void)
|
|
||||||
{
|
|
||||||
_inited = false;
|
|
||||||
_loaded = false;
|
|
||||||
|
|
||||||
if (_tmpval)
|
|
||||||
{
|
|
||||||
delete _tmpval;
|
|
||||||
_tmpval = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_stored)
|
|
||||||
{
|
|
||||||
delete _stored;
|
|
||||||
_stored = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void commit(Type def)
|
|
||||||
{
|
|
||||||
if (_tmpval)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
delete _stored;
|
|
||||||
_stored = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_stored = _tmpval;
|
|
||||||
_tmpval = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!_stored)
|
|
||||||
_stored = new Type(def);
|
|
||||||
}
|
|
||||||
|
|
||||||
_loaded = true;
|
|
||||||
_inited = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
void reset(void)
|
|
||||||
{
|
|
||||||
_loaded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const Type * _tmpval;
|
|
||||||
const Type * _stored;
|
|
||||||
bool _loaded;
|
|
||||||
bool _inited;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FunctionValue
|
|
||||||
{
|
|
||||||
friend class InnerFunctionType;
|
|
||||||
friend class Option;
|
|
||||||
|
|
||||||
FunctionValue()
|
|
||||||
: _loaded(false), _inited(false) {};
|
|
||||||
|
|
||||||
virtual ~FunctionValue() {};
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void operator()(const StringType & val)
|
|
||||||
{
|
|
||||||
throw Failure("undefined operator() for value");
|
|
||||||
}
|
|
||||||
|
|
||||||
const StringType & get(void) const
|
|
||||||
{
|
|
||||||
if (!_inited)
|
|
||||||
throw EmptyValue();
|
|
||||||
|
|
||||||
return _stored;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool loaded(void) const { return _loaded; };
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void commit(const StringType def)
|
|
||||||
{
|
|
||||||
if (_tmpval.empty())
|
|
||||||
{
|
|
||||||
_stored = def;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_stored = _tmpval;
|
|
||||||
_tmpval.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
operator()(_stored);
|
|
||||||
|
|
||||||
_loaded = true;
|
|
||||||
_inited = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
void store(const StringType val)
|
|
||||||
{
|
|
||||||
_tmpval = val;
|
|
||||||
_loaded = true;
|
|
||||||
_inited = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset(void)
|
|
||||||
{
|
|
||||||
_loaded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
StringType _tmpval;
|
|
||||||
StringType _stored;
|
|
||||||
bool _loaded;
|
|
||||||
bool _inited;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* NOTE: we use a non-templated classe to place this functions inside the .cpp */
|
|
||||||
struct Restriction
|
|
||||||
{
|
|
||||||
static void checkRange(const std::string & name, const SIntType value, const Range < SIntType > & range);
|
|
||||||
static void checkRange(const std::string & name, const UIntType value, const Range < UIntType > & range);
|
|
||||||
static void checkStringSet(const std::string & name, const StringType & value, const StringSet & allowed);
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename Type >
|
|
||||||
struct InnerOptionBase
|
|
||||||
{
|
|
||||||
typedef Variable < Value < Type > > MemberValue;
|
|
||||||
|
|
||||||
InnerOptionBase(const std::string name, MemberValue option, const Type defvalue)
|
|
||||||
: _name(name), _option(option), _default(defvalue) {};
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void reset(Object * const obj) const
|
|
||||||
{
|
|
||||||
_option(obj).reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
const Type & get(const Object * const obj) const
|
|
||||||
{
|
|
||||||
return _option(obj).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
bool loaded(const Object * const obj) const
|
|
||||||
{
|
|
||||||
return _option(obj).loaded();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const std::string _name;
|
|
||||||
MemberValue _option;
|
|
||||||
const Type _default;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < >
|
|
||||||
struct InnerOption < SIntType >: public InnerOptionBase < SIntType >
|
|
||||||
{
|
|
||||||
typedef InnerOptionBase < SIntType > Super;
|
|
||||||
typedef Super::MemberValue MemberValue;
|
|
||||||
|
|
||||||
InnerOption(const std::string name, MemberValue option, const SIntType defval,
|
|
||||||
const SIntType min, const SIntType max, const SIntType step)
|
|
||||||
: Super(name, option, defval), _range(min, max, step) {};
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void commit(Object * const obj) const
|
|
||||||
{
|
|
||||||
Restriction::checkRange(_name, _default, _range);
|
|
||||||
_option(obj).commit(_default);
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void store(Object * const obj, const SIntType stored) const
|
|
||||||
{
|
|
||||||
Restriction::checkRange(_name, _default, _range);
|
|
||||||
_option(obj).store(stored);
|
|
||||||
}
|
|
||||||
|
|
||||||
using Super::reset;
|
|
||||||
using Super::get;
|
|
||||||
|
|
||||||
const Range< SIntType > _range;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < >
|
|
||||||
struct InnerOption < UIntType >: public InnerOptionBase < UIntType >
|
|
||||||
{
|
|
||||||
typedef InnerOptionBase < UIntType > Super;
|
|
||||||
typedef Super::MemberValue MemberValue;
|
|
||||||
|
|
||||||
InnerOption(const std::string name, MemberValue option, const UIntType defval,
|
|
||||||
const UIntType min, const UIntType max, const UIntType step)
|
|
||||||
: Super(name, option, defval), _range(min, max, step) {};
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void commit(Object * const obj) const
|
|
||||||
{
|
|
||||||
Restriction::checkRange(_name, _default, _range);
|
|
||||||
_option(obj).commit(_default);
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void store(Object * const obj, const UIntType stored) const
|
|
||||||
{
|
|
||||||
Restriction::checkRange(_name, _default, _range);
|
|
||||||
_option(obj).store(stored);
|
|
||||||
}
|
|
||||||
|
|
||||||
using Super::reset;
|
|
||||||
using Super::get;
|
|
||||||
|
|
||||||
const Range< UIntType > _range;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < >
|
|
||||||
struct InnerOption < BooleanType >: public InnerOptionBase < BooleanType >
|
|
||||||
{
|
|
||||||
typedef InnerOptionBase < BooleanType > Super;
|
|
||||||
typedef Super::MemberValue MemberValue;
|
|
||||||
|
|
||||||
InnerOption(std::string name, MemberValue option, BooleanType defval)
|
|
||||||
: Super(name, option, defval) {};
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void commit(Object * obj) const
|
|
||||||
{
|
|
||||||
_option(obj).commit(_default);
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void store(Object * obj, BooleanType stored) const
|
|
||||||
{
|
|
||||||
_option(obj).store(stored);
|
|
||||||
}
|
|
||||||
|
|
||||||
using Super::reset;
|
|
||||||
using Super::get;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < >
|
|
||||||
struct InnerOption < StringType >: public InnerOptionBase < StringType >
|
|
||||||
{
|
|
||||||
typedef InnerOptionBase < StringType > Super;
|
|
||||||
typedef Super::MemberValue MemberValue;
|
|
||||||
|
|
||||||
InnerOption(const std::string name, MemberValue option, const StringType defval, const StringSet & allowed)
|
|
||||||
: Super(name, option, defval), _allowed(allowed) {};
|
|
||||||
|
|
||||||
InnerOption(const std::string name, MemberValue option, const StringType defval)
|
|
||||||
: Super(name, option, defval) {};
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void commit(Object * const obj) const
|
|
||||||
{
|
|
||||||
Restriction::checkStringSet(_name, _default, _allowed);
|
|
||||||
_option(obj).commit(_default);
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void store(Object * const obj, const StringType stored) const
|
|
||||||
{
|
|
||||||
Restriction::checkStringSet(_name, _default, _allowed);
|
|
||||||
_option(obj).store(stored);
|
|
||||||
}
|
|
||||||
|
|
||||||
using Super::reset;
|
|
||||||
using Super::get;
|
|
||||||
|
|
||||||
const StringSet _allowed;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct InnerFunctionType
|
|
||||||
{
|
|
||||||
typedef Variable < FunctionValue > MemberValue;
|
|
||||||
|
|
||||||
InnerFunctionType(const std::string name, MemberValue option, const StringType defval, const StringSet & allowed)
|
|
||||||
: _name(name), _option(option), _default(defval), _allowed(allowed) {};
|
|
||||||
|
|
||||||
InnerFunctionType(const std::string name, MemberValue option, const StringType defval)
|
|
||||||
: _name(name), _option(option), _default(defval) {};
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
const StringType & get(const Object * const obj) const
|
|
||||||
{
|
|
||||||
return _option(obj).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
bool loaded(const Object * const obj) const
|
|
||||||
{
|
|
||||||
return _option(obj).loaded();
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void reset(Object * const obj) const
|
|
||||||
{
|
|
||||||
_option(obj).reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void commit(Object * const obj) const
|
|
||||||
{
|
|
||||||
Restriction::checkStringSet(_name, _default, _allowed);
|
|
||||||
_option(obj).commit(_default);
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void store(Object * const obj, const StringType stored) const
|
|
||||||
{
|
|
||||||
Restriction::checkStringSet(_name, _default, _allowed);
|
|
||||||
_option(obj).store(stored);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const std::string _name;
|
|
||||||
MemberValue _option;
|
|
||||||
const StringType _default;
|
|
||||||
|
|
||||||
public:
|
|
||||||
const StringSet _allowed;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Option
|
|
||||||
{
|
|
||||||
typedef InnerOption < SIntType > InnerSIntType;
|
|
||||||
typedef InnerOption < UIntType > InnerUIntType;
|
|
||||||
typedef InnerOption < BooleanType > InnerBooleanType;
|
|
||||||
typedef InnerOption < StringType > InnerStringType;
|
|
||||||
|
|
||||||
typedef Variable < Value < SIntType > > SIntMemberType;
|
|
||||||
typedef Variable < Value < UIntType > > UIntMemberType;
|
|
||||||
typedef Variable < Value < BooleanType > > BooleanMemberType;
|
|
||||||
typedef Variable < Value < StringType > > StringMemberType;
|
|
||||||
|
|
||||||
typedef Variable < FunctionValue > FunctionMemberType;
|
|
||||||
|
|
||||||
typedef Tagged::Union < InnerStringType,
|
|
||||||
Tagged::Union < InnerBooleanType,
|
|
||||||
Tagged::Union < InnerSIntType ,
|
|
||||||
Tagged::Union < InnerUIntType,
|
|
||||||
Tagged::Union < InnerFunctionType > > > > >
|
|
||||||
InnerType;
|
|
||||||
|
|
||||||
explicit Option(std::string, StringMemberType, const StringType, StringSet & allowed, bool listme = true);
|
|
||||||
explicit Option(std::string, StringMemberType, const StringType = "", bool listme = true);
|
|
||||||
explicit Option(std::string, SIntMemberType, const SIntType = 0, SIntType min = INT_MIN, SIntType max = INT_MAX, SIntType step = 1, bool listme = true);
|
|
||||||
explicit Option(std::string, UIntMemberType, const UIntType = 0, UIntType min = 0, UIntType max = UINT_MAX, UIntType step = 1, bool listme = true);
|
|
||||||
explicit Option(std::string, BooleanMemberType, const BooleanType = false, bool listme = true);
|
|
||||||
|
|
||||||
explicit Option(std::string, FunctionMemberType, const StringType, StringSet & allowed, bool listme = true);
|
|
||||||
explicit Option(std::string, FunctionMemberType, const StringType = "", bool listme = true);
|
|
||||||
|
|
||||||
Option(const Option & o);
|
|
||||||
|
|
||||||
~Option(void);
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void set(Object * object, std::string value)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
/**/ if (_option.check<InnerFunctionType>()) _option.get<InnerFunctionType>().store(object, value);
|
|
||||||
else if (_option.check<InnerStringType>()) _option.get<InnerStringType>().store(object, value);
|
|
||||||
else if (_option.check<InnerBooleanType>()) _option.get<InnerBooleanType>().store(object, Strings::toboolean(value));
|
|
||||||
else if (_option.check<InnerSIntType>()) _option.get<InnerSIntType>().store(object, Strings::tolong(value));
|
|
||||||
else if (_option.check<InnerUIntType>()) _option.get<InnerUIntType>().store(object, Strings::toulong(value));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw Failure(STG(FMT("set() not implemented for type used in option '%s'") % _myname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Strings::invalid_value & e)
|
|
||||||
{
|
|
||||||
throw Failure(STG(FMT("got invalid value '%s' for option '%s'") % value % _myname));
|
|
||||||
}
|
|
||||||
catch (EmptyVariable & e)
|
|
||||||
{
|
|
||||||
throw Failure(STG(FMT("uninitialized variable while setting value '%s' for option '%s'") % value % _myname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
std::string get(const Object * const object) const
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
/**/ if (_option.check<InnerFunctionType>()) return _option.get<InnerFunctionType>().get(object);
|
|
||||||
else if (_option.check<InnerStringType>()) return _option.get<InnerStringType>().get(object);
|
|
||||||
else if (_option.check<InnerBooleanType>()) return (_option.get<InnerBooleanType>().get(object) ? "yes" : "no");
|
|
||||||
else if (_option.check<InnerSIntType>()) return STG(FMT("%d") % _option.get<InnerSIntType>().get(object));
|
|
||||||
else if (_option.check<InnerUIntType>()) return STG(FMT("%u") % _option.get<InnerUIntType>().get(object));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw Failure(STG(FMT("get() not implemented for type used in option '%s'") % _myname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (EmptyVariable & e)
|
|
||||||
{
|
|
||||||
throw Failure(STG(FMT("uninitialized variable while getting value for option '%s'") % _myname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
bool loaded(const Object * const object) const
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
/**/ if (_option.check<InnerFunctionType>()) return _option.get<InnerFunctionType>().loaded(object);
|
|
||||||
else if (_option.check<InnerBooleanType>()) return _option.get<InnerBooleanType>().loaded(object);
|
|
||||||
else if (_option.check<InnerStringType>()) return _option.get<InnerStringType>().loaded(object);
|
|
||||||
else if (_option.check<InnerSIntType>()) return _option.get<InnerSIntType>().loaded(object);
|
|
||||||
else if (_option.check<InnerUIntType>()) return _option.get<InnerUIntType>().loaded(object);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw Failure(STG(FMT("loaded() not implemented for type used in option '%s'") % _myname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (EmptyVariable & e)
|
|
||||||
{
|
|
||||||
throw Failure(STG(FMT("uninitialized variable while checking load status for option '%s'") % _myname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void reset(Object * const object)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
/**/ if (_option.check<InnerFunctionType>()) _option.get<InnerFunctionType>().reset(object);
|
|
||||||
else if (_option.check<InnerBooleanType>()) _option.get<InnerBooleanType>().reset(object);
|
|
||||||
else if (_option.check<InnerStringType>()) _option.get<InnerStringType>().reset(object);
|
|
||||||
else if (_option.check<InnerSIntType>()) _option.get<InnerSIntType>().reset(object);
|
|
||||||
else if (_option.check<InnerUIntType>()) _option.get<InnerUIntType>().reset(object);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw Failure(STG(FMT("reset() not implemented for type used in option '%s'") % _myname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (EmptyVariable & e)
|
|
||||||
{
|
|
||||||
throw Failure(STG(FMT("uninitialized variable while reseting status for option '%s'") % _myname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void commit(Object * const object)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
/**/ if (_option.check<InnerFunctionType>()) _option.get<InnerFunctionType>().commit(object);
|
|
||||||
else if (_option.check<InnerBooleanType>()) _option.get<InnerBooleanType>().commit(object);
|
|
||||||
else if (_option.check<InnerStringType>()) _option.get<InnerStringType>().commit(object);
|
|
||||||
else if (_option.check<InnerSIntType>()) _option.get<InnerSIntType>().commit(object);
|
|
||||||
else if (_option.check<InnerUIntType>()) _option.get<InnerUIntType>().commit(object);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw Failure(STG(FMT("commit() not implemented for type used in option '%s'") % _myname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (EmptyVariable & e)
|
|
||||||
{
|
|
||||||
throw Failure(STG(FMT("uninitialized variable while commiting option '%s'") % _myname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string & name(void) const { return _myname; }
|
|
||||||
bool listme(void) const { return _listme; };
|
|
||||||
|
|
||||||
const char ** values(void);
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void copyFrom(const Object * const srcobj, Object * const dstobj, bool force = false)
|
|
||||||
{
|
|
||||||
if (loaded(dstobj) && !force)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (loaded(srcobj))
|
|
||||||
set(dstobj, get(srcobj));
|
|
||||||
else
|
|
||||||
reset(dstobj);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const std::string _myname;
|
|
||||||
InnerType _option;
|
|
||||||
const bool _listme;
|
|
||||||
const char ** _values;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Options
|
|
||||||
{
|
|
||||||
typedef std::vector < std::string > Messages;
|
|
||||||
|
|
||||||
Options();
|
|
||||||
~Options();
|
|
||||||
|
|
||||||
typedef std::set < std::string > StringSet;
|
|
||||||
|
|
||||||
typedef std::map < std::string, Option > OptionMap;
|
|
||||||
typedef std::pair < std::string, Option > OptionPair;
|
|
||||||
|
|
||||||
typedef std::map < std::string, std::string > SynOptionMap;
|
|
||||||
typedef std::pair < std::string, std::string > SynOptionPair;
|
|
||||||
|
|
||||||
bool add(Option option);
|
|
||||||
|
|
||||||
/* only valid in "process" (for backwards compatibility config files) */
|
|
||||||
bool synonym(std::string, std::string);
|
|
||||||
|
|
||||||
template < typename Type >
|
|
||||||
void set(const std::string & name, Type value)
|
|
||||||
{
|
|
||||||
OptionMap::iterator iter = find_option(name);
|
|
||||||
|
|
||||||
if (iter == _map.end())
|
|
||||||
throw Failure(STG(FMT("unknown option: %s") % name));
|
|
||||||
|
|
||||||
iter->second.set(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
std::string get(const Object * const object, const std::string & name)
|
|
||||||
{
|
|
||||||
OptionMap::iterator iter = find_option(name);
|
|
||||||
|
|
||||||
if (iter == _map.end())
|
|
||||||
throw Failure(STG(FMT("unknown option: %s") % name));
|
|
||||||
|
|
||||||
return iter->second.get(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void process(Object * const object, const char * name, const char * value)
|
|
||||||
{
|
|
||||||
OptionMap::iterator iter = find_option(name);
|
|
||||||
|
|
||||||
if (iter == _map.end())
|
|
||||||
throw Failure(STG(FMT("unknown option '%s'") % name));
|
|
||||||
|
|
||||||
iter->second.set(object, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
Messages commit(Object * const object, const std::string & name)
|
|
||||||
{
|
|
||||||
Messages msgs;
|
|
||||||
|
|
||||||
OptionMap::iterator i = _map.find(name);
|
|
||||||
|
|
||||||
if (i != _map.end())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
i->second.commit(object);
|
|
||||||
}
|
|
||||||
catch (Failure & e)
|
|
||||||
{
|
|
||||||
msgs.push_back(e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
msgs.push_back(STG(FMT("unable to find option: %s") % name));
|
|
||||||
};
|
|
||||||
|
|
||||||
return msgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
Messages commit(Object * const object)
|
|
||||||
{
|
|
||||||
Messages msgs;
|
|
||||||
|
|
||||||
for (OptionMap::iterator i = _map.begin(); i != _map.end(); ++i)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
i->second.commit(object);
|
|
||||||
}
|
|
||||||
catch (Failure & e)
|
|
||||||
{
|
|
||||||
msgs.push_back(e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return msgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void reset(Object * object)
|
|
||||||
{
|
|
||||||
for (OptionMap::iterator i = _map.begin(); i != _map.end(); ++i)
|
|
||||||
i->second.reset(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
bool loaded(Object * object, const std::string & name)
|
|
||||||
{
|
|
||||||
OptionMap::iterator iter = find_option(name);
|
|
||||||
|
|
||||||
if (iter == _map.end())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return iter->second.loaded(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool exists(const std::string & name)
|
|
||||||
{
|
|
||||||
OptionMap::iterator iter = find_option(name);
|
|
||||||
|
|
||||||
return (iter != _map.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
StringSet options(void);
|
|
||||||
|
|
||||||
const char ** values(const char *); /* option value */
|
|
||||||
const char ** values(void); /* values from options */
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void copyFrom(const std::string & name, const Object * const src_obj, Object * const dst_obj, bool force = false)
|
|
||||||
{
|
|
||||||
OptionMap::iterator iter = find_option(name);
|
|
||||||
|
|
||||||
if (iter == _map.end())
|
|
||||||
throw Failure(STG(FMT("unknown option '%s'") % name));
|
|
||||||
|
|
||||||
iter->second.copyFrom(src_obj, dst_obj, force);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
void copyFrom(Object * src_obj, Object * dst_obj, bool force = false)
|
|
||||||
{
|
|
||||||
for (OptionMap::iterator iter = _map.begin(); iter != _map.end(); ++iter)
|
|
||||||
iter->second.copyFrom(src_obj, dst_obj, force);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
OptionMap::iterator find_option(std::string);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
OptionMap _map;
|
|
||||||
SynOptionMap _syn_map;
|
|
||||||
|
|
||||||
const char ** _values;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _CONFIG_OPTIONS_HPP_ */
|
|
|
@ -1,240 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <configurator/configfile.hpp>
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
#undef close
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Configfile::ignore(const std::string & str)
|
|
||||||
{
|
|
||||||
_ignores.insert(str);
|
|
||||||
};
|
|
||||||
|
|
||||||
bool Configfile::select(Section **ptr, const std::string & str)
|
|
||||||
{
|
|
||||||
/* default section == this! */
|
|
||||||
*ptr = this;
|
|
||||||
|
|
||||||
/* always success by default */
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool Configfile::adjust(Section * section, const std::string & opt, const std::string & val)
|
|
||||||
{
|
|
||||||
return section->load(opt, val);
|
|
||||||
};
|
|
||||||
|
|
||||||
bool Configfile::deserialize(std::ifstream & fd)
|
|
||||||
{
|
|
||||||
Section * section = NULL;
|
|
||||||
|
|
||||||
/* default selection! */
|
|
||||||
if (!select(§ion))
|
|
||||||
{
|
|
||||||
_errors.push_back("default selection has failed!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t count = 0;
|
|
||||||
|
|
||||||
while (fd.good())
|
|
||||||
{
|
|
||||||
std::string str;
|
|
||||||
|
|
||||||
/* read one line! */
|
|
||||||
std::getline(fd, str);
|
|
||||||
|
|
||||||
size_t lst = str.size() - 1;
|
|
||||||
|
|
||||||
if (str.size() >= 1 && str[lst] == '\r') //cuida das quebras de linha do tipo \r\n
|
|
||||||
{
|
|
||||||
str.erase(lst,1);
|
|
||||||
--lst;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* empty line! */
|
|
||||||
if (str.size() == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* comment! */
|
|
||||||
if (str[0] == '#')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
++count;
|
|
||||||
|
|
||||||
if (str[0] == '[' && str[lst] == ']')
|
|
||||||
{
|
|
||||||
str.erase(0,1); --lst;
|
|
||||||
str.erase(lst,1); --lst;
|
|
||||||
|
|
||||||
if (!select(§ion, str))
|
|
||||||
{
|
|
||||||
_errors.push_back(STG(FMT("erroneous section '%s'") % str));
|
|
||||||
|
|
||||||
/* ignore this section */
|
|
||||||
section = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string::size_type pos = str.find('=');
|
|
||||||
|
|
||||||
if (pos == std::string::npos)
|
|
||||||
{
|
|
||||||
_errors.push_back(STG(FMT("erroneous separator '%s'") % str));
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (section == NULL)
|
|
||||||
{
|
|
||||||
_errors.push_back(STG(FMT("no section for option '%s'") % str));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string opt(str.substr(0,pos));
|
|
||||||
std::string val(str.substr(pos+1));
|
|
||||||
|
|
||||||
if (_ignores.find(opt) != _ignores.end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (val == "@") val = "";
|
|
||||||
|
|
||||||
if (adjust(section, opt, val))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
_errors.push_back(STG(FMT("option '%s' does not exist or '%s' is not "
|
|
||||||
"a valid value (at section '%s')") % opt % val % section->name()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// retorna 'true' se arquivo tinha alguma coisa valida.
|
|
||||||
return (count != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Configfile::obtain()
|
|
||||||
{
|
|
||||||
std::ifstream fd(_filename.c_str());
|
|
||||||
|
|
||||||
if (!fd.is_open())
|
|
||||||
{
|
|
||||||
_errors.push_back(STG(FMT("unable to open file '%s': %s")
|
|
||||||
% _filename % strerror(errno)));
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!deserialize(fd))
|
|
||||||
{
|
|
||||||
fd.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd.close();
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
void Configfile::recurse(std::ofstream & fd, Section * section)
|
|
||||||
{
|
|
||||||
typedef Section::SectionMap::const_iterator SectionIter;
|
|
||||||
typedef Section::OptionMap::const_iterator OptionIter;
|
|
||||||
|
|
||||||
for (OptionIter i = section->option_begin(); i != section->option_end(); i++)
|
|
||||||
{
|
|
||||||
std::string res;
|
|
||||||
|
|
||||||
if ((*i).second.store(res))
|
|
||||||
{
|
|
||||||
if (res == "") res = "@";
|
|
||||||
fd << (*i).first << "=" << res << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!section->recursive())
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (SectionIter j = section->section_begin(); j != section->section_end(); j++)
|
|
||||||
recurse(fd, (*j).second);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Configfile::serialize(std::ofstream & fd)
|
|
||||||
{
|
|
||||||
recurse(fd, this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Configfile::provide()
|
|
||||||
{
|
|
||||||
std::string tmp(_filename);
|
|
||||||
tmp += ".new";
|
|
||||||
|
|
||||||
std::ofstream fd(tmp.c_str());
|
|
||||||
|
|
||||||
if (!fd.good())
|
|
||||||
{
|
|
||||||
_errors.push_back(STG(FMT("unable to open file '%s': %s")
|
|
||||||
% tmp % strerror(errno)));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!serialize(fd))
|
|
||||||
{
|
|
||||||
fd.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd.close();
|
|
||||||
|
|
||||||
if (rename(tmp.c_str(), _filename.c_str()) != 0)
|
|
||||||
{
|
|
||||||
_errors.push_back(STG(FMT("unable to replace config file '%s': %s")
|
|
||||||
% _filename % strerror(errno)));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
#define close _close
|
|
||||||
#endif
|
|
|
@ -1,90 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
#include <format.hpp>
|
|
||||||
|
|
||||||
#include <configurator/section.hpp>
|
|
||||||
|
|
||||||
#ifndef _CONFIG_CONFIGFILE_HPP_
|
|
||||||
#define _CONFIG_CONFIGFILE_HPP_
|
|
||||||
|
|
||||||
struct Configfile: public Section
|
|
||||||
{
|
|
||||||
typedef std::list < std::string > ErrorVector;
|
|
||||||
typedef std::set < std::string > NameSet;
|
|
||||||
|
|
||||||
Configfile(const std::string & name, const std::string & desc)
|
|
||||||
: Section(name, desc), _good(false) {};
|
|
||||||
|
|
||||||
virtual ~Configfile() {};
|
|
||||||
|
|
||||||
bool good() const { return _good; };
|
|
||||||
const std::string & filename() const { return _filename; };
|
|
||||||
|
|
||||||
const ErrorVector & errors() const { return _errors; };
|
|
||||||
|
|
||||||
void ignore(const std::string &);
|
|
||||||
|
|
||||||
virtual bool obtain();
|
|
||||||
virtual bool provide();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual bool select(Section **, const std::string & str = "");
|
|
||||||
virtual bool adjust(Section *, const std::string & opt, const std::string & val);
|
|
||||||
|
|
||||||
virtual bool deserialize(std::ifstream &);
|
|
||||||
virtual bool serialize(std::ofstream &);
|
|
||||||
|
|
||||||
void recurse(std::ofstream &, Section *);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool _good;
|
|
||||||
ErrorVector _errors;
|
|
||||||
NameSet _ignores;
|
|
||||||
std::string _filename;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _CONFIG_CONFIGFILE_HPP_ */
|
|
|
@ -1,186 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <configurator/option.hpp>
|
|
||||||
|
|
||||||
bool Option::equals(const std::string & value) const
|
|
||||||
{
|
|
||||||
switch (_restriction.numeral())
|
|
||||||
{
|
|
||||||
case Restriction::N_UNIQUE:
|
|
||||||
{
|
|
||||||
Restriction::Value my_value;
|
|
||||||
|
|
||||||
if (!_restriction.get(Restriction::F_USER, my_value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return (my_value == value);
|
|
||||||
}
|
|
||||||
case Restriction::N_MULTIPLE:
|
|
||||||
{
|
|
||||||
Restriction::Vector my_values;
|
|
||||||
|
|
||||||
if (!_restriction.get(Restriction::F_USER, my_values))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (Restriction::Vector::iterator i = my_values.begin(); i != my_values.end(); i++)
|
|
||||||
{
|
|
||||||
if ((*i) == value)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Option::load(const std::string & value)
|
|
||||||
{
|
|
||||||
bool ret = _restriction.set( (const Restriction::Format)Restriction::F_FILE, value);
|
|
||||||
|
|
||||||
if (ret) _modified = false;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Option::change(const std::string & value)
|
|
||||||
{
|
|
||||||
bool ret = _restriction.set(Restriction::F_FILE, value);
|
|
||||||
|
|
||||||
if (ret) _modified = true;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Option::store(std::string & value) const
|
|
||||||
{
|
|
||||||
switch (_restriction.numeral())
|
|
||||||
{
|
|
||||||
case Restriction::N_UNIQUE:
|
|
||||||
return _restriction.get(Restriction::F_FILE, value);
|
|
||||||
|
|
||||||
case Restriction::N_MULTIPLE:
|
|
||||||
{
|
|
||||||
Restriction::Vector values;
|
|
||||||
|
|
||||||
if (!_restriction.get(Restriction::F_FILE, values))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Strings::Merger strs;
|
|
||||||
|
|
||||||
for (Restriction::Vector::iterator i = values.begin(); i != values.end(); i++)
|
|
||||||
strs.add(*i);
|
|
||||||
|
|
||||||
value = strs.merge(",");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Option::Flags Option::set(const char * value)
|
|
||||||
{
|
|
||||||
std::string str_value(value);
|
|
||||||
return set(str_value);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Option::Flags Option::set(const Restriction::Value & value)
|
|
||||||
{
|
|
||||||
Restriction::Value last_value, curr_value;
|
|
||||||
Flags flags;
|
|
||||||
|
|
||||||
bool ret1 = _restriction.get(Restriction::F_USER, last_value);
|
|
||||||
|
|
||||||
if (!_restriction.set(Restriction::F_USER, value))
|
|
||||||
return flags;
|
|
||||||
|
|
||||||
flags[F_ADJUSTED] = true;
|
|
||||||
|
|
||||||
bool ret2 = _restriction.get(Restriction::F_USER, curr_value);
|
|
||||||
|
|
||||||
if (!ret1 || (ret2 && (last_value != curr_value)))
|
|
||||||
{
|
|
||||||
flags[F_MODIFIED] = true;
|
|
||||||
_modified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
Option::Flags Option::set(const Restriction::Vector & values)
|
|
||||||
{
|
|
||||||
Restriction::Vector last_values, curr_values;
|
|
||||||
Flags flags;
|
|
||||||
|
|
||||||
bool ret1 = _restriction.get(Restriction::F_USER, last_values);
|
|
||||||
|
|
||||||
if (!_restriction.set(Restriction::F_USER, values))
|
|
||||||
return flags;
|
|
||||||
|
|
||||||
flags[F_ADJUSTED] = true;
|
|
||||||
|
|
||||||
bool ret2 = _restriction.get(Restriction::F_USER, curr_values);
|
|
||||||
|
|
||||||
if (!ret1 || (ret2 && (last_values != curr_values)))
|
|
||||||
{
|
|
||||||
flags[F_MODIFIED] = true;
|
|
||||||
_modified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Option::get(Restriction::Value & value) const
|
|
||||||
{
|
|
||||||
return _restriction.get(Restriction::F_USER, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Option::get(Restriction::Vector & values) const
|
|
||||||
{
|
|
||||||
return _restriction.get(Restriction::F_USER, values);
|
|
||||||
}
|
|
|
@ -1,128 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <list>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <format.hpp>
|
|
||||||
#include <strings.hpp>
|
|
||||||
|
|
||||||
#include <configurator/restriction.hpp>
|
|
||||||
|
|
||||||
#ifndef _CONFIG_OPTION_HPP_
|
|
||||||
#define _CONFIG_OPTION_HPP_
|
|
||||||
|
|
||||||
struct Option
|
|
||||||
{
|
|
||||||
enum FlagTypes
|
|
||||||
{
|
|
||||||
F_MODIFIED = 0x0, /* if option was modified */
|
|
||||||
F_ADJUSTED = 0x1, /* if option was correctly formated */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Flags: public std::vector<bool>
|
|
||||||
{
|
|
||||||
Flags(): std::vector<bool>(2) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef Restriction::Value Value;
|
|
||||||
typedef Restriction::Vector Vector;
|
|
||||||
|
|
||||||
/* exception */
|
|
||||||
struct InvalidDefaultValue: public std::runtime_error
|
|
||||||
{
|
|
||||||
InvalidDefaultValue(const std::string & name, const std::string & value)
|
|
||||||
: std::runtime_error(STG(FMT("invalid default value '%s' for option '%s'") % value % name)),
|
|
||||||
_name(name), _value(value)
|
|
||||||
{};
|
|
||||||
|
|
||||||
~InvalidDefaultValue() throw ()
|
|
||||||
{};
|
|
||||||
|
|
||||||
const std::string & name() const { return _name; };
|
|
||||||
const std::string & value() const { return _value; };
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const std::string _name;
|
|
||||||
const std::string _value;
|
|
||||||
};
|
|
||||||
|
|
||||||
Option(const std::string & name, const std::string & desc, const std::string & defvalue, const Restriction & restriction)
|
|
||||||
: _name(name), _description(desc), _restriction(restriction), _modified(true)
|
|
||||||
{
|
|
||||||
// std::string value(defvalue);
|
|
||||||
|
|
||||||
if (!(set(defvalue)[F_ADJUSTED]))
|
|
||||||
throw InvalidDefaultValue(name, defvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string & name() const { return _name; };
|
|
||||||
const std::string & description() const { return _description; };
|
|
||||||
|
|
||||||
const Restriction & restriction() const { return _restriction; };
|
|
||||||
bool modified() const { return _modified; };
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool load(const std::string &);
|
|
||||||
bool change(const std::string &);
|
|
||||||
bool store(std::string &) const;
|
|
||||||
|
|
||||||
// Flags set(const char *);
|
|
||||||
Flags set(const Value &);
|
|
||||||
Flags set(const Vector &);
|
|
||||||
|
|
||||||
bool get(Value &) const;
|
|
||||||
bool get(Vector &) const;
|
|
||||||
|
|
||||||
bool equals(const std::string &) const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const std::string _name;
|
|
||||||
const std::string _description;
|
|
||||||
|
|
||||||
Restriction _restriction;
|
|
||||||
bool _modified;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _CONFIG_OPTION_HPP_ */
|
|
|
@ -1,358 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <strings.hpp>
|
|
||||||
|
|
||||||
#include <configurator/restriction.hpp>
|
|
||||||
|
|
||||||
/* internal helper! */
|
|
||||||
bool Restriction::equalNumber(const double a, const double b)
|
|
||||||
{
|
|
||||||
char tmp1[64];
|
|
||||||
char tmp2[64];
|
|
||||||
|
|
||||||
snprintf(tmp1, sizeof(tmp1), "%.3f", a);
|
|
||||||
snprintf(tmp2, sizeof(tmp2), "%.3f", b);
|
|
||||||
|
|
||||||
if (strncmp(tmp1, tmp2, sizeof(tmp1)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* process value to our internal representation */
|
|
||||||
|
|
||||||
bool Restriction::process(Restriction::Format fmt,
|
|
||||||
const Restriction::Value & value, Restriction::Value & final) const
|
|
||||||
{
|
|
||||||
switch (_bounds)
|
|
||||||
{
|
|
||||||
case B_RANGE:
|
|
||||||
{
|
|
||||||
if (_kind != K_NUMBER)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::string tmpvalue;
|
|
||||||
|
|
||||||
Restriction::Value::const_iterator itr = value.begin();
|
|
||||||
Restriction::Value::const_iterator end = value.end();
|
|
||||||
|
|
||||||
tmpvalue.reserve(value.size());
|
|
||||||
|
|
||||||
// f*cking dot/comma notation!
|
|
||||||
for (; itr != end; ++itr)
|
|
||||||
tmpvalue += ((*itr) != ',' ? (*itr) : '.');
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
double newvalue = Strings::todouble(tmpvalue);
|
|
||||||
|
|
||||||
if (newvalue < _init && newvalue > _fini)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
double res = (newvalue - _init) / _step;
|
|
||||||
|
|
||||||
if (!Restriction::equalNumber(res, rint(res)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
final = value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case B_LIST:
|
|
||||||
for (List::const_iterator i = _list.begin(); i != _list.end(); i++)
|
|
||||||
{
|
|
||||||
const Value & tmp = (*i);
|
|
||||||
|
|
||||||
if (tmp == value)
|
|
||||||
{
|
|
||||||
final = value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case B_MAPS:
|
|
||||||
switch (fmt)
|
|
||||||
{
|
|
||||||
case F_USER:
|
|
||||||
{
|
|
||||||
Map::const_iterator i = _map_from_usr.find(value);
|
|
||||||
|
|
||||||
if (i == _map_from_usr.end())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const Value & tmp = (*i).second;
|
|
||||||
|
|
||||||
final = tmp;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case F_FILE:
|
|
||||||
{
|
|
||||||
Map::const_iterator i = _map_from_cfg.find(value);
|
|
||||||
|
|
||||||
if (i == _map_from_cfg.end())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
final = value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case B_FREE:
|
|
||||||
final = value;
|
|
||||||
return true;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unprocess the value (outputs the external representation) */
|
|
||||||
|
|
||||||
bool Restriction::unprocess(Restriction::Format fmt,
|
|
||||||
const Restriction::Value & value, Restriction::Value & final) const
|
|
||||||
{
|
|
||||||
switch (_bounds)
|
|
||||||
{
|
|
||||||
case B_MAPS:
|
|
||||||
|
|
||||||
switch (fmt)
|
|
||||||
{
|
|
||||||
case F_USER:
|
|
||||||
{
|
|
||||||
Map::const_iterator i = _map_from_cfg.find(value);
|
|
||||||
|
|
||||||
if (i == _map_from_cfg.end())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
final = (*i).second;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
final = value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************** *****************************/
|
|
||||||
|
|
||||||
bool Restriction::get(Restriction::Format fmt, Restriction::Value & value) const
|
|
||||||
{
|
|
||||||
if (_numeral != N_UNIQUE)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!unprocess(fmt, _value._unique, value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Restriction::get(Restriction::Format fmt, Restriction::Vector & values) const
|
|
||||||
{
|
|
||||||
if (_numeral != N_MULTIPLE)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const List & my_values = _value._multiple;
|
|
||||||
|
|
||||||
for (List::const_iterator i = my_values.begin(); i != my_values.end(); i++)
|
|
||||||
{
|
|
||||||
const Value & value = (*i);
|
|
||||||
|
|
||||||
Value final;
|
|
||||||
|
|
||||||
if (!unprocess(fmt, value, final))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
values.push_back(final);
|
|
||||||
};
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************** *****************************/
|
|
||||||
|
|
||||||
bool Restriction::set(Restriction::Format fmt, const Restriction::Value & value)
|
|
||||||
{
|
|
||||||
switch (_numeral)
|
|
||||||
{
|
|
||||||
case N_UNIQUE:
|
|
||||||
{
|
|
||||||
Value final;
|
|
||||||
|
|
||||||
if (!constThis().process(fmt, value, final))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_value._unique = final;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case N_MULTIPLE:
|
|
||||||
{
|
|
||||||
if (value == "@" || value == "#" || value == "")
|
|
||||||
{
|
|
||||||
_value._multiple.clear();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Strings::vector_type values;
|
|
||||||
Strings::tokenize(value, values, ",");
|
|
||||||
|
|
||||||
return set(fmt, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Restriction::set(Restriction::Format fmt, const Restriction::Vector & values)
|
|
||||||
{
|
|
||||||
if (_numeral != N_MULTIPLE)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (values.empty())
|
|
||||||
{
|
|
||||||
_value._multiple.clear();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* list needed to store temporary values */
|
|
||||||
List finals;
|
|
||||||
|
|
||||||
for (Vector::const_iterator i = values.begin(); i != values.end(); i++)
|
|
||||||
{
|
|
||||||
const Value & value = (*i);
|
|
||||||
|
|
||||||
Value final;
|
|
||||||
|
|
||||||
if (!constThis().process(fmt, value, final))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
finals.push_back(final);
|
|
||||||
}
|
|
||||||
|
|
||||||
List & lst = _value._multiple;
|
|
||||||
|
|
||||||
/* need to clear values set before */
|
|
||||||
lst.clear();
|
|
||||||
|
|
||||||
for (List::iterator i = finals.begin(); i != finals.end(); i++)
|
|
||||||
{
|
|
||||||
Value value = (*i);
|
|
||||||
lst.push_back(value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************** *****************************/
|
|
||||||
|
|
||||||
void Restriction::allowed(Restriction::Vector & vals) const
|
|
||||||
{
|
|
||||||
switch (_bounds)
|
|
||||||
{
|
|
||||||
case B_FREE:
|
|
||||||
return;
|
|
||||||
|
|
||||||
case B_LIST:
|
|
||||||
for (List::const_iterator i = _list.begin(); i != _list.end(); i++)
|
|
||||||
vals.push_back(*i);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_MAPS:
|
|
||||||
for (Map::const_iterator i = _map_from_usr.begin(); i != _map_from_usr.end(); i++)
|
|
||||||
vals.push_back(i->first);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_RANGE:
|
|
||||||
{
|
|
||||||
if (_kind != K_NUMBER)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// is there any fraction?
|
|
||||||
bool has_fraction =
|
|
||||||
(!Restriction::equalNumber(_init, rint(_init))) ||
|
|
||||||
(!Restriction::equalNumber(_fini, rint(_fini))) ||
|
|
||||||
(!Restriction::equalNumber(_step, rint(_step)));
|
|
||||||
|
|
||||||
const char * format = (has_fraction ? "%.2f" : "%02.0f");
|
|
||||||
|
|
||||||
for (double i = _init; i <= _fini; i += _step)
|
|
||||||
{
|
|
||||||
char tmp[32];
|
|
||||||
snprintf(tmp, sizeof(tmp), format, i);
|
|
||||||
vals.push_back(std::string(tmp));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Restriction::init_class()
|
|
||||||
{
|
|
||||||
_value._unique.clear();
|
|
||||||
_value._multiple.clear();
|
|
||||||
}
|
|
|
@ -1,269 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <list>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include <const_this.hpp>
|
|
||||||
|
|
||||||
#ifndef _CONFIG_RESTRICTION_HPP_
|
|
||||||
#define _CONFIG_RESTRICTION_HPP_
|
|
||||||
|
|
||||||
struct Restriction: public ConstThis < Restriction >
|
|
||||||
{
|
|
||||||
/* generic types */
|
|
||||||
|
|
||||||
// TODO: change this type name for something different
|
|
||||||
// to avoid conflicting with "format.hpp".
|
|
||||||
enum Format
|
|
||||||
{
|
|
||||||
F_USER,
|
|
||||||
F_FILE
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Kind
|
|
||||||
{
|
|
||||||
K_STRING,
|
|
||||||
K_NUMBER // = K_INTEGER // compatibility
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Bounds
|
|
||||||
{
|
|
||||||
B_FREE,
|
|
||||||
B_RANGE,
|
|
||||||
B_LIST,
|
|
||||||
B_MAPS
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Numeral
|
|
||||||
{
|
|
||||||
N_UNIQUE,
|
|
||||||
N_MULTIPLE
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::string Value;
|
|
||||||
|
|
||||||
/* types used for data input */
|
|
||||||
struct Pair
|
|
||||||
{
|
|
||||||
const char *pretty;
|
|
||||||
const char *value;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::pair < Value, Value > PairMap;
|
|
||||||
typedef std::list < PairMap > ListMap;
|
|
||||||
|
|
||||||
/* types used internally */
|
|
||||||
typedef std::map < Value, Value > Map;
|
|
||||||
typedef std::vector < Value > Vector;
|
|
||||||
|
|
||||||
typedef std::list < Value > List;
|
|
||||||
typedef std::pair < Value, Value > MapPair;
|
|
||||||
|
|
||||||
struct Generic
|
|
||||||
{
|
|
||||||
Value _unique;
|
|
||||||
List _multiple;
|
|
||||||
};
|
|
||||||
|
|
||||||
Restriction(Kind kind, Numeral num)
|
|
||||||
: _kind(kind), _bounds(B_FREE), _numeral(num), _unit(""),
|
|
||||||
_init(-1), _fini(-1), _step(-1)
|
|
||||||
{
|
|
||||||
init_class();
|
|
||||||
}
|
|
||||||
|
|
||||||
Restriction(Kind kind, Numeral num,
|
|
||||||
double init, double fini, double step = 1)
|
|
||||||
: _kind(kind), _bounds(B_RANGE), _numeral(num), _unit(""),
|
|
||||||
_init(init), _fini(fini), _step(step)
|
|
||||||
{
|
|
||||||
init_class();
|
|
||||||
}
|
|
||||||
|
|
||||||
Restriction(Kind kind, Numeral num,
|
|
||||||
const char *unit, double init, double fini, double step = 1.0)
|
|
||||||
: _kind(kind), _bounds(B_RANGE), _numeral(num), _unit(unit),
|
|
||||||
_init(init), _fini(fini), _step(step)
|
|
||||||
{
|
|
||||||
init_class();
|
|
||||||
}
|
|
||||||
|
|
||||||
Restriction(Kind kind, Numeral num,
|
|
||||||
std::string unit, double init, double fini, double step = 1.0)
|
|
||||||
: _kind(kind), _bounds(B_RANGE), _numeral(num), _unit(unit),
|
|
||||||
_init(init), _fini(fini), _step(step)
|
|
||||||
{
|
|
||||||
init_class();
|
|
||||||
}
|
|
||||||
|
|
||||||
Restriction(Kind kind, Numeral num,
|
|
||||||
const char *first, ...)
|
|
||||||
: _kind(kind), _bounds(B_LIST), _numeral(num), _unit(""),
|
|
||||||
_init(-1), _fini(-1), _step(-1)
|
|
||||||
{
|
|
||||||
_list.push_back(std::string(first));
|
|
||||||
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, first);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
const char *arg = va_arg(ap, const char *);
|
|
||||||
|
|
||||||
if (arg == NULL) break;
|
|
||||||
|
|
||||||
_list.push_back(std::string(arg));
|
|
||||||
}
|
|
||||||
|
|
||||||
init_class();
|
|
||||||
}
|
|
||||||
|
|
||||||
Restriction(Kind kind, const char *unit, Numeral num,
|
|
||||||
const char *first, ...)
|
|
||||||
: _kind(kind), _bounds(B_LIST), _numeral(num), _unit(unit),
|
|
||||||
_init(-1), _fini(-1), _step(-1)
|
|
||||||
{
|
|
||||||
_list.push_back(std::string(first));
|
|
||||||
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, first);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
const char *arg = va_arg(ap, const char *);
|
|
||||||
|
|
||||||
if (arg == NULL) break;
|
|
||||||
|
|
||||||
_list.push_back(std::string(arg));
|
|
||||||
}
|
|
||||||
|
|
||||||
init_class();
|
|
||||||
}
|
|
||||||
|
|
||||||
Restriction(Kind kind, Numeral num,
|
|
||||||
const struct Pair first, ...)
|
|
||||||
: _kind(kind), _bounds(B_MAPS), _numeral(num), _unit(""),
|
|
||||||
_init(-1), _fini(-1), _step(-1)
|
|
||||||
{
|
|
||||||
_map_from_usr.insert(MapPair(Value(first.pretty), Value(first.value)));
|
|
||||||
_map_from_cfg.insert(MapPair(Value(first.value), Value(first.pretty)));
|
|
||||||
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, first);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
Pair arg = va_arg(ap, Pair);
|
|
||||||
|
|
||||||
if (arg.pretty == NULL) break;
|
|
||||||
|
|
||||||
_map_from_usr.insert(MapPair(Value(arg.pretty), Value(arg.value)));
|
|
||||||
_map_from_cfg.insert(MapPair(Value(arg.value), Value(arg.pretty)));
|
|
||||||
}
|
|
||||||
|
|
||||||
init_class();
|
|
||||||
}
|
|
||||||
|
|
||||||
Restriction(Kind kind, Numeral num, List list)
|
|
||||||
: _kind(kind), _bounds(B_LIST), _numeral(num), _unit(""),
|
|
||||||
_init(-1), _fini(-1), _step(-1), _list(list)
|
|
||||||
{
|
|
||||||
init_class();
|
|
||||||
}
|
|
||||||
|
|
||||||
Restriction(Kind kind, Numeral num, ListMap map)
|
|
||||||
: _kind(kind), _bounds(B_MAPS), _numeral(num), _unit(""),
|
|
||||||
_init(-1), _fini(-1), _step(-1)
|
|
||||||
{
|
|
||||||
for (ListMap::iterator i = map.begin(); i != map.end(); i++)
|
|
||||||
{
|
|
||||||
_map_from_usr.insert(MapPair(Value((*i).first), Value((*i).second)));
|
|
||||||
_map_from_cfg.insert(MapPair(Value((*i).second), Value((*i).first)));
|
|
||||||
}
|
|
||||||
|
|
||||||
init_class();
|
|
||||||
}
|
|
||||||
|
|
||||||
const Kind kind() const { return _kind; };
|
|
||||||
const Bounds bounds() const { return _bounds; };
|
|
||||||
const Numeral numeral() const { return _numeral; };
|
|
||||||
|
|
||||||
const std::string & unit() const { return _unit; };
|
|
||||||
|
|
||||||
bool set(Format, const Vector &);
|
|
||||||
bool set(Format, const Value &);
|
|
||||||
|
|
||||||
bool get(Format, Vector &) const;
|
|
||||||
bool get(Format, Value &) const;
|
|
||||||
|
|
||||||
void allowed(Vector &) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool process(const Format, const Value &, Value &) const;
|
|
||||||
bool unprocess(const Format, const Value &, Value &) const;
|
|
||||||
|
|
||||||
void init_class();
|
|
||||||
|
|
||||||
static bool equalNumber(const double, const double);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const Kind _kind;
|
|
||||||
const Bounds _bounds;
|
|
||||||
const Numeral _numeral;
|
|
||||||
|
|
||||||
Value _unit;
|
|
||||||
|
|
||||||
const double _init, _fini, _step;
|
|
||||||
|
|
||||||
Map _map_from_usr,
|
|
||||||
_map_from_cfg;
|
|
||||||
|
|
||||||
List _list;
|
|
||||||
|
|
||||||
Generic _value;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _CONFIG_RESTRICTION_HPP_ */
|
|
|
@ -1,136 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <configurator/section.hpp>
|
|
||||||
|
|
||||||
void Section::options(Section::OptionVector & vec) const
|
|
||||||
{
|
|
||||||
for (OptionMap::const_iterator it = _options.begin(); it != _options.end();)
|
|
||||||
{
|
|
||||||
vec.push_back(const_cast< Option * >(&(it->second)));
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Section::sections(Section::SectionVector & vec) const
|
|
||||||
{
|
|
||||||
for (SectionMap::const_iterator it = _sections.begin(); it != _sections.end();)
|
|
||||||
{
|
|
||||||
vec.push_back(const_cast< Section * >(it->second));
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********/
|
|
||||||
|
|
||||||
Option * Section::option_find(const std::string & str, bool recurse) const
|
|
||||||
{
|
|
||||||
OptionMap::const_iterator i = _options.find(str);
|
|
||||||
|
|
||||||
if (i == _options.end())
|
|
||||||
{
|
|
||||||
if (!recurse)
|
|
||||||
throw OptionNotFound(str, _name);
|
|
||||||
// throw not_found();
|
|
||||||
|
|
||||||
for (SectionMap::const_iterator i = _sections.begin(); i != _sections.end(); i++)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return i->second->option_find(str, recurse);
|
|
||||||
}
|
|
||||||
catch (NotFound & e)
|
|
||||||
{
|
|
||||||
/* keep looping! */
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// throw not_found();
|
|
||||||
throw OptionNotFound(str, _name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return const_cast< Option * >(&(i->second));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Option * Section::option_find(const char * str, bool recurse)
|
|
||||||
{
|
|
||||||
std::string sstr(str);
|
|
||||||
return option_find(sstr, recurse);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********/
|
|
||||||
|
|
||||||
Section * Section::section_find(const std::string & str, bool recurse) const
|
|
||||||
{
|
|
||||||
SectionMap::const_iterator i = _sections.find(str);
|
|
||||||
|
|
||||||
if (i == _sections.end())
|
|
||||||
{
|
|
||||||
if (!recurse)
|
|
||||||
throw SectionNotFound(str, _name);
|
|
||||||
|
|
||||||
for (SectionMap::const_iterator i = _sections.begin(); i != _sections.end(); i++)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return i->second->section_find(str, recurse);
|
|
||||||
}
|
|
||||||
catch (NotFound & e)
|
|
||||||
{
|
|
||||||
/* keep looping! */
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
throw SectionNotFound(str, _name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return const_cast< Section * >(i->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Section * Section::section_find(const char * str, bool recurse)
|
|
||||||
{
|
|
||||||
std::string sstr(str);
|
|
||||||
return section_find(sstr, recurse);
|
|
||||||
}
|
|
||||||
*/
|
|
|
@ -1,260 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CONFIG_SECTION_HPP_
|
|
||||||
#define _CONFIG_SECTION_HPP_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <format.hpp>
|
|
||||||
|
|
||||||
#include <configurator/option.hpp>
|
|
||||||
|
|
||||||
struct Section
|
|
||||||
{
|
|
||||||
typedef std::map < std::string, Option > OptionMap;
|
|
||||||
typedef std::vector< Option * > OptionVector;
|
|
||||||
|
|
||||||
typedef std::map < std::string, Section * > SectionMap;
|
|
||||||
typedef std::vector < Section * > SectionVector;
|
|
||||||
|
|
||||||
struct NotFound: public std::runtime_error
|
|
||||||
{
|
|
||||||
NotFound(const std::string & type, const std::string & name, const std::string & me)
|
|
||||||
: std::runtime_error(STG(FMT("%s '%s' not found on section '%s'") % type % name % me)) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OptionNotFound: public NotFound
|
|
||||||
{
|
|
||||||
OptionNotFound(const std::string & name, const std::string & me)
|
|
||||||
: NotFound("option", name, me) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SectionNotFound: public NotFound
|
|
||||||
{
|
|
||||||
SectionNotFound(const std::string & name, const std::string & me)
|
|
||||||
: NotFound("section", name, me) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef NotFound not_found; /* backward compatibility */
|
|
||||||
|
|
||||||
// protected:
|
|
||||||
Section(const std::string & name, const std::string & desc, bool recursive = true)
|
|
||||||
: _name(name), _description(desc), _recursive(recursive) {};
|
|
||||||
|
|
||||||
void add(const Option & o)
|
|
||||||
{
|
|
||||||
_options.insert(std::pair<std::string,Option>(o.name(), o));
|
|
||||||
};
|
|
||||||
|
|
||||||
void del(const std::string & name)
|
|
||||||
{
|
|
||||||
_options.erase(name);
|
|
||||||
};
|
|
||||||
|
|
||||||
void add(Section * s)
|
|
||||||
{
|
|
||||||
_sections.insert(std::pair< std::string, Section * >(s->name(), s));
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
const std::string & name() const { return _name; };
|
|
||||||
const std::string & description() const { return _description; };
|
|
||||||
|
|
||||||
const bool recursive() const { return _recursive; };
|
|
||||||
|
|
||||||
OptionMap::const_iterator option_begin() const { return _options.begin(); };
|
|
||||||
OptionMap::const_iterator option_end() const { return _options.end(); };
|
|
||||||
|
|
||||||
SectionMap::const_iterator section_begin() const { return _sections.begin(); };
|
|
||||||
SectionMap::const_iterator section_end() const { return _sections.end(); };
|
|
||||||
|
|
||||||
/**/
|
|
||||||
|
|
||||||
// Option * option_find(const char *, bool recurse = false) const;
|
|
||||||
// Section * section_find(const char *, bool recurse = false) const;
|
|
||||||
|
|
||||||
Option * option_find(const std::string &, bool recurse = false) const;
|
|
||||||
Section * section_find(const std::string &, bool recurse = false) const;
|
|
||||||
|
|
||||||
/**/
|
|
||||||
|
|
||||||
void options(OptionVector &) const;
|
|
||||||
void sections(SectionVector &) const;
|
|
||||||
|
|
||||||
/**/
|
|
||||||
|
|
||||||
template < typename T, typename F >
|
|
||||||
bool search_and_apply(const std::string & key, T & value, F f)
|
|
||||||
{
|
|
||||||
OptionMap::iterator i = _options.find(key);
|
|
||||||
|
|
||||||
if (i != _options.end())
|
|
||||||
return f(i->second);
|
|
||||||
|
|
||||||
if (!_recursive)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return (find_if(_sections.begin(), _sections.end(), f) != _sections.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct ConstKeyValue
|
|
||||||
{
|
|
||||||
ConstKeyValue(const std::string & k, const std::string &v)
|
|
||||||
: _k(k), _v(v) {};
|
|
||||||
|
|
||||||
const std::string & _k;
|
|
||||||
const std::string & _v;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct KeyValue
|
|
||||||
{
|
|
||||||
KeyValue(const std::string & k, std::string &v)
|
|
||||||
: _k(k), _v(v) {};
|
|
||||||
|
|
||||||
const std::string & _k;
|
|
||||||
std::string & _v;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct load_section: protected ConstKeyValue
|
|
||||||
{
|
|
||||||
load_section(const std::string & k, const std::string & v): ConstKeyValue(k,v) {};
|
|
||||||
|
|
||||||
bool operator()(Option & o) { return o.load(_v); };
|
|
||||||
bool operator()(SectionMap::value_type & v) { return v.second->load(_k,_v); };
|
|
||||||
};
|
|
||||||
|
|
||||||
struct change_section: protected ConstKeyValue
|
|
||||||
{
|
|
||||||
change_section(const std::string & k, const std::string & v): ConstKeyValue(k,v) {};
|
|
||||||
|
|
||||||
bool operator()(Option & o) { return o.change(_v); };
|
|
||||||
bool operator()(SectionMap::value_type & v) { return v.second->change(_k,_v); };
|
|
||||||
};
|
|
||||||
|
|
||||||
struct store_section: protected KeyValue
|
|
||||||
{
|
|
||||||
store_section(const std::string & k, std::string & v): KeyValue(k,v) {};
|
|
||||||
|
|
||||||
bool operator()(Option & o) { return o.store(_v); };
|
|
||||||
bool operator()(SectionMap::value_type & v) { return v.second->store(_k,_v); };
|
|
||||||
};
|
|
||||||
|
|
||||||
struct set_section: protected ConstKeyValue
|
|
||||||
{
|
|
||||||
set_section(const std::string & k, const std::string & v): ConstKeyValue(k,v) {};
|
|
||||||
|
|
||||||
bool operator()(Option & o) { return (o.set(_v))[Option::F_ADJUSTED]; };
|
|
||||||
bool operator()(SectionMap::value_type & v) { return v.second->set(_k,_v); };
|
|
||||||
};
|
|
||||||
|
|
||||||
struct get_section: protected KeyValue
|
|
||||||
{
|
|
||||||
get_section(const std::string & k, std::string & v): KeyValue(k,v) {};
|
|
||||||
|
|
||||||
bool operator()(Option & o) { return o.get(_v); };
|
|
||||||
bool operator()(SectionMap::value_type & v) { return v.second->get(_k,_v); };
|
|
||||||
};
|
|
||||||
|
|
||||||
struct modified_section
|
|
||||||
{
|
|
||||||
bool operator()(const OptionMap::value_type & v) { return v.second.modified(); };
|
|
||||||
bool operator()(const SectionMap::value_type & v) { return v.second->modified(); };
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
/*
|
|
||||||
bool load(const char * key, const std::string value)
|
|
||||||
{
|
|
||||||
std::string skey(key);
|
|
||||||
return search_and_apply(skey, value, load_section(skey, value));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
bool load(const std::string & key, const std::string & value)
|
|
||||||
{
|
|
||||||
return search_and_apply(key, value, load_section(key, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool change(const std::string & key, const std::string & value)
|
|
||||||
{
|
|
||||||
return search_and_apply(key, value, change_section(key, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool store(const std::string & key, std::string & value)
|
|
||||||
{
|
|
||||||
return search_and_apply(key, value, store_section(key, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool set(const std::string & key, const std::string & value)
|
|
||||||
{
|
|
||||||
return search_and_apply(key, value, set_section(key, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get(const std::string & key, std::string & value)
|
|
||||||
{
|
|
||||||
return search_and_apply(key, value, get_section(key, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool modified() const
|
|
||||||
{
|
|
||||||
return ((find_if(_options.begin(), _options.end(), modified_section()) != _options.end()) ||
|
|
||||||
(find_if(_sections.begin(), _sections.end(), modified_section()) != _sections.end()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Section(): _name(""), _description(""), _recursive(false) {};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const std::string _name;
|
|
||||||
const std::string _description;
|
|
||||||
|
|
||||||
OptionMap _options;
|
|
||||||
SectionMap _sections;
|
|
||||||
|
|
||||||
const bool _recursive;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _CONFIG_SECTION_HPP_ */
|
|
|
@ -1,15 +0,0 @@
|
||||||
|
|
||||||
#ifndef _CONST_THIS_H_
|
|
||||||
#define _CONST_THIS_H_
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
struct ConstThis
|
|
||||||
{
|
|
||||||
T const & constThis() const
|
|
||||||
{
|
|
||||||
// TODO: will this return the right reference?
|
|
||||||
return static_cast<const T&>(*this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _CONST_THIS_H_ */
|
|
|
@ -1,102 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include <initializer.hpp>
|
|
||||||
|
|
||||||
#ifndef _FLAGGER_HPP_
|
|
||||||
#define _FLAGGER_HPP_
|
|
||||||
|
|
||||||
template < typename Flag >
|
|
||||||
struct Flagger
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
struct Bool
|
|
||||||
{
|
|
||||||
Bool(): value(false) {};
|
|
||||||
Bool(bool &v): value(v) {};
|
|
||||||
|
|
||||||
bool value;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::map< Flag, Bool > Map;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef Initializer< Flag > InitFlags;
|
|
||||||
|
|
||||||
Flagger() {};
|
|
||||||
|
|
||||||
Flagger(InitFlags flags)
|
|
||||||
{
|
|
||||||
for (typename InitFlags::iterator i = flags.begin(); i != flags.end(); i++)
|
|
||||||
{
|
|
||||||
Flag & flag = (*i);
|
|
||||||
_map[flag].value = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
void set(Flag elt, bool value = true)
|
|
||||||
{
|
|
||||||
_map[elt].value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_set(Flag elt)
|
|
||||||
{
|
|
||||||
return _map[elt].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
Flagger & operator&(Flag elt)
|
|
||||||
{
|
|
||||||
set(elt);
|
|
||||||
return *this;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool operator[](Flag elt)
|
|
||||||
{
|
|
||||||
return is_set(elt);
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Map _map;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _FLAGGER_HPP_ */
|
|
|
@ -1,337 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "format.hpp"
|
|
||||||
//#include <iostream>
|
|
||||||
|
|
||||||
void FormatTraits::initialize(const char * format_string)
|
|
||||||
{
|
|
||||||
std::string txt;
|
|
||||||
|
|
||||||
const char * ptr = format_string;
|
|
||||||
|
|
||||||
while (*ptr != '\0')
|
|
||||||
{
|
|
||||||
if (*ptr != '%')
|
|
||||||
{
|
|
||||||
txt += *ptr;
|
|
||||||
++ptr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * ptr2 = ptr+1;
|
|
||||||
|
|
||||||
if (*ptr2 == '%')
|
|
||||||
{
|
|
||||||
txt += *ptr;
|
|
||||||
ptr += 2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!txt.empty())
|
|
||||||
push_argument(txt, T_LITERAL);
|
|
||||||
|
|
||||||
std::string arg(1, *ptr);
|
|
||||||
|
|
||||||
++ptr;
|
|
||||||
|
|
||||||
bool finished = false;
|
|
||||||
|
|
||||||
short long_count = 0;
|
|
||||||
short short_count = 0;
|
|
||||||
|
|
||||||
while(*ptr != '\0' && !finished)
|
|
||||||
{
|
|
||||||
switch (*ptr)
|
|
||||||
{
|
|
||||||
case ' ':
|
|
||||||
// uncomplete format with ' ', make it a literal.
|
|
||||||
arg += *ptr;
|
|
||||||
push_argument(arg, T_LITERAL);
|
|
||||||
finished = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '%':
|
|
||||||
// uncomplete format with '%', make it a literal and start a new format.
|
|
||||||
push_argument(arg, T_LITERAL);
|
|
||||||
arg += *ptr;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'h':
|
|
||||||
short_count = std::min<short>(short_count+1, 2);
|
|
||||||
long_count = 0;
|
|
||||||
arg += *ptr;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'l':
|
|
||||||
long_count = std::min<short>(long_count+1, 2);
|
|
||||||
short_count = 0;
|
|
||||||
arg += *ptr;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'd':
|
|
||||||
case 'i':
|
|
||||||
arg += *ptr;
|
|
||||||
switch (long_count - short_count)
|
|
||||||
{
|
|
||||||
case 2:
|
|
||||||
push_argument(arg, T_SIGNED_LONG_LONG);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
push_argument(arg, T_SIGNED_LONG);
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
push_argument(arg, T_SIGNED_INT);
|
|
||||||
break;
|
|
||||||
case -1:
|
|
||||||
push_argument(arg, T_SIGNED_SHORT);
|
|
||||||
break;
|
|
||||||
case -2:
|
|
||||||
push_argument(arg, T_SIGNED_SHORT_SHORT);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
finished = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'o':
|
|
||||||
case 'u':
|
|
||||||
case 'x':
|
|
||||||
case 'X':
|
|
||||||
arg += *ptr;
|
|
||||||
switch (long_count - short_count)
|
|
||||||
{
|
|
||||||
case 2:
|
|
||||||
push_argument(arg, T_UNSIGNED_LONG_LONG);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
push_argument(arg, T_UNSIGNED_LONG);
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
push_argument(arg, T_UNSIGNED_INT);
|
|
||||||
break;
|
|
||||||
case -1:
|
|
||||||
push_argument(arg, T_UNSIGNED_SHORT);
|
|
||||||
break;
|
|
||||||
case -2:
|
|
||||||
push_argument(arg, T_UNSIGNED_SHORT_SHORT);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
finished = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'e':
|
|
||||||
case 'E':
|
|
||||||
case 'f':
|
|
||||||
case 'F':
|
|
||||||
case 'g':
|
|
||||||
case 'G':
|
|
||||||
case 'a':
|
|
||||||
case 'A':
|
|
||||||
arg += *ptr;
|
|
||||||
push_argument(arg, T_FLOAT);
|
|
||||||
finished = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'c':
|
|
||||||
arg += *ptr;
|
|
||||||
push_argument(arg, T_CHAR);
|
|
||||||
finished = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 's':
|
|
||||||
arg += *ptr;
|
|
||||||
push_argument(arg, T_STRING);
|
|
||||||
finished = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'p':
|
|
||||||
arg += *ptr;
|
|
||||||
push_argument(arg, T_POINTER);
|
|
||||||
finished = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'C':
|
|
||||||
case 'S':
|
|
||||||
case 'm':
|
|
||||||
case 'n': // unsupported for now.
|
|
||||||
arg += *ptr;
|
|
||||||
push_argument(arg, T_ANYTHING);
|
|
||||||
finished = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
arg += *ptr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
++ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!arg.empty())
|
|
||||||
push_argument(arg, T_LITERAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!txt.empty())
|
|
||||||
push_argument(txt, T_LITERAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormatTraits::push_argument(std::string & data, FormatTraits::Type type)
|
|
||||||
{
|
|
||||||
// std::cerr << "pushing type (" << type << ") with format (" << data << ")" << std::endl;
|
|
||||||
|
|
||||||
_args.push(Argument(data, type));
|
|
||||||
data.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormatTraits::pop_argument(void)
|
|
||||||
{
|
|
||||||
_args.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
const FormatTraits::Argument * FormatTraits::next_argument(void)
|
|
||||||
{
|
|
||||||
// std::cerr << "size: " << _args.size() << std::endl;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
// std::cerr << "loop size: " << _args.size() << std::endl;
|
|
||||||
|
|
||||||
if (_args.empty())
|
|
||||||
return NULL; // throw NoArgumentLeft();
|
|
||||||
|
|
||||||
const Argument & top = _args.front();
|
|
||||||
|
|
||||||
if (top.type() == T_LITERAL)
|
|
||||||
{
|
|
||||||
// std::cerr << "top type == LITERAL, looping..." << std::endl;
|
|
||||||
_result += top.fmts();
|
|
||||||
pop_argument();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// std::cerr << "top type: " << top.type() << std::endl;
|
|
||||||
return ⊤
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
Format::Format(const char * format_string, bool raise_exception)
|
|
||||||
: _format(format_string), _valid(true), _raise(raise_exception)
|
|
||||||
{
|
|
||||||
FormatTraits::initialize(format_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
Format::Format(std::string format_string, bool raise_exception)
|
|
||||||
: _format(format_string), _valid(true), _raise(raise_exception)
|
|
||||||
{
|
|
||||||
FormatTraits::initialize(format_string.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Format::Format(std::string & format_string, bool raise_exception)
|
|
||||||
: _format(NULL), _valid(true), _raise(raise_exception)
|
|
||||||
{
|
|
||||||
initialize(format_string.c_str());
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Format::mark_invalid(std::string & msg)
|
|
||||||
{
|
|
||||||
if (_valid)
|
|
||||||
{
|
|
||||||
_valid = false;
|
|
||||||
|
|
||||||
_result = "** INVALID FORMAT: ";
|
|
||||||
_result += msg;
|
|
||||||
_result += " **";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Format::raise(void) const
|
|
||||||
{
|
|
||||||
if (!_valid)
|
|
||||||
{
|
|
||||||
// call specialized class
|
|
||||||
FormatException::raise(_result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Format::valid(void) const
|
|
||||||
{
|
|
||||||
// raise();
|
|
||||||
return _valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Format::str()
|
|
||||||
{
|
|
||||||
if (!valid())
|
|
||||||
return _result;
|
|
||||||
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
if (next_argument() != NULL)
|
|
||||||
{
|
|
||||||
std::string msg;
|
|
||||||
|
|
||||||
msg += "too few arguments passed for format '";
|
|
||||||
msg += _format;
|
|
||||||
msg += "' (";
|
|
||||||
msg += _format;
|
|
||||||
msg += ")";
|
|
||||||
|
|
||||||
mark_invalid(msg);
|
|
||||||
|
|
||||||
return _result;
|
|
||||||
}
|
|
||||||
// catch (NoArgumentLeft e)
|
|
||||||
// {
|
|
||||||
// return _result;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,561 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _FORMAT_H_
|
|
||||||
#define _FORMAT_H_
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <typeinfo>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include <queue>
|
|
||||||
#include <iostream>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef WIN32 // WINDOWS
|
|
||||||
# include <KHostSystem.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct InvalidFormat
|
|
||||||
{
|
|
||||||
InvalidFormat(std::string _msg) : msg(_msg) {}
|
|
||||||
const std::string msg;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < bool E >
|
|
||||||
struct FormatException
|
|
||||||
{
|
|
||||||
void raise(const std::string & msg) const
|
|
||||||
{
|
|
||||||
/* DO NOTHING */
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template < >
|
|
||||||
struct FormatException < true >
|
|
||||||
{
|
|
||||||
void raise(const std::string & msg) const
|
|
||||||
{
|
|
||||||
throw InvalidFormat(msg);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FormatTraits
|
|
||||||
{
|
|
||||||
enum Type
|
|
||||||
{
|
|
||||||
T_ANYTHING = 1,
|
|
||||||
|
|
||||||
T_SIGNED_SHORT,
|
|
||||||
T_SIGNED_SHORT_SHORT,
|
|
||||||
T_SIGNED_INT,
|
|
||||||
T_SIGNED_LONG,
|
|
||||||
T_SIGNED_LONG_LONG,
|
|
||||||
|
|
||||||
T_UNSIGNED_SHORT,
|
|
||||||
T_UNSIGNED_SHORT_SHORT,
|
|
||||||
T_UNSIGNED_INT,
|
|
||||||
T_UNSIGNED_LONG,
|
|
||||||
T_UNSIGNED_LONG_LONG,
|
|
||||||
|
|
||||||
T_FLOAT,
|
|
||||||
T_CHAR,
|
|
||||||
|
|
||||||
T_POINTER,
|
|
||||||
T_STRING,
|
|
||||||
|
|
||||||
T_LITERAL
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Argument
|
|
||||||
{
|
|
||||||
Argument(std::string fmts, Type type)
|
|
||||||
: _fmts(fmts), _type(type) {};
|
|
||||||
|
|
||||||
const Type type(void) const { return _type; }
|
|
||||||
const std::string & fmts(void) const { return _fmts; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const std::string _fmts;
|
|
||||||
const Type _type;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::queue < Argument > ArgumentQueue;
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
|
|
||||||
template < typename V >
|
|
||||||
bool number_verify_signed_short( V value ) const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
((typeid(V) == typeid(short int) ||
|
|
||||||
typeid(V) == typeid(short) ||
|
|
||||||
typeid(V) == typeid(const short int) ||
|
|
||||||
typeid(V) == typeid(const short) ||
|
|
||||||
typeid(V) == typeid(volatile short int) ||
|
|
||||||
typeid(V) == typeid(volatile short)) &&
|
|
||||||
sizeof(V) == sizeof(short));
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename V >
|
|
||||||
bool number_verify_unsigned_short( V value ) const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
((typeid(V) == typeid(unsigned short int) ||
|
|
||||||
typeid(V) == typeid(unsigned short) ||
|
|
||||||
typeid(V) == typeid(const unsigned short int) ||
|
|
||||||
typeid(V) == typeid(const unsigned short) ||
|
|
||||||
typeid(V) == typeid(volatile unsigned short int) ||
|
|
||||||
typeid(V) == typeid(volatile unsigned short)) &&
|
|
||||||
sizeof(V) == sizeof(unsigned short));
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename V >
|
|
||||||
bool number_verify_signed_long( V value ) const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
((typeid(V) == typeid(long int) ||
|
|
||||||
typeid(V) == typeid(long) ||
|
|
||||||
typeid(V) == typeid(const long int) ||
|
|
||||||
typeid(V) == typeid(const long) ||
|
|
||||||
typeid(V) == typeid(volatile long int) ||
|
|
||||||
typeid(V) == typeid(volatile long)) &&
|
|
||||||
sizeof(V) == sizeof(long));
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename V >
|
|
||||||
bool number_verify_unsigned_long( V value ) const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
((typeid(V) == typeid(unsigned long int) ||
|
|
||||||
typeid(V) == typeid(unsigned long) ||
|
|
||||||
typeid(V) == typeid(const unsigned long int) ||
|
|
||||||
typeid(V) == typeid(const unsigned long) ||
|
|
||||||
typeid(V) == typeid(volatile unsigned long int) ||
|
|
||||||
typeid(V) == typeid(volatile unsigned long)) &&
|
|
||||||
sizeof(V) == sizeof(long long));
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename V >
|
|
||||||
bool number_verify_signed_long_long( V value ) const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
((typeid(V) == typeid(long long int) ||
|
|
||||||
typeid(V) == typeid(long long) ||
|
|
||||||
typeid(V) == typeid(const long long int) ||
|
|
||||||
typeid(V) == typeid(const long long) ||
|
|
||||||
typeid(V) == typeid(volatile long long) ||
|
|
||||||
typeid(V) == typeid(volatile long long int)) &&
|
|
||||||
sizeof(V) == sizeof(long long));
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename V >
|
|
||||||
bool number_verify_unsigned_long_long( V value ) const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
((typeid(V) == typeid(unsigned long long int) ||
|
|
||||||
typeid(V) == typeid(unsigned long long) ||
|
|
||||||
typeid(V) == typeid(const unsigned long long int) ||
|
|
||||||
typeid(V) == typeid(const unsigned long long) ||
|
|
||||||
typeid(V) == typeid(volatile unsigned long long) ||
|
|
||||||
typeid(V) == typeid(volatile unsigned long long int)) &&
|
|
||||||
sizeof(V) == sizeof(unsigned long long));
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename V >
|
|
||||||
bool number_verify_signed_int( V value ) const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
(sizeof(V) <= sizeof(int) ||
|
|
||||||
typeid(V) == typeid(int) ||
|
|
||||||
typeid(V) == typeid(const int) ||
|
|
||||||
typeid(V) == typeid(volatile int));
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename V >
|
|
||||||
bool number_verify_unsigned_int( V value ) const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
(sizeof(V) <= sizeof(unsigned int) ||
|
|
||||||
typeid(V) == typeid(unsigned int) ||
|
|
||||||
typeid(V) == typeid(const unsigned int) ||
|
|
||||||
typeid(V) == typeid(volatile unsigned int));
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename V >
|
|
||||||
bool generic_verify( V value, const Type type ) const
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
/* EXCEPTION: consider any number an valid input. */
|
|
||||||
case T_SIGNED_INT:
|
|
||||||
case T_UNSIGNED_INT:
|
|
||||||
return
|
|
||||||
(number_verify_signed_int(value) ||
|
|
||||||
number_verify_unsigned_int(value) ||
|
|
||||||
number_verify_signed_long(value) ||
|
|
||||||
number_verify_unsigned_long(value) ||
|
|
||||||
number_verify_signed_short(value) ||
|
|
||||||
number_verify_unsigned_short(value));
|
|
||||||
|
|
||||||
case T_SIGNED_SHORT_SHORT:
|
|
||||||
return (typeid(V) == typeid(char) || typeid(V) == typeid(const char));
|
|
||||||
|
|
||||||
case T_SIGNED_SHORT:
|
|
||||||
return number_verify_signed_short(value);
|
|
||||||
|
|
||||||
case T_SIGNED_LONG:
|
|
||||||
return number_verify_signed_long(value);
|
|
||||||
|
|
||||||
case T_SIGNED_LONG_LONG:
|
|
||||||
return number_verify_signed_long_long(value);
|
|
||||||
|
|
||||||
case T_UNSIGNED_SHORT_SHORT:
|
|
||||||
return (typeid(V) == typeid(unsigned char) || typeid(V) == typeid(unsigned char));
|
|
||||||
|
|
||||||
case T_UNSIGNED_SHORT:
|
|
||||||
return number_verify_unsigned_short(value);
|
|
||||||
|
|
||||||
case T_UNSIGNED_LONG:
|
|
||||||
return number_verify_unsigned_long(value);
|
|
||||||
|
|
||||||
case T_UNSIGNED_LONG_LONG:
|
|
||||||
return number_verify_unsigned_long_long(value);
|
|
||||||
|
|
||||||
case T_FLOAT:
|
|
||||||
return (typeid(V) == typeid(float)) || (typeid(V) == typeid(double) ||
|
|
||||||
typeid(V) == typeid(const float)) || (typeid(V) == typeid(const double));
|
|
||||||
|
|
||||||
case T_CHAR:
|
|
||||||
return (typeid(V) == typeid(char)) || (typeid(V) == typeid(unsigned char) ||
|
|
||||||
typeid(V) == typeid(const char)) || (typeid(V) == typeid(const unsigned char));
|
|
||||||
|
|
||||||
case T_POINTER:
|
|
||||||
case T_STRING:
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case T_ANYTHING:
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case T_LITERAL:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Argument * next_argument(void);
|
|
||||||
|
|
||||||
void push_argument(std::string & data, const Type type);
|
|
||||||
void pop_argument(void);
|
|
||||||
|
|
||||||
void initialize(const char *);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ArgumentQueue _args;
|
|
||||||
std::string _result;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template < bool E = false >
|
|
||||||
struct FormatBase: protected FormatTraits, protected FormatException < E >
|
|
||||||
{
|
|
||||||
static const unsigned int strings_base_length = 64;
|
|
||||||
static const unsigned int generic_base_length = 64;
|
|
||||||
|
|
||||||
explicit FormatBase(const char * format_string)
|
|
||||||
: _format(format_string), _valid(true)
|
|
||||||
{
|
|
||||||
FormatTraits::initialize(format_string);
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit FormatBase(std::string format_string)
|
|
||||||
: _format(format_string), _valid(true)
|
|
||||||
{
|
|
||||||
FormatTraits::initialize(format_string.c_str());
|
|
||||||
};
|
|
||||||
|
|
||||||
bool valid(void) const
|
|
||||||
{
|
|
||||||
return _valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string str()
|
|
||||||
{
|
|
||||||
if (valid() && (next_argument() != NULL))
|
|
||||||
{
|
|
||||||
std::string msg;
|
|
||||||
|
|
||||||
// TODO: why format appears two times?
|
|
||||||
msg += "too few arguments passed for format '";
|
|
||||||
msg += _format;
|
|
||||||
msg += "' (";
|
|
||||||
msg += _format;
|
|
||||||
msg += ")";
|
|
||||||
|
|
||||||
mark_invalid(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
raise();
|
|
||||||
return _result;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template < typename V >
|
|
||||||
FormatBase & operator%( V value )
|
|
||||||
{
|
|
||||||
if (!valid())
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
const Argument * top = next_argument();
|
|
||||||
|
|
||||||
if (top == NULL)
|
|
||||||
{
|
|
||||||
std::string msg;
|
|
||||||
|
|
||||||
msg += "too many arguments passed for format '";
|
|
||||||
msg += _format;
|
|
||||||
msg += "'";
|
|
||||||
|
|
||||||
mark_invalid(msg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char temp[generic_base_length];
|
|
||||||
|
|
||||||
if (!FormatTraits::generic_verify(value, top->type()))
|
|
||||||
{
|
|
||||||
std::string msg;
|
|
||||||
|
|
||||||
msg += "type mismatch: got type '";
|
|
||||||
msg += typeid(value).name();
|
|
||||||
msg += "' in format '";
|
|
||||||
msg += top->fmts();
|
|
||||||
msg += "' (";
|
|
||||||
msg += _format;
|
|
||||||
msg += ")";
|
|
||||||
|
|
||||||
mark_invalid(msg);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(temp, sizeof(temp), top->fmts().c_str(), value);
|
|
||||||
_result += temp;
|
|
||||||
|
|
||||||
pop_argument();
|
|
||||||
}
|
|
||||||
|
|
||||||
raise();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename V >
|
|
||||||
FormatBase & operator%( V * value )
|
|
||||||
{
|
|
||||||
if (!valid())
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
const Argument * top = next_argument();
|
|
||||||
|
|
||||||
if (top == NULL)
|
|
||||||
{
|
|
||||||
std::string msg;
|
|
||||||
|
|
||||||
msg += "too many arguments passed for format '";
|
|
||||||
msg += _format;
|
|
||||||
msg += "'";
|
|
||||||
|
|
||||||
mark_invalid(msg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (top->type())
|
|
||||||
{
|
|
||||||
case T_POINTER:
|
|
||||||
{
|
|
||||||
char temp[generic_base_length];
|
|
||||||
snprintf(temp, sizeof(temp), top->fmts().c_str(), value);
|
|
||||||
_result += temp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_STRING:
|
|
||||||
{
|
|
||||||
if ((typeid(const char) == typeid(V)) ||
|
|
||||||
(typeid(char) == typeid(V)) ||
|
|
||||||
(typeid(const unsigned char) == typeid(V)) ||
|
|
||||||
(typeid(unsigned char) == typeid(V)) ||
|
|
||||||
(typeid(const void) == typeid(V)) ||
|
|
||||||
(typeid(void) == typeid(V)))
|
|
||||||
{
|
|
||||||
int len = strlen((const char*)value)+strings_base_length+1;
|
|
||||||
|
|
||||||
char * temp = new char[len];
|
|
||||||
|
|
||||||
snprintf(temp, len, top->fmts().c_str(), value);
|
|
||||||
_result += temp;
|
|
||||||
|
|
||||||
delete[] temp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string msg;
|
|
||||||
|
|
||||||
msg += "type mismatch: got type '";
|
|
||||||
msg += typeid(value).name();
|
|
||||||
msg += "' in string format (";
|
|
||||||
msg += _format;
|
|
||||||
msg += ")";
|
|
||||||
|
|
||||||
mark_invalid(msg);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
std::string msg;
|
|
||||||
|
|
||||||
msg += "type mismatch: got pointer/string type in format '";
|
|
||||||
msg += top->fmts();
|
|
||||||
msg += "' (";
|
|
||||||
msg += _format;
|
|
||||||
msg += ")";
|
|
||||||
|
|
||||||
mark_invalid(msg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pop_argument();
|
|
||||||
}
|
|
||||||
|
|
||||||
raise();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
FormatBase & operator%( const std::string value )
|
|
||||||
{
|
|
||||||
if (!valid())
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
const Argument * top = next_argument();
|
|
||||||
|
|
||||||
if (top == NULL)
|
|
||||||
{
|
|
||||||
std::string msg;
|
|
||||||
|
|
||||||
msg += "too many arguments passed for format '";
|
|
||||||
msg += _format;
|
|
||||||
msg += "'";
|
|
||||||
|
|
||||||
mark_invalid(msg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (top->type() == T_STRING)
|
|
||||||
{
|
|
||||||
int len = value.length()+strings_base_length+1;
|
|
||||||
|
|
||||||
char * temp = new char[len];
|
|
||||||
|
|
||||||
snprintf(temp, len, top->fmts().c_str(), value.c_str());
|
|
||||||
_result += temp;
|
|
||||||
|
|
||||||
delete[] temp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string msg;
|
|
||||||
|
|
||||||
msg += "type mismatch: got string type in format '";
|
|
||||||
msg += top->fmts();
|
|
||||||
msg += "' (";
|
|
||||||
msg += _format;
|
|
||||||
msg += ")";
|
|
||||||
|
|
||||||
mark_invalid(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
pop_argument();
|
|
||||||
}
|
|
||||||
|
|
||||||
raise();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void mark_invalid(std::string & msg)
|
|
||||||
{
|
|
||||||
if (_valid)
|
|
||||||
{
|
|
||||||
_valid = false;
|
|
||||||
|
|
||||||
_result = "** INVALID FORMAT: ";
|
|
||||||
_result += msg;
|
|
||||||
_result += " **";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void raise(void) const
|
|
||||||
{
|
|
||||||
if (!_valid)
|
|
||||||
{
|
|
||||||
// call specialized class
|
|
||||||
FormatException< E >::raise(_result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const std::string _format;
|
|
||||||
bool _valid;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* useful typedef for general usage (not generating exceptions) */
|
|
||||||
typedef FormatBase<> Format;
|
|
||||||
|
|
||||||
/* macros used for shortening lines and making the code clearer */
|
|
||||||
#define STG(x) (x).str()
|
|
||||||
#define FMT(x) Format(x)
|
|
||||||
|
|
||||||
#endif /* _FORMAT_H_ */
|
|
|
@ -1,429 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the "LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <refcounter.hpp>
|
|
||||||
|
|
||||||
#ifndef _FUNCTION_HPP_
|
|
||||||
#define _FUNCTION_HPP_
|
|
||||||
|
|
||||||
namespace Function
|
|
||||||
{
|
|
||||||
struct EmptyFunction {};
|
|
||||||
struct NonMemberFunction {};
|
|
||||||
|
|
||||||
/**/
|
|
||||||
|
|
||||||
template < typename FunctionTraits >
|
|
||||||
struct StorageBase: COUNTER_SUPER(StorageBase < FunctionTraits >)
|
|
||||||
{
|
|
||||||
typedef typename FunctionTraits::BaseType BaseType;
|
|
||||||
|
|
||||||
typedef typename FunctionTraits::FunType FunType;
|
|
||||||
typedef typename FunctionTraits::ObjType ObjType;
|
|
||||||
|
|
||||||
template < typename Functor >
|
|
||||||
StorageBase(const Functor f)
|
|
||||||
: _object(reinterpret_cast< ObjType >(new Functor(f))),
|
|
||||||
_function(reinterpret_cast< FunType >(&Functor::operator())),
|
|
||||||
_malloced(true)
|
|
||||||
{};
|
|
||||||
|
|
||||||
template < typename Functor >
|
|
||||||
StorageBase(Functor & f, bool malloced)
|
|
||||||
: _object(reinterpret_cast< ObjType >((malloced ? new Functor(f) : &f))),
|
|
||||||
_function(reinterpret_cast< FunType >(&Functor::operator())),
|
|
||||||
_malloced(malloced)
|
|
||||||
{};
|
|
||||||
|
|
||||||
StorageBase(FunType const * member)
|
|
||||||
: _object(reinterpret_cast< ObjType >(0)),
|
|
||||||
_function(reinterpret_cast< FunType >(member)),
|
|
||||||
_malloced(false)
|
|
||||||
{};
|
|
||||||
|
|
||||||
StorageBase()
|
|
||||||
: _object(reinterpret_cast< ObjType >(0)),
|
|
||||||
_function(reinterpret_cast< FunType >(0)),
|
|
||||||
_malloced(false)
|
|
||||||
{};
|
|
||||||
|
|
||||||
StorageBase(const StorageBase & o)
|
|
||||||
: COUNTER_REFER(o, StorageBase < FunctionTraits >),
|
|
||||||
_object(o._object), _function(o._function), _malloced(o._malloced)
|
|
||||||
{};
|
|
||||||
|
|
||||||
virtual ~StorageBase() {};
|
|
||||||
|
|
||||||
void unreference()
|
|
||||||
{
|
|
||||||
// TODO: will this work if we delete a different type? //
|
|
||||||
if (_malloced)
|
|
||||||
delete _object;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename Functor >
|
|
||||||
void operator=(Functor f)
|
|
||||||
{
|
|
||||||
_object = reinterpret_cast< ObjType >(new Functor(f)),
|
|
||||||
_function = reinterpret_cast< FunType >(&Functor::operator());
|
|
||||||
_malloced = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ObjType _object;
|
|
||||||
FunType _function;
|
|
||||||
bool _malloced;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**/
|
|
||||||
|
|
||||||
template < typename R >
|
|
||||||
struct VTable0
|
|
||||||
{
|
|
||||||
R operator()(void) { return R(); };
|
|
||||||
};
|
|
||||||
|
|
||||||
template < >
|
|
||||||
struct VTable0< void >
|
|
||||||
{
|
|
||||||
void operator()(void) { return; };
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename R >
|
|
||||||
struct Function0Traits
|
|
||||||
{
|
|
||||||
typedef VTable0<R> BaseType;
|
|
||||||
|
|
||||||
typedef R (BaseType::* FunType)(void);
|
|
||||||
typedef BaseType * ObjType;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**/
|
|
||||||
|
|
||||||
template < typename R, typename A0 >
|
|
||||||
struct VTable1
|
|
||||||
{
|
|
||||||
R operator()(A0 a0) { return R(); };
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename A0 >
|
|
||||||
struct VTable1< void, A0 >
|
|
||||||
{
|
|
||||||
void operator()(A0 a0) { return; };
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename R, typename A0 >
|
|
||||||
struct Function1Traits
|
|
||||||
{
|
|
||||||
typedef VTable1<R, A0> BaseType;
|
|
||||||
|
|
||||||
typedef R (BaseType::* FunType)(A0);
|
|
||||||
typedef BaseType * ObjType;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**/
|
|
||||||
|
|
||||||
template < typename R, typename A0, typename A1 >
|
|
||||||
struct VTable2
|
|
||||||
{
|
|
||||||
R operator()(A0 a0, A1) { return R(); };
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename A0, typename A1 >
|
|
||||||
struct VTable2< void, A0, A1 >
|
|
||||||
{
|
|
||||||
void operator()(A0 a0, A1 a1) { return; };
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename R, typename A0, typename A1 >
|
|
||||||
struct Function2Traits
|
|
||||||
{
|
|
||||||
typedef VTable2<R, A0, A1> BaseType;
|
|
||||||
|
|
||||||
typedef R (BaseType::* FunType)(A0, A1);
|
|
||||||
typedef BaseType * ObjType;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**/
|
|
||||||
|
|
||||||
template < typename R, typename A0, typename A1, typename A2 >
|
|
||||||
struct VTable3
|
|
||||||
{
|
|
||||||
R operator()(A0 a0, A1 a1, A2 a2) { return R(); };
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename A0, typename A1, typename A2 >
|
|
||||||
struct VTable3< void, A0, A1, A2 >
|
|
||||||
{
|
|
||||||
void operator()(A0 a0, A1 a1, A2 a2) { return; };
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename R, typename A0, typename A1, typename A2 >
|
|
||||||
struct Function3Traits
|
|
||||||
{
|
|
||||||
typedef VTable3<R, A0, A1, A2> BaseType;
|
|
||||||
|
|
||||||
typedef R (BaseType::* FunType)(A0, A1, A2);
|
|
||||||
typedef BaseType * ObjType;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**/
|
|
||||||
|
|
||||||
template < typename R, typename A0, typename A1, typename A2, typename A3 >
|
|
||||||
struct VTable4
|
|
||||||
{
|
|
||||||
R operator()(A0 a0, A1 a1, A2 a2, A3 a3) { return R(); };
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename A0, typename A1, typename A2, typename A3 >
|
|
||||||
struct VTable4< void, A0, A1, A2, A3 >
|
|
||||||
{
|
|
||||||
void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { return; };
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename R, typename A0, typename A1, typename A2, typename A3 >
|
|
||||||
struct Function4Traits
|
|
||||||
{
|
|
||||||
typedef VTable4<R, A0, A1, A2, A3> BaseType;
|
|
||||||
|
|
||||||
typedef R (BaseType::* FunType)(A0, A1, A2, A3);
|
|
||||||
typedef BaseType * ObjType;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**/
|
|
||||||
|
|
||||||
template < typename R, typename A0 >
|
|
||||||
struct Function0 : public StorageBase < Function0Traits < R > >
|
|
||||||
{
|
|
||||||
typedef StorageBase < Function0Traits < R > > Storage;
|
|
||||||
|
|
||||||
template < typename Functor >
|
|
||||||
Function0(const Functor f)
|
|
||||||
: Storage(f) {};
|
|
||||||
|
|
||||||
template < typename Functor >
|
|
||||||
Function0(Functor & f, bool m)
|
|
||||||
: Storage(f, m) {};
|
|
||||||
|
|
||||||
Function0(const typename Function0Traits < R >::FunType * m)
|
|
||||||
: Storage(m) {};
|
|
||||||
|
|
||||||
Function0() {};
|
|
||||||
|
|
||||||
R operator()(void)
|
|
||||||
{
|
|
||||||
if (reinterpret_cast<void *>(Storage::_object) == 0)
|
|
||||||
throw EmptyFunction();
|
|
||||||
|
|
||||||
return ((Storage::_object)->*(Storage::_function))();
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
R operator()(Object * object)
|
|
||||||
{
|
|
||||||
if (reinterpret_cast<void *>(Storage::_function) == 0)
|
|
||||||
throw EmptyFunction();
|
|
||||||
|
|
||||||
if (reinterpret_cast<void *>(Storage::_object) != 0)
|
|
||||||
throw NonMemberFunction();
|
|
||||||
|
|
||||||
return (reinterpret_cast< typename Function0Traits < R >::ObjType *>(object)->*(Storage::_function))();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename R, typename A0 >
|
|
||||||
struct Function1 : public StorageBase < Function1Traits < R, A0 > >
|
|
||||||
{
|
|
||||||
typedef StorageBase < Function1Traits < R, A0 > > Storage;
|
|
||||||
|
|
||||||
template < typename Functor >
|
|
||||||
Function1(const Functor f)
|
|
||||||
: Storage(f) {};
|
|
||||||
|
|
||||||
template < typename Functor >
|
|
||||||
Function1(Functor & f, bool m)
|
|
||||||
: Storage(f, m) {};
|
|
||||||
|
|
||||||
Function1(const typename Function1Traits < R, A0 >::FunType * m)
|
|
||||||
: Storage(m) {};
|
|
||||||
|
|
||||||
Function1() {};
|
|
||||||
|
|
||||||
R operator()(A0 a0)
|
|
||||||
{
|
|
||||||
if (reinterpret_cast<void *>(Storage::_object) == 0)
|
|
||||||
throw EmptyFunction();
|
|
||||||
|
|
||||||
return ((Storage::_object)->*(Storage::_function))(a0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
R operator()(Object * object, A0 a0)
|
|
||||||
{
|
|
||||||
if (reinterpret_cast<void *>(Storage::_function) == 0)
|
|
||||||
throw EmptyFunction();
|
|
||||||
|
|
||||||
if (reinterpret_cast<void *>(Storage::_object) != 0)
|
|
||||||
throw NonMemberFunction();
|
|
||||||
|
|
||||||
return (reinterpret_cast< typename Function1Traits < R, A0 >::ObjType *>(object)->*(Storage::_function))(a0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename R, typename A0, typename A1 >
|
|
||||||
struct Function2 : public StorageBase < Function2Traits < R, A0, A1 > >
|
|
||||||
{
|
|
||||||
typedef StorageBase < Function2Traits < R, A0, A1 > > Storage;
|
|
||||||
|
|
||||||
template < typename Functor >
|
|
||||||
Function2(const Functor f)
|
|
||||||
: Storage(f) {};
|
|
||||||
|
|
||||||
template < typename Functor >
|
|
||||||
Function2(Functor & f, bool m)
|
|
||||||
: Storage(f, m) {};
|
|
||||||
|
|
||||||
Function2(const typename Function2Traits < R, A0, A1 >::FunType * m)
|
|
||||||
: Storage(m) {};
|
|
||||||
|
|
||||||
Function2() {};
|
|
||||||
|
|
||||||
R operator()(A0 a0, A1 a1)
|
|
||||||
{
|
|
||||||
if (reinterpret_cast<void *>(Storage::_object) == 0)
|
|
||||||
throw EmptyFunction();
|
|
||||||
|
|
||||||
return ((Storage::_object)->*(Storage::_function))(a0, a1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
R operator()(Object * object, A0 a0, A1 a1)
|
|
||||||
{
|
|
||||||
if (reinterpret_cast<void *>(Storage::_function) == 0)
|
|
||||||
throw EmptyFunction();
|
|
||||||
|
|
||||||
if (reinterpret_cast<void *>(Storage::_object) != 0)
|
|
||||||
throw NonMemberFunction();
|
|
||||||
|
|
||||||
return (reinterpret_cast< typename Function2Traits < R, A0, A1 >::ObjType *>(object)->*(Storage::_function))(a0, a1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename R, typename A0, typename A1, typename A2 >
|
|
||||||
struct Function3 : public StorageBase < Function3Traits < R, A0, A1, A2 > >
|
|
||||||
{
|
|
||||||
typedef StorageBase < Function3Traits < R, A0, A1, A2 > > Storage;
|
|
||||||
|
|
||||||
template < typename Functor >
|
|
||||||
Function3(const Functor f)
|
|
||||||
: Storage(f) {};
|
|
||||||
|
|
||||||
template < typename Functor >
|
|
||||||
Function3(Functor & f, bool m)
|
|
||||||
: Storage(f, m) {};
|
|
||||||
|
|
||||||
Function3(const typename Function3Traits < R, A0, A1, A2 >::FunType * m)
|
|
||||||
: Storage(m) {};
|
|
||||||
|
|
||||||
Function3() {};
|
|
||||||
|
|
||||||
R operator()(A0 a0, A1 a1, A2 a2)
|
|
||||||
{
|
|
||||||
if (reinterpret_cast<const void *>(Storage::_object) == 0)
|
|
||||||
throw EmptyFunction();
|
|
||||||
|
|
||||||
return ((Storage::_object)->*(Storage::_function))(a0, a1, a2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
R operator()(Object * object, A0 a0, A1 a1, A2 a2)
|
|
||||||
{
|
|
||||||
if (reinterpret_cast<void *>(Storage::_function) == 0)
|
|
||||||
throw EmptyFunction();
|
|
||||||
|
|
||||||
if (reinterpret_cast<void *>(Storage::_object) != 0)
|
|
||||||
throw NonMemberFunction();
|
|
||||||
|
|
||||||
return (reinterpret_cast< typename Function3Traits < R, A0, A1, A2 >::ObjType *>(object)->*(Storage::_function))(a0, a1, a2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename R, typename A0, typename A1, typename A2, typename A3 >
|
|
||||||
struct Function4 : public StorageBase < Function4Traits < R, A0, A1, A2, A3 > >
|
|
||||||
{
|
|
||||||
typedef StorageBase < Function4Traits < R, A0, A1, A2, A3 > > Storage;
|
|
||||||
|
|
||||||
template < typename Functor >
|
|
||||||
Function4(const Functor f)
|
|
||||||
: Storage(f) {};
|
|
||||||
|
|
||||||
template < typename Functor >
|
|
||||||
Function4(Functor & f, bool m)
|
|
||||||
: Storage(f, m) {};
|
|
||||||
|
|
||||||
Function4(const typename Function4Traits < R, A0, A1, A2, A3 >::FunType * m)
|
|
||||||
: Storage(m) {};
|
|
||||||
|
|
||||||
Function4() {};
|
|
||||||
|
|
||||||
R operator()(A0 a0, A1 a1, A2 a2, A3 a3)
|
|
||||||
{
|
|
||||||
if (reinterpret_cast<void *>(Storage::_object) == 0)
|
|
||||||
throw EmptyFunction();
|
|
||||||
|
|
||||||
return ((Storage::_object)->*(Storage::_function))(a0, a1, a2, a3);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Object >
|
|
||||||
R operator()(Object * object, A0 a0, A1 a1, A2 a2, A3 a3)
|
|
||||||
{
|
|
||||||
if (reinterpret_cast<void *>(Storage::_function) == 0)
|
|
||||||
throw EmptyFunction();
|
|
||||||
|
|
||||||
if (reinterpret_cast<void *>(Storage::_object) != 0)
|
|
||||||
throw NonMemberFunction();
|
|
||||||
|
|
||||||
return (reinterpret_cast< typename Function4Traits < R, A0, A1, A2, A3 >::ObjType *>(object)->*(Storage::_function))(a0, a1, a2, a3);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _FUNCTION_HPP_ */
|
|
|
@ -1,80 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#ifndef _INITIALIZER_HPP_
|
|
||||||
#define _INITIALIZER_HPP_
|
|
||||||
|
|
||||||
template < typename Type >
|
|
||||||
struct Initializer: public std::vector< Type >
|
|
||||||
{
|
|
||||||
typedef std::vector< Type > Super;
|
|
||||||
|
|
||||||
Initializer(Type e) { Super::push_back(e); };
|
|
||||||
Initializer(Type & e) { Super::push_back(e); };
|
|
||||||
|
|
||||||
Initializer & operator&(const Initializer v)
|
|
||||||
{
|
|
||||||
Super::insert(Super::end(), v.begin(), v.end());
|
|
||||||
return *this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Initializer & operator&(Initializer & v)
|
|
||||||
{
|
|
||||||
Super::insert(Super::end(), v.begin(), v.end());
|
|
||||||
return *this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Initializer & operator&(Type v)
|
|
||||||
{
|
|
||||||
Super::insert(Super::end(), v);
|
|
||||||
return *this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Initializer & operator&(Type & v)
|
|
||||||
{
|
|
||||||
Super::insert(Super::end(), v);
|
|
||||||
return *this;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _INITIALIZER_HPP_ */
|
|
|
@ -1,318 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <k3lapi.hpp>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
K3LAPIBase::K3LAPIBase()
|
|
||||||
: _device_count(0), _channel_count(0), _link_count(0),
|
|
||||||
_device_config(0), _channel_config(0), _link_config(0)
|
|
||||||
{};
|
|
||||||
|
|
||||||
/* initialize the whole thing! */
|
|
||||||
|
|
||||||
void K3LAPIBase::start(void)
|
|
||||||
{
|
|
||||||
/* tie the used k3l to the compiled k3l version */
|
|
||||||
char *ret = k3lStart(k3lApiMajorVersion, k3lApiMinorVersion, 0); //k3lApiBuildVersion);
|
|
||||||
|
|
||||||
if (ret && *ret)
|
|
||||||
throw start_failed(ret);
|
|
||||||
|
|
||||||
/* call init automagically */
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void K3LAPIBase::stop(void)
|
|
||||||
{
|
|
||||||
k3lStop();
|
|
||||||
fini();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* envio de comandos para placa */
|
|
||||||
|
|
||||||
void K3LAPIBase::mixer(int32 dev, int32 obj, byte track, KMixerSource src, int32 index) const
|
|
||||||
{
|
|
||||||
KMixerCommand mix;
|
|
||||||
|
|
||||||
mix.Track = track;
|
|
||||||
mix.Source = src;
|
|
||||||
mix.SourceIndex = index;
|
|
||||||
|
|
||||||
command(dev, obj, CM_MIXER, (const char *) &mix);
|
|
||||||
}
|
|
||||||
|
|
||||||
void K3LAPIBase::mixerRecord(int32 dev, KDeviceType type, int32 obj, byte track, KMixerSource src, int32 index) const
|
|
||||||
{
|
|
||||||
/* estes buffers *NAO PODEM SER ESTATICOS*! */
|
|
||||||
char cmd[] = { 0x3f, 0x03, (char)obj, (char)track, 0xff, 0xff };
|
|
||||||
|
|
||||||
switch (src)
|
|
||||||
{
|
|
||||||
case kmsChannel:
|
|
||||||
cmd[4] = 0x05;
|
|
||||||
cmd[5] = (char)index;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kmsNoDelayChannel:
|
|
||||||
cmd[4] = 0x0a;
|
|
||||||
cmd[5] = (char)index;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kmsGenerator:
|
|
||||||
cmd[4] = 0x09;
|
|
||||||
|
|
||||||
switch ((KMixerTone)index)
|
|
||||||
{
|
|
||||||
case kmtSilence:
|
|
||||||
cmd[5] = 0x0F;
|
|
||||||
break;
|
|
||||||
case kmtDial:
|
|
||||||
cmd[5] = 0x08;
|
|
||||||
break;
|
|
||||||
case kmtBusy:
|
|
||||||
cmd[5] = 0x0D;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kmtFax:
|
|
||||||
case kmtVoice:
|
|
||||||
case kmtEndOf425:
|
|
||||||
case kmtCollect:
|
|
||||||
case kmtEndOfDtmf:
|
|
||||||
/* TODO: exception, unable to generate */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kmsCTbus:
|
|
||||||
case kmsPlay:
|
|
||||||
/* TODO: exception, not implemented! */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 dsp = get_dsp(type, DSP_AUDIO);
|
|
||||||
|
|
||||||
raw_command(dev, dsp, cmd, sizeof(cmd));
|
|
||||||
}
|
|
||||||
|
|
||||||
void K3LAPIBase::mixerCTbus(int32 dev, int32 obj, byte track, KMixerSource src, int32 index) const
|
|
||||||
{
|
|
||||||
KMixerCommand mix;
|
|
||||||
|
|
||||||
mix.Track = track;
|
|
||||||
mix.Source = src;
|
|
||||||
mix.SourceIndex = index;
|
|
||||||
|
|
||||||
command(dev, obj, CM_MIXER_CTBUS, (const char *) &mix);
|
|
||||||
}
|
|
||||||
|
|
||||||
void K3LAPIBase::command(int32 dev, int32 obj, int32 code, std::string & str) const
|
|
||||||
{
|
|
||||||
command(dev, obj, code, str.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void K3LAPIBase::command (int32 dev, int32 obj, int32 code, const char * parms) const
|
|
||||||
{
|
|
||||||
K3L_COMMAND cmd;
|
|
||||||
|
|
||||||
cmd.Cmd = code;
|
|
||||||
cmd.Object = obj;
|
|
||||||
cmd.Params = (byte *)parms;
|
|
||||||
|
|
||||||
int32 rc = k3lSendCommand(dev, &cmd);
|
|
||||||
|
|
||||||
if (rc != ksSuccess)
|
|
||||||
throw failed_command(code, dev, obj, rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void K3LAPIBase::raw_command(int32 dev, int32 dsp, std::string & str) const
|
|
||||||
{
|
|
||||||
raw_command(dev, dsp, str.data(), str.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void K3LAPIBase::raw_command(int32 dev, int32 dsp, const char * cmds, int32 size) const
|
|
||||||
{
|
|
||||||
std::string str(cmds, size);
|
|
||||||
|
|
||||||
int32 rc = k3lSendRawCommand(dev, dsp, (void *)cmds, size);
|
|
||||||
|
|
||||||
if (rc != ksSuccess)
|
|
||||||
throw failed_raw_command(dev, dsp, rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
KLibraryStatus K3LAPIBase::get_param(K3L_EVENT *ev, const char *name, std::string &res) const
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
res.append(tmp_param, strlen(tmp_param));
|
|
||||||
return ksSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string K3LAPIBase::get_param(K3L_EVENT *ev, const char *name) const
|
|
||||||
{
|
|
||||||
std::string res;
|
|
||||||
|
|
||||||
KLibraryStatus rc = get_param(ev, name, res);
|
|
||||||
|
|
||||||
if (rc != ksSuccess)
|
|
||||||
throw get_param_failed(name, rc);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string K3LAPIBase::get_param_optional(K3L_EVENT *ev, const char *name) const
|
|
||||||
{
|
|
||||||
std::string res;
|
|
||||||
|
|
||||||
(void)get_param(ev, name, res);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void K3LAPIBase::init(void)
|
|
||||||
{
|
|
||||||
if (_device_count != 0) return;
|
|
||||||
|
|
||||||
_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];
|
|
||||||
_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)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void K3LAPIBase::fini(void)
|
|
||||||
{
|
|
||||||
for (unsigned int dev = 0; dev < _device_count; dev++)
|
|
||||||
{
|
|
||||||
if (_channel_config[dev])
|
|
||||||
{
|
|
||||||
delete[] _channel_config[dev];
|
|
||||||
_channel_config[dev] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_link_config[dev])
|
|
||||||
{
|
|
||||||
delete[] _link_config[dev];
|
|
||||||
_link_config[dev] = 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; }
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 K3LAPIBase::get_dsp(KDeviceType devtype, K3LAPI::DspType type) const
|
|
||||||
{
|
|
||||||
switch (devtype)
|
|
||||||
{
|
|
||||||
case kdtFXO:
|
|
||||||
case kdtFXOVoIP:
|
|
||||||
#if K3L_AT_LEAST(1,6,0)
|
|
||||||
case kdtGSM:
|
|
||||||
case kdtGSMSpx:
|
|
||||||
#endif
|
|
||||||
#if K3L_AT_LEAST(2,1,0)
|
|
||||||
case kdtGSMUSB:
|
|
||||||
case kdtGSMUSBSpx:
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return (type == DSP_AUDIO ? 1 : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 K3LAPIBase::get_dsp(const K3LAPIBase::GenericTarget & tgt, K3LAPI::DspType type) const
|
|
||||||
{
|
|
||||||
return get_dsp(_device_type[tgt.device], type);
|
|
||||||
}
|
|
|
@ -1,494 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include <format.hpp>
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
#include <types.hpp>
|
|
||||||
|
|
||||||
#ifndef _K3LAPI_HPP_
|
|
||||||
#define _K3LAPI_HPP_
|
|
||||||
|
|
||||||
struct K3LAPITraits
|
|
||||||
{
|
|
||||||
struct invalid_device;
|
|
||||||
struct invalid_channel;
|
|
||||||
struct invalid_link;
|
|
||||||
|
|
||||||
struct invalid_target: public std::runtime_error
|
|
||||||
{
|
|
||||||
friend class invalid_device;
|
|
||||||
friend class invalid_channel;
|
|
||||||
friend class invalid_link;
|
|
||||||
|
|
||||||
const int32 device, object;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
invalid_target(int32 _device, int32 _object, const std::string & msg)
|
|
||||||
: std::runtime_error(msg), device(_device), object(_object) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct invalid_device: public invalid_target
|
|
||||||
{
|
|
||||||
invalid_device(int32 _device)
|
|
||||||
: invalid_target(_device, -1, STG(FMT("invalid device number '%d'") % _device)) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct invalid_channel: public invalid_target
|
|
||||||
{
|
|
||||||
invalid_channel(int32 _device, int32 _channel)
|
|
||||||
: invalid_target(_device, _channel, STG(FMT("invalid channel number '%d' on device '%d'") % _channel % _device)) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct invalid_link: public invalid_target
|
|
||||||
{
|
|
||||||
invalid_link(int32 _device, int32 _link)
|
|
||||||
: invalid_target(_device, _link, STG(FMT("invalid link number '%d' on device '%d'") % _link % _device)) {};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct K3LAPIBase
|
|
||||||
{
|
|
||||||
/* High level checked object identifier. */
|
|
||||||
|
|
||||||
struct GenericTarget
|
|
||||||
{
|
|
||||||
typedef enum { DEVICE, CHANNEL, MIXER, LINK } Type;
|
|
||||||
|
|
||||||
GenericTarget(const K3LAPIBase & k3lapi, Type _type, int32 _device, int32 _object)
|
|
||||||
: type(_type), device((unsigned int)_device), object((unsigned int)_object)
|
|
||||||
{
|
|
||||||
switch (_type)
|
|
||||||
{
|
|
||||||
case DEVICE:
|
|
||||||
if (!k3lapi.valid_device(_device))
|
|
||||||
throw K3LAPITraits::invalid_device(_device);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CHANNEL:
|
|
||||||
case MIXER:
|
|
||||||
if (!k3lapi.valid_channel(_device, _object))
|
|
||||||
throw K3LAPITraits::invalid_channel(_device, _object);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LINK:
|
|
||||||
if (!k3lapi.valid_link(_device, _object))
|
|
||||||
throw K3LAPITraits::invalid_link(_device, _object);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const Type type;
|
|
||||||
|
|
||||||
const unsigned int device;
|
|
||||||
const unsigned int object;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct LinkTarget : public GenericTarget
|
|
||||||
{
|
|
||||||
LinkTarget(const K3LAPIBase & k3lapi, int32 _device, int32 _object)
|
|
||||||
: GenericTarget(k3lapi, GenericTarget::LINK, _device, _object) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ChannelTarget : public GenericTarget
|
|
||||||
{
|
|
||||||
ChannelTarget(const K3LAPIBase & k3lapi, int32 _device, int32 _object)
|
|
||||||
: GenericTarget(k3lapi, GenericTarget::CHANNEL, _device, _object) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
*/
|
|
||||||
template < GenericTarget::Type T >
|
|
||||||
struct Target: public GenericTarget
|
|
||||||
{
|
|
||||||
Target(const K3LAPIBase & k3lapi, int32 _device, int32 _object)
|
|
||||||
: GenericTarget(k3lapi, T, _device, _object) {};
|
|
||||||
|
|
||||||
// operator const GenericTarget&() const { return static_cast<const GenericTarget &>(*this); };
|
|
||||||
};
|
|
||||||
|
|
||||||
/* exceptions */
|
|
||||||
|
|
||||||
struct start_failed: public std::runtime_error
|
|
||||||
{
|
|
||||||
start_failed(const char * msg)
|
|
||||||
: std::runtime_error(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 get_param_failed
|
|
||||||
{
|
|
||||||
get_param_failed(std::string _name, int32 _rc)
|
|
||||||
: name(_name), rc((KLibraryStatus)_rc) {};
|
|
||||||
|
|
||||||
std::string name;
|
|
||||||
KLibraryStatus rc;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* typedefs essenciais */
|
|
||||||
|
|
||||||
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 */
|
|
||||||
|
|
||||||
K3LAPIBase();
|
|
||||||
virtual ~K3LAPIBase() {};
|
|
||||||
|
|
||||||
/* (init|final)ialize the whole thing! */
|
|
||||||
|
|
||||||
void start(void);
|
|
||||||
void stop(void);
|
|
||||||
|
|
||||||
/* verificacao de intervalos */
|
|
||||||
|
|
||||||
inline bool valid_device(int32 dev) const
|
|
||||||
{
|
|
||||||
return (dev >= 0 && dev < ((int32)_device_count));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool valid_channel(int32 dev, int32 obj) const
|
|
||||||
{
|
|
||||||
return (valid_device(dev) && obj >= 0 && obj < ((int32)_channel_count[dev]));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool valid_link(int32 dev, int32 obj) const
|
|
||||||
{
|
|
||||||
return (valid_device(dev) && obj >= 0 && obj < ((int32)_link_count[dev]));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* envio de comandos para placa (geral) */
|
|
||||||
|
|
||||||
void raw_command(int32 dev, int32 dsp, std::string & str) const;
|
|
||||||
void raw_command(int32 dev, int32 dsp, const char * cmds, int32 size) const;
|
|
||||||
|
|
||||||
/* obter dados 'cacheados' (geral) */
|
|
||||||
|
|
||||||
inline unsigned int device_count(void) const
|
|
||||||
{
|
|
||||||
return _device_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* envio de comandos para placa (sem identificadores) */
|
|
||||||
|
|
||||||
void mixer(int32 dev, int32 obj, byte track, KMixerSource src, int32 index) const;
|
|
||||||
void mixerRecord(int32 dev, KDeviceType type, int32 obj, byte track, KMixerSource src, int32 index) const;
|
|
||||||
void mixerCTbus(int32 dev, int32 obj, byte track, KMixerSource src, int32 index) const;
|
|
||||||
|
|
||||||
void command (int32 dev, int32 obj, int32 code, std::string & str) const;
|
|
||||||
void command (int32 dev, int32 obj, int32 code, const char * parms = NULL) const;
|
|
||||||
|
|
||||||
|
|
||||||
/* envio de comandos para placa (com identificadores) */
|
|
||||||
|
|
||||||
void mixer(const GenericTarget & tgt, byte track, KMixerSource src, int32 index) const
|
|
||||||
{
|
|
||||||
mixer(tgt.device, tgt.object, track, src, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mixerRecord(const GenericTarget & tgt, byte track, KMixerSource src, int32 index) const
|
|
||||||
{
|
|
||||||
mixerRecord((int32)tgt.device, _device_type[tgt.device], (int32)tgt.object, track, src, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mixerCTbus(const GenericTarget & tgt, byte track, KMixerSource src, int32 index) const
|
|
||||||
{
|
|
||||||
mixerCTbus((int32)tgt.device, (int32)tgt.object, track, src, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void command(const GenericTarget & tgt, int32 code, std::string & str) const
|
|
||||||
{
|
|
||||||
command((int32)tgt.device, (int32)tgt.object, code, str);
|
|
||||||
};
|
|
||||||
|
|
||||||
void command(const GenericTarget & tgt, int32 code, const char * parms = NULL) const
|
|
||||||
{
|
|
||||||
command((int32)tgt.device, (int32)tgt.object, code, parms);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* obter dados 'cacheados' (com indentificadores) */
|
|
||||||
|
|
||||||
inline unsigned int channel_count(const GenericTarget & tgt) const
|
|
||||||
{
|
|
||||||
return _channel_count[tgt.device];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned int link_count(const GenericTarget & tgt) const
|
|
||||||
{
|
|
||||||
return _link_count[tgt.device];
|
|
||||||
}
|
|
||||||
|
|
||||||
KDeviceType device_type(const GenericTarget & tgt) const
|
|
||||||
{
|
|
||||||
return _device_type[tgt.device];
|
|
||||||
}
|
|
||||||
|
|
||||||
const K3L_DEVICE_CONFIG & device_config(const GenericTarget & tgt) const
|
|
||||||
{
|
|
||||||
return _device_config[tgt.device];
|
|
||||||
}
|
|
||||||
|
|
||||||
const K3L_CHANNEL_CONFIG & channel_config(const Target<GenericTarget::CHANNEL> & tgt) const
|
|
||||||
{
|
|
||||||
return _channel_config[tgt.device][tgt.object];
|
|
||||||
}
|
|
||||||
|
|
||||||
const K3L_LINK_CONFIG & link_config(const Target<GenericTarget::LINK> & tgt) const
|
|
||||||
{
|
|
||||||
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) const;
|
|
||||||
|
|
||||||
std::string get_param(K3L_EVENT *ev, const char *name) const;
|
|
||||||
std::string get_param_optional(K3L_EVENT *ev, const char *name) const;
|
|
||||||
|
|
||||||
/* inicializa valores em cache */
|
|
||||||
|
|
||||||
void init(void);
|
|
||||||
void fini(void);
|
|
||||||
|
|
||||||
/* utilidades diversas e informacoes */
|
|
||||||
|
|
||||||
enum DspType
|
|
||||||
{
|
|
||||||
DSP_AUDIO,
|
|
||||||
DSP_SIGNALING,
|
|
||||||
};
|
|
||||||
|
|
||||||
int32 get_dsp(KDeviceType, DspType) const;
|
|
||||||
|
|
||||||
int32 get_dsp(const GenericTarget &, DspType) const;
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* exceptions */
|
|
||||||
template < bool E = false >
|
|
||||||
struct K3LAPIException
|
|
||||||
{
|
|
||||||
void invalid_device(const int32 device) const
|
|
||||||
{
|
|
||||||
/* NOTHING */
|
|
||||||
}
|
|
||||||
|
|
||||||
void invalid_channel(const int32 device, const int32 channel) const
|
|
||||||
{
|
|
||||||
/* NOTHING */
|
|
||||||
}
|
|
||||||
|
|
||||||
void invalid_link(const int32 device, const int32 link) const
|
|
||||||
{
|
|
||||||
/* NOTHING */
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template < >
|
|
||||||
struct K3LAPIException < true >
|
|
||||||
{
|
|
||||||
void invalid_device(const int32 device) const
|
|
||||||
{
|
|
||||||
throw K3LAPITraits::invalid_device(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
void invalid_channel(const int32 device, const int32 channel) const
|
|
||||||
{
|
|
||||||
throw K3LAPITraits::invalid_channel(device, channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void invalid_link(const int32 device, const int32 link) const
|
|
||||||
{
|
|
||||||
throw K3LAPITraits::invalid_link(device, link);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template < bool E = false >
|
|
||||||
struct K3LAPITemplate: public K3LAPIBase, protected K3LAPIException < E >
|
|
||||||
{
|
|
||||||
using K3LAPIBase::device_config;
|
|
||||||
using K3LAPIBase::channel_config;
|
|
||||||
using K3LAPIBase::link_config;
|
|
||||||
|
|
||||||
using K3LAPIBase::device_type;
|
|
||||||
using K3LAPIBase::get_dsp;
|
|
||||||
|
|
||||||
using K3LAPIBase::mixerRecord;
|
|
||||||
|
|
||||||
/* obter dados 'cacheados' (sem identificadores) */
|
|
||||||
|
|
||||||
inline unsigned int channel_count(int32 dev) const
|
|
||||||
{
|
|
||||||
if (!valid_device(dev))
|
|
||||||
{
|
|
||||||
K3LAPIException< E >::invalid_device(dev);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _channel_count[dev];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned int link_count(int32 dev) const
|
|
||||||
{
|
|
||||||
if (!valid_device(dev))
|
|
||||||
{
|
|
||||||
K3LAPIException< E >::invalid_device(dev);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _link_count[dev];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint32 channel_stats(int32 dev, int32 obj, uint32 index) const
|
|
||||||
{
|
|
||||||
if (!valid_channel(dev, obj))
|
|
||||||
{
|
|
||||||
K3LAPIException< E >::invalid_channel(dev, obj);
|
|
||||||
return 0u;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 res_value = 0u;
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(2,1,0)
|
|
||||||
if (k3lGetChannelStats(dev, obj, index, &res_value) != ksSuccess)
|
|
||||||
return 0u;
|
|
||||||
|
|
||||||
return res_value;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
KDeviceType device_type(int32 dev) const
|
|
||||||
{
|
|
||||||
if (!valid_device(dev))
|
|
||||||
{
|
|
||||||
K3LAPIException< E >::invalid_device(dev);
|
|
||||||
return kdtDevTypeCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _device_type[dev];
|
|
||||||
}
|
|
||||||
|
|
||||||
const K3L_DEVICE_CONFIG & device_config(int32 dev) const
|
|
||||||
{
|
|
||||||
if (!valid_device(dev))
|
|
||||||
throw K3LAPITraits::invalid_device(dev);
|
|
||||||
|
|
||||||
return _device_config[dev];
|
|
||||||
}
|
|
||||||
|
|
||||||
const K3L_CHANNEL_CONFIG & channel_config(int32 dev, int32 obj) const
|
|
||||||
{
|
|
||||||
if (!valid_channel(dev, obj))
|
|
||||||
throw K3LAPITraits::invalid_channel(dev, obj);
|
|
||||||
|
|
||||||
return _channel_config[dev][obj];
|
|
||||||
}
|
|
||||||
|
|
||||||
const K3L_LINK_CONFIG & link_config(int32 dev, int32 obj) const
|
|
||||||
{
|
|
||||||
if (!valid_link(dev, obj))
|
|
||||||
throw K3LAPITraits::invalid_link(dev, obj);
|
|
||||||
|
|
||||||
return _link_config[dev][obj];
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 get_dsp(int32 dev, DspType type) const
|
|
||||||
{
|
|
||||||
return get_dsp(device_type(dev), type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mixerRecord(int32 dev, int32 obj, byte track, KMixerSource src, int32 index) const
|
|
||||||
{
|
|
||||||
mixerRecord(dev, device_type(dev), obj, track, src, index);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef K3LAPITemplate<> K3LAPI;
|
|
||||||
|
|
||||||
#endif /* _K3LAPI_HPP_ */
|
|
|
@ -1,206 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <k3lutil.hpp>
|
|
||||||
|
|
||||||
std::string K3LUtil::channelStatus(int32 dev, int32 channel,
|
|
||||||
Verbose::Presentation fmt)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
const K3L_CHANNEL_CONFIG & config = _k3lapi.channel_config(dev, channel);
|
|
||||||
|
|
||||||
K3L_CHANNEL_STATUS status;
|
|
||||||
|
|
||||||
KLibraryStatus ret = (KLibraryStatus) k3lGetDeviceStatus (dev,
|
|
||||||
channel + ksoChannel, &status, sizeof(status));
|
|
||||||
|
|
||||||
switch (ret)
|
|
||||||
{
|
|
||||||
case ksSuccess: return Verbose::channelStatus(config.Signaling,
|
|
||||||
status.AddInfo, fmt);
|
|
||||||
default: return (fmt == Verbose::EXACT ? "<unknown[fail]>"
|
|
||||||
: "Unknown (fail)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(K3LAPITraits::invalid_channel & e)
|
|
||||||
{
|
|
||||||
return (fmt == Verbose::EXACT ? "<unknown[fail]>" : "Unknown (fail)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string K3LUtil::callStatus(int32 dev, int32 channel,
|
|
||||||
Verbose::Presentation fmt)
|
|
||||||
{
|
|
||||||
K3L_CHANNEL_STATUS status;
|
|
||||||
|
|
||||||
KLibraryStatus ret = (KLibraryStatus) k3lGetDeviceStatus(dev,
|
|
||||||
channel + ksoChannel, &status, sizeof(status));
|
|
||||||
|
|
||||||
switch (ret)
|
|
||||||
{
|
|
||||||
case ksSuccess: return Verbose::callStatus(status.CallStatus, fmt);
|
|
||||||
default: return (fmt == Verbose::EXACT ? "<unknown[fail]>"
|
|
||||||
: "Unknown (fail)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string K3LUtil::linkStatus(int32 dev, int32 link,
|
|
||||||
Verbose::Presentation fmt, KSignaling signaling, bool simpleStatus)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (signaling == ksigInactive)
|
|
||||||
{
|
|
||||||
const K3L_LINK_CONFIG & config = _k3lapi.link_config(dev, link);
|
|
||||||
signaling = config.Signaling;
|
|
||||||
}
|
|
||||||
|
|
||||||
K3L_LINK_STATUS status;
|
|
||||||
|
|
||||||
KLibraryStatus ret = (KLibraryStatus) k3lGetDeviceStatus (dev,
|
|
||||||
link + ksoLink, &status, sizeof(status));
|
|
||||||
|
|
||||||
switch (ret)
|
|
||||||
{
|
|
||||||
case ksSuccess: return Verbose::linkStatus(signaling, status.E1, fmt, simpleStatus);
|
|
||||||
default: return (fmt == Verbose::EXACT ?
|
|
||||||
"<unknown[failure]>" : "Unknown (failure)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(K3LAPITraits::invalid_channel & e)
|
|
||||||
{
|
|
||||||
return (fmt == Verbose::EXACT ? "<unknown[failure]>"
|
|
||||||
: "Unknown (failure)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int K3LUtil::physicalLinkCount(int32 dev, bool count_virtual)
|
|
||||||
{
|
|
||||||
unsigned int number = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
switch (_k3lapi.device_type(dev))
|
|
||||||
{
|
|
||||||
#if K3L_AT_LEAST(1,6,0)
|
|
||||||
case kdtFXS:
|
|
||||||
number = (count_virtual ? (_k3lapi.channel_count(dev) < 50 ? 1 : 2) : 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kdtFXSSpx:
|
|
||||||
number = (count_virtual ? (_k3lapi.channel_count(dev) < 30 ? 1 : 2) : 0);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(2,1,0)
|
|
||||||
case kdtE1FXSSpx:
|
|
||||||
number = (count_virtual ? 2 : 1);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* E1 boards */
|
|
||||||
case kdtE1:
|
|
||||||
case kdtE1Spx:
|
|
||||||
case kdtE1IP:
|
|
||||||
number = _k3lapi.link_count(dev);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kdtPR:
|
|
||||||
case kdtE1GW:
|
|
||||||
number = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(1,6,0)
|
|
||||||
case kdtFXO:
|
|
||||||
case kdtFXOVoIP:
|
|
||||||
case kdtGSM:
|
|
||||||
case kdtGSMSpx:
|
|
||||||
#else
|
|
||||||
case kdtFX:
|
|
||||||
case kdtFXVoIP:
|
|
||||||
#endif
|
|
||||||
case kdtConf:
|
|
||||||
case kdtGWIP:
|
|
||||||
#if K3L_AT_LEAST(2,1,0)
|
|
||||||
case kdtGSMUSB:
|
|
||||||
case kdtGSMUSBSpx:
|
|
||||||
case kdtReserved1: // just to avoid warnings.
|
|
||||||
case kdtDevTypeCount: // just to avoid warnings.
|
|
||||||
#endif
|
|
||||||
number = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(K3LAPITraits::invalid_device & e)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return number;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
K3LUtil::ErrorCountType K3LUtil::linkErrorCount(int32 dev, int32 link,
|
|
||||||
Verbose::Presentation fmt)
|
|
||||||
{
|
|
||||||
ErrorCountType result;
|
|
||||||
K3L_LINK_ERROR_COUNTER status;
|
|
||||||
|
|
||||||
KLibraryStatus ret = (KLibraryStatus) k3lGetDeviceStatus (dev,
|
|
||||||
link + ksoLinkMon, &status, sizeof(status));
|
|
||||||
|
|
||||||
switch (ret)
|
|
||||||
{
|
|
||||||
case ksSuccess:
|
|
||||||
for (unsigned int i = klecChangesToLock; i < klecCount; i++)
|
|
||||||
{
|
|
||||||
result.push_back(ErrorCountPairType(Verbose::linkErrorCounter
|
|
||||||
((KLinkErrorCounter)i, fmt), status.ErrorCounters[i]));
|
|
||||||
}
|
|
||||||
/* fall */
|
|
||||||
|
|
||||||
default:
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
#include <k3lapi.hpp>
|
|
||||||
#include <verbose.hpp>
|
|
||||||
|
|
||||||
#ifndef _K3LUTIL_HPP_
|
|
||||||
#define _K3LUTIL_HPP_
|
|
||||||
|
|
||||||
struct K3LUtil
|
|
||||||
{
|
|
||||||
typedef std::pair < std::string, unsigned int > ErrorCountPairType;
|
|
||||||
typedef std::list < ErrorCountPairType > ErrorCountType;
|
|
||||||
|
|
||||||
K3LUtil(K3LAPI & k3lapi): _k3lapi(k3lapi) {};
|
|
||||||
|
|
||||||
std::string callStatus(int32 dev, int32 channel,
|
|
||||||
Verbose::Presentation fmt = Verbose::HUMAN);
|
|
||||||
|
|
||||||
std::string channelStatus(int32, int32,
|
|
||||||
Verbose::Presentation fmt = Verbose::HUMAN);
|
|
||||||
|
|
||||||
std::string linkStatus(int32, int32,
|
|
||||||
Verbose::Presentation fmt = Verbose::HUMAN,
|
|
||||||
KSignaling sig = ksigInactive,
|
|
||||||
bool simpleStatus = false);
|
|
||||||
|
|
||||||
unsigned int physicalLinkCount(int32 dev, bool count_virtual = false);
|
|
||||||
|
|
||||||
ErrorCountType linkErrorCount(int32, int32,
|
|
||||||
Verbose::Presentation fmt = Verbose::HUMAN);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
K3LAPI & _k3lapi;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _K3LUTIL_HPP_ */
|
|
||||||
|
|
|
@ -1,557 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <tagged_union.hpp>
|
|
||||||
#include <format.hpp>
|
|
||||||
#include <refcounter.hpp>
|
|
||||||
#include <flagger.hpp>
|
|
||||||
|
|
||||||
#if defined(COMMONS_LIBRARY_USING_ASTERISK) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#include <time.h>
|
|
||||||
}
|
|
||||||
#elif defined(COMMONS_LIBRARY_USING_CALLWEAVER)
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#include <callweaver/localtime.h>
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
|
|
||||||
********************************************************************************
|
|
||||||
***************************** 'Logger' user manual *****************************
|
|
||||||
********************************************************************************
|
|
||||||
|
|
||||||
* Description:
|
|
||||||
|
|
||||||
This class does the management of log messages for applications. It works with
|
|
||||||
the following axioms:
|
|
||||||
|
|
||||||
<*> There are several class of messages.
|
|
||||||
<*> There are some outputs, which may be files, sockets, or a console device.
|
|
||||||
<*> There are options for classes, for outputs and for the association of both.
|
|
||||||
|
|
||||||
The last rule also shows the order in which options are processed: first the
|
|
||||||
'classes' options are processed, then 'output' options are processed, and then
|
|
||||||
the options for the tuple '(class, output)' are processed.
|
|
||||||
|
|
||||||
The options are mapped like this:
|
|
||||||
|
|
||||||
<class-of-message> -> options [prefix, flags]
|
|
||||||
<output-sink> -> options [prefix]
|
|
||||||
( <class-of-message>, <output-sink> ) -> options [prefix, flags]
|
|
||||||
|
|
||||||
- "prefix" means a fixed string prefix before the real message.
|
|
||||||
- "flags" means auxiliary flags (DATETIME, THREADID) which are
|
|
||||||
used to add information based on OS or process context info.
|
|
||||||
|
|
||||||
* Example of use:
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
C_DBG_FUNC,
|
|
||||||
C_DBG_LOCK,
|
|
||||||
C_WARNING,
|
|
||||||
C_ERROR,
|
|
||||||
C_CLI,
|
|
||||||
}
|
|
||||||
AstClassId;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
F_CONSOLE,
|
|
||||||
F_GENERIC,
|
|
||||||
F_TRACE,
|
|
||||||
}
|
|
||||||
AstOutputId;
|
|
||||||
|
|
||||||
// used to indicate the console log //
|
|
||||||
struct AstConsoleLog {};
|
|
||||||
|
|
||||||
struct AstPrinter: public Logger::DefaultPrinter
|
|
||||||
{
|
|
||||||
typedef Logger::DefaultPrinter Super;
|
|
||||||
|
|
||||||
using namespace Tagged;
|
|
||||||
|
|
||||||
using Super::operator()(int);
|
|
||||||
|
|
||||||
// just 2 type of descriptors //
|
|
||||||
typedef Union < int, Union < AstConsoleLog > > Container;
|
|
||||||
|
|
||||||
ast_printer(std::string & msg): Super(msg) {};
|
|
||||||
|
|
||||||
bool operator()(const AstConsoleLog & log)
|
|
||||||
{
|
|
||||||
ast_console_puts(_msg.c_str());
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
bool operator()(int log)
|
|
||||||
{
|
|
||||||
return Super::operator()(log);
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
bool start_log()
|
|
||||||
{
|
|
||||||
typedef Logger::Manager<AstClassId, AstOutputId, AstPrinter, SimpleLock> LogManager;
|
|
||||||
|
|
||||||
LogManager logger;
|
|
||||||
|
|
||||||
// shortcut definition //
|
|
||||||
typedef LogManager::Option LogOption;
|
|
||||||
|
|
||||||
FILE * log_file = fopen( "output.log", "a");
|
|
||||||
|
|
||||||
if (!log_file)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
logger.add( F_CONSOLE, AstConsoleLog(), "chan_khomp: ");
|
|
||||||
logger.add( F_GENERIC, log_file);
|
|
||||||
|
|
||||||
logger.classe( C_WARNING )
|
|
||||||
& LogOption(F_CONSOLE, "WARNING: ", LogOption::Flags(LogOption::Flag(LogOption::DATETIME)))
|
|
||||||
& LogOption(F_GENERIC, "W: ", LogOption::Flags(LogOption::Flag(LogOption::DATETIME)))
|
|
||||||
|
|
||||||
logger.classe( C_DBG_LOCK ).enabled(false);
|
|
||||||
|
|
||||||
logger.classe( C_DBG_LOCK )
|
|
||||||
& LogOption(F_GENERIC, "L: ", LogOption::Flags
|
|
||||||
(LogOption::flag_type(LogOption::ENABLED) &
|
|
||||||
LogOption::flag_type(LogOption::DATETIME))
|
|
||||||
|
|
||||||
logger(C_WARNING, "eu sou uma mensagem de warning");
|
|
||||||
|
|
||||||
logger.classe(C_WARNING).set(F_GENERIC, LogOption::ENABLED, true);
|
|
||||||
logger.classe(C_WARNING).set(F_CONSOLE, LogOption::ENABLED, false);
|
|
||||||
|
|
||||||
logger.classe(C_CLI).prefix("<K>");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void message_the_user(int fd)
|
|
||||||
{
|
|
||||||
logger(C_CLI, fd, "eu sou uma mensagem de cli!");
|
|
||||||
logger(C_WARNING, "eu sou um warning");
|
|
||||||
}
|
|
||||||
|
|
||||||
********************************************************************************
|
|
||||||
********************************************************************************
|
|
||||||
|
|
||||||
Now, the code..!
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LOGGER_HPP_
|
|
||||||
#define _LOGGER_HPP_
|
|
||||||
|
|
||||||
#include <tagged_union.hpp>
|
|
||||||
|
|
||||||
struct Logger
|
|
||||||
{
|
|
||||||
/*** a base struct for printing messages in many ways ***/
|
|
||||||
|
|
||||||
struct DefaultPrinter
|
|
||||||
{
|
|
||||||
typedef Tagged::Union < int, Tagged::Union < FILE *, Tagged::Union < std::ostream * > > > BaseType;
|
|
||||||
|
|
||||||
typedef bool ReturnType;
|
|
||||||
|
|
||||||
DefaultPrinter(std::string & msg): _msg(msg) {};
|
|
||||||
|
|
||||||
bool operator()(std::ostream * out)
|
|
||||||
{
|
|
||||||
(*out) << _msg;
|
|
||||||
out->flush();
|
|
||||||
|
|
||||||
return out->good();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(FILE * out)
|
|
||||||
{
|
|
||||||
if (fputs(_msg.c_str(), out) < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (fflush(out) < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(int out)
|
|
||||||
{
|
|
||||||
#ifndef KWIN32
|
|
||||||
return (write(out, _msg.c_str(), _msg.size()) == (int)_msg.size());
|
|
||||||
#else
|
|
||||||
// no need for file descriptors on windows
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string & msg() { return _msg; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string & _msg;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*** manage the printing of messages ***/
|
|
||||||
|
|
||||||
template <class ClassId, class OutputId, class Printer, class LockType>
|
|
||||||
struct Manager
|
|
||||||
{
|
|
||||||
typedef typename Printer::BaseType BaseType;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/* holds a stream, and an optimal message prefix */
|
|
||||||
struct OutputOptions
|
|
||||||
{
|
|
||||||
OutputOptions(BaseType & stream, std::string & prefix)
|
|
||||||
: _stream(stream), _prefix(prefix) {};
|
|
||||||
|
|
||||||
BaseType _stream;
|
|
||||||
std::string _prefix;
|
|
||||||
LockType _lock;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::map < OutputId, OutputOptions > OutputMap;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/* print in a specific 'message class' */
|
|
||||||
struct ClassType
|
|
||||||
{
|
|
||||||
ClassType(void)
|
|
||||||
: _enabled(true)
|
|
||||||
{};
|
|
||||||
|
|
||||||
// ClassType(ClassType & o)
|
|
||||||
// : _stream_map(o._stream_map), _prefix(o.prefix),
|
|
||||||
// _lock(o._lock),_enabled(o._enabled)
|
|
||||||
// {};
|
|
||||||
|
|
||||||
/* initializes the options of the (class, stream) pair */
|
|
||||||
struct Option
|
|
||||||
{
|
|
||||||
typedef enum { ENABLED, DATETIME, THREADID, DATETIMEMS } EnumType;
|
|
||||||
|
|
||||||
typedef Flagger< EnumType > Flags;
|
|
||||||
typedef typename Flags::InitFlags InitFlags;
|
|
||||||
|
|
||||||
Option(OutputId output, const char * prefix,
|
|
||||||
Flags flags = InitFlags(ENABLED))
|
|
||||||
: _output(output), _prefix(prefix), _flags(flags) {};
|
|
||||||
|
|
||||||
Option(OutputId output, std::string prefix,
|
|
||||||
Flags flags = InitFlags(ENABLED))
|
|
||||||
: _output(output), _prefix(prefix), _flags(flags) {};
|
|
||||||
|
|
||||||
Option(OutputId output,
|
|
||||||
Flags flags = InitFlags(ENABLED))
|
|
||||||
: _output(output), _flags(flags) {};
|
|
||||||
|
|
||||||
OutputId _output;
|
|
||||||
std::string _prefix;
|
|
||||||
Flags _flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/* holds a prefix and a activation status */
|
|
||||||
struct OptionContainer
|
|
||||||
{
|
|
||||||
OptionContainer(std::string prefix, typename Option::Flags flags)
|
|
||||||
: _prefix(prefix), _flags(flags) {};
|
|
||||||
|
|
||||||
std::string _prefix;
|
|
||||||
typename Option::Flags _flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::multimap < OutputId, OptionContainer > OptionMap;
|
|
||||||
|
|
||||||
/* utility function for printing */
|
|
||||||
bool print(std::string & msg, BaseType & stream, LockType & lock)
|
|
||||||
{
|
|
||||||
lock.lock();
|
|
||||||
|
|
||||||
Printer p(msg);
|
|
||||||
bool ret = stream.visit(p);
|
|
||||||
|
|
||||||
lock.unlock();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
bool print(std::string & msg, BaseType & stream, LockType & lock)
|
|
||||||
{
|
|
||||||
lock.lock();
|
|
||||||
|
|
||||||
Printer p(msg);
|
|
||||||
bool ret = stream.visit(p);
|
|
||||||
|
|
||||||
lock.unlock();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
public:
|
|
||||||
ClassType & operator&(const Option & value)
|
|
||||||
{
|
|
||||||
add(value._output, value._prefix, value._flags);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add(OutputId output_id, std::string prefix,
|
|
||||||
typename Option::Flags flags)
|
|
||||||
{
|
|
||||||
typedef std::pair < OutputId, OptionContainer > pair_type;
|
|
||||||
_stream_map.insert(pair_type(output_id, OptionContainer(prefix, flags)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get and set methods for active mode */
|
|
||||||
void set(OutputId id, typename Option::EnumType flag, bool value = true)
|
|
||||||
{
|
|
||||||
typename OptionMap::iterator iter = _stream_map.find(id);
|
|
||||||
|
|
||||||
if (iter == _stream_map.end())
|
|
||||||
return;
|
|
||||||
|
|
||||||
(*iter).second._flags.set(flag, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get(OutputId idx, typename Option::EnumType flag)
|
|
||||||
{
|
|
||||||
typename OptionMap::iterator iter = _stream_map.find(idx);
|
|
||||||
|
|
||||||
if (iter == _stream_map.end())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return (*iter).second._flags.is_set(flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get/adjust the enable/disable value for the class */
|
|
||||||
void enabled(bool enabled) { _enabled = enabled; };
|
|
||||||
bool enabled() { return _enabled; };
|
|
||||||
|
|
||||||
/* get/adjust the classe prefix */
|
|
||||||
void prefix(const char * prefix) { _prefix = prefix; }
|
|
||||||
void prefix(std::string & prefix) { _prefix = prefix; }
|
|
||||||
std::string & prefix() { return _prefix; }
|
|
||||||
|
|
||||||
/* printing function (operator, actually) */
|
|
||||||
bool operator()(OutputMap & out_map, std::string & msg)
|
|
||||||
{
|
|
||||||
if (!_enabled)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
typedef typename OptionMap::iterator Iter;
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
for (Iter iter = _stream_map.begin(); iter != _stream_map.end(); iter++)
|
|
||||||
{
|
|
||||||
OptionContainer & opt = (*iter).second;
|
|
||||||
|
|
||||||
if (!opt._flags[Option::ENABLED])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
typename OutputMap::iterator out_iter = out_map.find((*iter).first);
|
|
||||||
|
|
||||||
/* this stream have been added already? if not, skip! */
|
|
||||||
if (out_iter == out_map.end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* final message */
|
|
||||||
std::string out_msg;
|
|
||||||
|
|
||||||
if (opt._flags[Option::DATETIME])
|
|
||||||
{
|
|
||||||
#if defined(COMMONS_LIBRARY_USING_ASTERISK) || defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
|
|
||||||
time_t tv;
|
|
||||||
struct tm lt;
|
|
||||||
|
|
||||||
time (&tv);
|
|
||||||
localtime_r (&tv, <);
|
|
||||||
|
|
||||||
out_msg += STG(FMT("[%02d-%02d-%02d %02d:%02d:%02d] ")
|
|
||||||
% (lt.tm_year % 100) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour
|
|
||||||
% lt.tm_min % lt.tm_sec);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opt._flags[Option::DATETIMEMS])
|
|
||||||
{
|
|
||||||
#if defined(COMMONS_LIBRARY_USING_ASTERISK) || defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
|
|
||||||
time_t tv;
|
|
||||||
struct tm lt;
|
|
||||||
|
|
||||||
time (&tv);
|
|
||||||
localtime_r (&tv, <);
|
|
||||||
|
|
||||||
out_msg += STG(FMT("[%02d-%02d-%02d %02d:%02d:%02d:%04d] ")
|
|
||||||
% (lt.tm_year % 100) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour % lt.tm_min
|
|
||||||
% lt.tm_sec % (tv * 1000));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
OutputOptions & out_opt = (*out_iter).second;
|
|
||||||
|
|
||||||
if (opt._flags[Option::THREADID])
|
|
||||||
{
|
|
||||||
#if defined (COMMONS_LIBRARY_USING_ASTERISK) || defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
|
|
||||||
out_msg += STG(FMT("%08x ") % ((unsigned long)pthread_self()));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
out_msg += _prefix;
|
|
||||||
out_msg += out_opt._prefix;
|
|
||||||
out_msg += opt._prefix;
|
|
||||||
out_msg += msg;
|
|
||||||
out_msg += "\n";
|
|
||||||
|
|
||||||
ret |= print(out_msg, out_opt._stream, out_opt._lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(BaseType & stream, std::string & msg)
|
|
||||||
{
|
|
||||||
std::string final_msg;
|
|
||||||
|
|
||||||
final_msg += _prefix;
|
|
||||||
final_msg += msg;
|
|
||||||
final_msg += "\n";
|
|
||||||
|
|
||||||
return print(final_msg, stream, _lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
OptionMap _stream_map;
|
|
||||||
std::string _prefix;
|
|
||||||
LockType _lock;
|
|
||||||
bool _enabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* util declaration */
|
|
||||||
typedef typename ClassType::Option Option;
|
|
||||||
|
|
||||||
/* class_id_type -> ClassType mapper */
|
|
||||||
typedef std::map < ClassId, ClassType > ClassMap;
|
|
||||||
|
|
||||||
/* local option pair */
|
|
||||||
typedef std::pair < OutputId, OutputOptions > OutputOptionPair;
|
|
||||||
|
|
||||||
void add(OutputId output, BaseType stream, const char * prefix = "")
|
|
||||||
{
|
|
||||||
std::string str_prefix(prefix);
|
|
||||||
|
|
||||||
_output_map.insert(OutputOptionPair(output, OutputOptions(stream, str_prefix)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void add(OutputId output, BaseType stream, std::string prefix)
|
|
||||||
{
|
|
||||||
_output_map.insert(OutputOptionPair(output, OutputOptions(stream, prefix)));
|
|
||||||
}
|
|
||||||
|
|
||||||
ClassType & classe(ClassId classeid)
|
|
||||||
{
|
|
||||||
return _classe_map[classeid];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(ClassId classeid, const char * msg)
|
|
||||||
{
|
|
||||||
std::string str_msg(msg);
|
|
||||||
return _classe_map[classeid](_output_map, str_msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(ClassId classeid, std::string & msg)
|
|
||||||
{
|
|
||||||
return _classe_map[classeid](_output_map, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(ClassId classeid, Format fmt)
|
|
||||||
{
|
|
||||||
std::string str_fmt = STG(fmt);
|
|
||||||
return _classe_map[classeid](_output_map, str_fmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(ClassId classeid, BaseType stream, const char * msg)
|
|
||||||
{
|
|
||||||
std::string str_msg(msg);
|
|
||||||
return _classe_map[classeid](stream, str_msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(ClassId classeid, BaseType stream, std::string & msg)
|
|
||||||
{
|
|
||||||
return _classe_map[classeid](stream, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(ClassId classeid, BaseType stream, Format fmt)
|
|
||||||
{
|
|
||||||
std::string str_fmt = STG(fmt);
|
|
||||||
return _classe_map[classeid](stream, str_fmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ClassMap _classe_map;
|
|
||||||
OutputMap _output_map;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
Logger();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _LOGGER_HPP_ */
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NONCOPYABLE_HPP_
|
|
||||||
#define _NONCOPYABLE_HPP_
|
|
||||||
|
|
||||||
struct NonCopyable
|
|
||||||
{
|
|
||||||
NonCopyable() {};
|
|
||||||
private:
|
|
||||||
NonCopyable(NonCopyable const &) { };
|
|
||||||
NonCopyable & operator=(NonCopyable const &) { return *this; };
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _NONCOPYABLE_HPP_ */
|
|
||||||
|
|
|
@ -1,268 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the "LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* This struct uses static polymorphism, and derived classes should implement *
|
|
||||||
* the "unreference()" method, which should release all resources when called */
|
|
||||||
|
|
||||||
#ifndef _REFCOUNTER_HPP_
|
|
||||||
#define _REFCOUNTER_HPP_
|
|
||||||
|
|
||||||
#define COUNTER_CLASS(...) ReferenceCounter< __VA_ARGS__ >
|
|
||||||
#define COUNTER_SUPER(...) public COUNTER_CLASS( __VA_ARGS__ )
|
|
||||||
#define COUNTER_REFER(o, ...) COUNTER_CLASS( __VA_ARGS__ )(static_cast< const COUNTER_CLASS( __VA_ARGS__ ) & >(o))
|
|
||||||
|
|
||||||
// DEPRECATED DECLARATIONS ///
|
|
||||||
#define NEW_REFCOUNTER(...) public ReferenceCounter< __VA_ARGS__ >
|
|
||||||
#define INC_REFCOUNTER(o, ...) ReferenceCounter< __VA_ARGS__ >(static_cast< const ReferenceCounter < __VA_ARGS__ > & >(o))
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <noncopyable.hpp>
|
|
||||||
#include <atomic.hpp>
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
# include <iostream>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct ReferenceData: public NonCopyable
|
|
||||||
{
|
|
||||||
ReferenceData()
|
|
||||||
: _data_count(1)
|
|
||||||
{};
|
|
||||||
|
|
||||||
inline unsigned int increment(void)
|
|
||||||
{
|
|
||||||
if (!_data_count)
|
|
||||||
abort();
|
|
||||||
|
|
||||||
Atomic::doAdd(&_data_count);
|
|
||||||
|
|
||||||
return _data_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned int decrement(void)
|
|
||||||
{
|
|
||||||
if (!_data_count)
|
|
||||||
abort();
|
|
||||||
|
|
||||||
Atomic::doSub(&_data_count);
|
|
||||||
return _data_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
volatile unsigned int _data_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
struct ReferenceCounter
|
|
||||||
{
|
|
||||||
typedef T Type;
|
|
||||||
|
|
||||||
ReferenceCounter(bool create_counter = true)
|
|
||||||
: _reference_count(0)
|
|
||||||
{
|
|
||||||
reference_restart(create_counter);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
std::cerr << ((void*)this) << ": ReferenceCounter() [ref_count="
|
|
||||||
<< (_reference_count ? (*_reference_count) : -1) << "]" << std::endl;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
ReferenceCounter(const ReferenceCounter & o)
|
|
||||||
: _reference_count(0)
|
|
||||||
{
|
|
||||||
reference_reflect(o);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
std::cerr << ((void*)this) << ": ReferenceCounter(" << ((void*)(&o)) << ") [ref_count="
|
|
||||||
<< (_reference_count ? (*_reference_count) : -1) << "]" << std::endl;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~ReferenceCounter()
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
std::cerr << ((void*)this) << ": ~ReferenceCounter() [ref_count="
|
|
||||||
<< (_reference_count ? (*_reference_count) : -1) << "]" << std::endl;
|
|
||||||
#endif
|
|
||||||
reference_disconnect(_reference_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReferenceCounter & operator=(const ReferenceCounter & o)
|
|
||||||
{
|
|
||||||
reference_reflect(o);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
std::cerr << ((void*)this) << ": ReferenceCounter::operator=(" << ((void*)(&o)) << ") [ref_count="
|
|
||||||
<< (_reference_count ? (*_reference_count) : -1) << "]" << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
inline void reference_restart(bool create_counter = false)
|
|
||||||
{
|
|
||||||
ReferenceData * oldref = _reference_count;
|
|
||||||
|
|
||||||
_reference_count = (create_counter ? new ReferenceData() : 0);
|
|
||||||
|
|
||||||
if (oldref) reference_disconnect(oldref);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void reference_reflect(const ReferenceCounter & other)
|
|
||||||
{
|
|
||||||
ReferenceData * newref = other._reference_count;
|
|
||||||
ReferenceData * oldref = _reference_count;
|
|
||||||
|
|
||||||
/* NOTE: increment before, avoid our reference being zero, even *
|
|
||||||
* for a short period of time. */
|
|
||||||
|
|
||||||
if (newref) newref->increment();
|
|
||||||
|
|
||||||
_reference_count = newref;
|
|
||||||
|
|
||||||
if (oldref) reference_disconnect(oldref);
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void reference_disconnect(ReferenceData *& counter)
|
|
||||||
{
|
|
||||||
if (counter)
|
|
||||||
{
|
|
||||||
unsigned int result = counter->decrement();
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
static_cast< Type * >(this)->unreference();
|
|
||||||
delete counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
counter = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
ReferenceData * _reference_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
struct ReferenceContainer: COUNTER_SUPER(ReferenceContainer< T >)
|
|
||||||
{
|
|
||||||
/* type */
|
|
||||||
typedef T Type;
|
|
||||||
|
|
||||||
/* shorthand */
|
|
||||||
typedef COUNTER_CLASS(ReferenceContainer< Type >) Counter;
|
|
||||||
|
|
||||||
// TODO: make this a generic exception someday
|
|
||||||
struct NotFound {};
|
|
||||||
|
|
||||||
ReferenceContainer()
|
|
||||||
: Counter(false),
|
|
||||||
_reference_value(0)
|
|
||||||
{};
|
|
||||||
|
|
||||||
ReferenceContainer(Type * value)
|
|
||||||
: _reference_value(value)
|
|
||||||
{};
|
|
||||||
|
|
||||||
ReferenceContainer(const ReferenceContainer & value)
|
|
||||||
: Counter(false),
|
|
||||||
_reference_value(0)
|
|
||||||
{
|
|
||||||
operator()(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~ReferenceContainer()
|
|
||||||
{};
|
|
||||||
|
|
||||||
ReferenceContainer operator=(const ReferenceContainer & value)
|
|
||||||
{
|
|
||||||
operator()(value);
|
|
||||||
return *this;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**/
|
|
||||||
|
|
||||||
void unreference()
|
|
||||||
{
|
|
||||||
if (_reference_value)
|
|
||||||
{
|
|
||||||
delete _reference_value;
|
|
||||||
_reference_value = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// simulates a copy constructor
|
|
||||||
void operator()(const ReferenceContainer & value)
|
|
||||||
{
|
|
||||||
Counter::reference_reflect(value);
|
|
||||||
|
|
||||||
_reference_value = const_cast<Type *>(value._reference_value);
|
|
||||||
};
|
|
||||||
|
|
||||||
// shortcut for operator below
|
|
||||||
void operator=(const Type * value)
|
|
||||||
{
|
|
||||||
operator()(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
// accept value (pointer)!
|
|
||||||
void operator()(const Type * value)
|
|
||||||
{
|
|
||||||
Counter::reference_restart((value != 0));
|
|
||||||
|
|
||||||
_reference_value = const_cast<Type *>(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
// return value (pointer)!
|
|
||||||
Type * operator()(void) const
|
|
||||||
{
|
|
||||||
return _reference_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Type * _reference_value;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _REFCOUNTER_HPP_ */
|
|
|
@ -1,149 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <regex.hpp>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
void Regex::Expression::initialize(void)
|
|
||||||
{
|
|
||||||
unsigned int tmplen = strlen(_expression);
|
|
||||||
|
|
||||||
bool extflag = (_flags & E_EXTENDED);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < tmplen; ++i)
|
|
||||||
{
|
|
||||||
switch (_expression[i])
|
|
||||||
{
|
|
||||||
case '\\':
|
|
||||||
++i;
|
|
||||||
|
|
||||||
if (!extflag && i < tmplen)
|
|
||||||
if (_expression[i] == '(')
|
|
||||||
++_subcounter;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '(':
|
|
||||||
if (extflag)
|
|
||||||
++_subcounter;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_errorstate = regcomp(&_comp_regex, _expression, _flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Regex::Expression::regerror_as_string(void) const
|
|
||||||
{
|
|
||||||
unsigned int count = regerror(_errorstate, &_comp_regex, 0, 0) + 1;
|
|
||||||
|
|
||||||
char * msg = new char[count];
|
|
||||||
|
|
||||||
regerror(_errorstate, &_comp_regex, msg, count);
|
|
||||||
|
|
||||||
std::string tmp(msg, count);
|
|
||||||
|
|
||||||
delete[] msg;
|
|
||||||
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Regex::Match::initialize(void)
|
|
||||||
{
|
|
||||||
if (_expression.valid())
|
|
||||||
{
|
|
||||||
_subcounter = (_expression.subcount() + 2); // 0 + N.. + invalid
|
|
||||||
_submatches = new regmatch_t[_subcounter];
|
|
||||||
_subcaching = new std::string[_subcounter];
|
|
||||||
_have_match = (regexec(_expression.repr(), _basestring.c_str(),
|
|
||||||
_subcounter, _submatches, _flags) == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Regex::Match::replace(std::string rep, unsigned int index)
|
|
||||||
{
|
|
||||||
ReplaceMap tmp;
|
|
||||||
tmp.insert(ReplacePair(index,rep));
|
|
||||||
return replace(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Regex::Match::replace(Regex::ReplaceMap & map)
|
|
||||||
{
|
|
||||||
if (!_have_match)
|
|
||||||
return _basestring;
|
|
||||||
|
|
||||||
std::string buffer = _basestring;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_submatches[0].rm_so != 0 && (map.find(0) != map.end()))
|
|
||||||
return buffer.replace(_submatches[0].rm_so, _submatches[0].rm_eo - _submatches[0].rm_so, map.find(0)->second);
|
|
||||||
|
|
||||||
for (unsigned int n = 1; (_submatches[n].rm_so != -1) && (n < _subcounter); n++)
|
|
||||||
{
|
|
||||||
//// s f RRR s f RRR s f RRRR s f
|
|
||||||
//// XXXYYY(ZZZ)AAA(BBB)CCCEEE(FFFF)GGGG
|
|
||||||
|
|
||||||
bool globalsubs = false;
|
|
||||||
|
|
||||||
if (map.find(n) == map.end())
|
|
||||||
{
|
|
||||||
if (map.find(UINT_MAX) == map.end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
globalsubs = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer = buffer.replace(_submatches[n].rm_so,
|
|
||||||
_submatches[n].rm_eo - _submatches[n].rm_so,
|
|
||||||
map.find((globalsubs ? UINT_MAX : n))->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::out_of_range e)
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
|
@ -1,243 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <regex.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include <refcounter.hpp>
|
|
||||||
#include <noncopyable.hpp>
|
|
||||||
|
|
||||||
#ifndef _REGEX_HPP_
|
|
||||||
#define _REGEX_HPP_
|
|
||||||
|
|
||||||
struct Regex
|
|
||||||
{
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
E_EXTENDED = REG_EXTENDED,
|
|
||||||
E_IGNORE_CASE = REG_ICASE,
|
|
||||||
E_NO_SUB_MATCH = REG_NOSUB,
|
|
||||||
E_EXPLICIT_NEWLINE = REG_NEWLINE,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
M_NO_BEGIN_OF_LINE = REG_NOTBOL,
|
|
||||||
M_NO_END_OF_LINE = REG_NOTEOL,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
/* mark replace for full match (submatch "0"). */
|
|
||||||
REP_BASE = 0u,
|
|
||||||
/* mark global string for replace. */
|
|
||||||
REP_ALL = UINT_MAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::pair < unsigned int, std::string > ReplacePair;
|
|
||||||
typedef std::map < unsigned int, std::string > ReplaceMap;
|
|
||||||
|
|
||||||
struct Expression : public NonCopyable
|
|
||||||
{
|
|
||||||
Expression(const char * expression, unsigned int flags = 0)
|
|
||||||
: _expression(expression), _alloced(false),
|
|
||||||
_subcounter(0), _errorstate(INT_MAX), _flags(flags)
|
|
||||||
{
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression(std::string & expression, unsigned int flags = 0)
|
|
||||||
: _expression(strdup(expression.c_str())), _alloced(true),
|
|
||||||
_subcounter(0), _errorstate(INT_MAX), _flags(flags)
|
|
||||||
{
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
~Expression()
|
|
||||||
{
|
|
||||||
if (_errorstate != INT_MAX)
|
|
||||||
regfree(&_comp_regex);
|
|
||||||
|
|
||||||
if (_alloced)
|
|
||||||
{
|
|
||||||
delete _expression;
|
|
||||||
_expression = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool valid(void) const { return (_errorstate == 0); }
|
|
||||||
|
|
||||||
unsigned int subcount(void) const { return _subcounter; }
|
|
||||||
const regex_t * repr(void) const { return &_comp_regex; }
|
|
||||||
|
|
||||||
std::string error(void) const
|
|
||||||
{
|
|
||||||
switch (_errorstate)
|
|
||||||
{
|
|
||||||
case 0: return "";
|
|
||||||
case INT_MAX: return "uninitialized";
|
|
||||||
default: return regerror_as_string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string regerror_as_string(void) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void initialize(void);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const char * _expression;
|
|
||||||
const bool _alloced;
|
|
||||||
|
|
||||||
unsigned int _subcounter;
|
|
||||||
|
|
||||||
int _errorstate;
|
|
||||||
regex_t _comp_regex;
|
|
||||||
|
|
||||||
const unsigned int _flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Match: COUNTER_SUPER(Match)
|
|
||||||
{
|
|
||||||
Match(const char * basestring, const Expression & expression, unsigned int flags = 0)
|
|
||||||
: _basestring(basestring), _expression(expression), _subcounter(0), _submatches(0),
|
|
||||||
_have_match(false), _flags(flags)
|
|
||||||
{
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
Match(const std::string & basestring, const Expression & expression, unsigned int flags = 0)
|
|
||||||
: _basestring(basestring), _expression(expression), _subcounter(0), _submatches(0),
|
|
||||||
_have_match(false), _flags(flags)
|
|
||||||
{
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
Match(const Match & o)
|
|
||||||
: COUNTER_REFER(o, Match),
|
|
||||||
_basestring(o._basestring), _expression(o._expression),
|
|
||||||
_subcounter(o._subcounter), _submatches(o._submatches),
|
|
||||||
_have_match(o._have_match), _flags(o._flags)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void unreference()
|
|
||||||
{
|
|
||||||
delete[] _submatches;
|
|
||||||
delete[] _subcaching;
|
|
||||||
|
|
||||||
_submatches = 0;
|
|
||||||
_subcaching = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool matched(void)
|
|
||||||
{
|
|
||||||
return _have_match;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool matched(unsigned int number)
|
|
||||||
{
|
|
||||||
if (_have_match && number < _subcounter)
|
|
||||||
return (_submatches[number].rm_so != -1);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string & submatch(int number)
|
|
||||||
{
|
|
||||||
if (!matched(number))
|
|
||||||
return _subcaching[_subcounter - 1 /* invalid, always empty! */ ];
|
|
||||||
|
|
||||||
if (_subcaching[number].empty())
|
|
||||||
{
|
|
||||||
_subcaching[number].assign(_basestring, _submatches[number].rm_so,
|
|
||||||
_submatches[number].rm_eo - _submatches[number].rm_so);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _subcaching[number];
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string & operator[](int number)
|
|
||||||
{
|
|
||||||
return submatch(number);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief replaces strings matched by parentesis
|
|
||||||
* \param each item of the vector is a parentesis replaced
|
|
||||||
* \return string replaced
|
|
||||||
* \note The overload method match only one string in parentesis.
|
|
||||||
* \author Eduardo Nunes Pereira
|
|
||||||
*
|
|
||||||
* If fails the empty string is returned.
|
|
||||||
*/
|
|
||||||
std::string replace(ReplaceMap &);
|
|
||||||
std::string replace(std::string, unsigned int index = REP_BASE);
|
|
||||||
|
|
||||||
// NOTE: there is already a way to get subcount defined on EXPRESSION class!
|
|
||||||
|
|
||||||
private:
|
|
||||||
void initialize(void);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const std::string _basestring;
|
|
||||||
const Expression & _expression;
|
|
||||||
|
|
||||||
unsigned int _subcounter;
|
|
||||||
regmatch_t * _submatches;
|
|
||||||
std::string * _subcaching;
|
|
||||||
bool _have_match;
|
|
||||||
|
|
||||||
const unsigned int _flags;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _REGEX_HPP_ */
|
|
||||||
|
|
|
@ -1,485 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <ringbuffer.hpp>
|
|
||||||
|
|
||||||
// #include <stdio.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* Documentation of the formula used in the buffer arithmetic.
|
|
||||||
*
|
|
||||||
* [0|1|2|3|4|5|6|7] => size=8
|
|
||||||
* | |
|
|
||||||
* reader |
|
|
||||||
* writer
|
|
||||||
*
|
|
||||||
* => writer has places [5,6,7,0,1] to write (5 places).
|
|
||||||
*
|
|
||||||
* => 8 - (4-2+1) = 8 - (2+1) = 8 - 3 = 5
|
|
||||||
*
|
|
||||||
* > writer goes 1 up, amount goes 1 down.
|
|
||||||
* > reader goes 1 up, amount goes 1 up.
|
|
||||||
* > size goes 1 down, amount goes 1 down.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/********** BUFFER FUNCTIONS **********/
|
|
||||||
|
|
||||||
/* writes everything or nothing */
|
|
||||||
bool Ringbuffer_traits::traits_provide(char * buffer, const char * value, unsigned int amount, bool do_not_overwrite)
|
|
||||||
{
|
|
||||||
/* avoid using different values */
|
|
||||||
Buffer_table cache = _pointers;
|
|
||||||
|
|
||||||
bool need_overwrite = false;
|
|
||||||
|
|
||||||
if (amount > free_blocks(cache))
|
|
||||||
{
|
|
||||||
if (do_not_overwrite)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* if we are allowed to overwrite, just the buffer size matters for us */
|
|
||||||
if (amount >= _size)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* we need to change reader pointer below... */
|
|
||||||
need_overwrite = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned int wr = cache.writer.complete;
|
|
||||||
const unsigned int wp = cache.writer.complete - 1;
|
|
||||||
|
|
||||||
/* should we go around the buffer for writing? */
|
|
||||||
if ((wr + amount) > _size)
|
|
||||||
{
|
|
||||||
// fprintf(stderr, "%p> first if matched\n", this);
|
|
||||||
|
|
||||||
if (need_overwrite)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
Buffer_pointer extra(cache.reader);
|
|
||||||
extra.complete = ((wr + amount) % _size); // (extra.complete + amount) % _size;
|
|
||||||
// extra.complete = (extra.complete + amount) % _size;
|
|
||||||
|
|
||||||
if (update(cache.reader, extra))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
while (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int wr1 = _size - wr + 1; /* writer is already 1 position after */
|
|
||||||
unsigned int wr2 = amount - wr1;
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> partial write: (%d/%d) %d/%d [%d/%d]\n", this, wr1, wr2, amount, _size, reader, writer);
|
|
||||||
|
|
||||||
/* two partial writes (one at the end, another at the beginning) */
|
|
||||||
memcpy((void *) &(buffer[wp]), (const void *) (value), _block * wr1);
|
|
||||||
memcpy((void *) (buffer), (const void *) &(value[wr1]), _block * wr2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// fprintf(stderr, "%p> second if matched\n", this);
|
|
||||||
|
|
||||||
if (need_overwrite)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
Buffer_pointer extra(cache.reader);
|
|
||||||
extra.complete = ((wr + amount) % _size); // (extra.complete + amount) % _size;
|
|
||||||
|
|
||||||
if (update(cache.reader, extra))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
while (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> full write: a=%d/s=%d [r=%d/w=%d]\n", this, amount, _size, reader, writer);
|
|
||||||
|
|
||||||
/* we are talking about buffers here, man! */
|
|
||||||
memcpy((void *) &(buffer[wp]), (const void *) value, _block * amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
_pointers.writer.complete = ((wp + amount) % _size) + 1;
|
|
||||||
_pointers.writer.partial = 1;
|
|
||||||
|
|
||||||
// if (need_overwrite)
|
|
||||||
// fprintf(stdout, "%p> write end: w=%d/r=%d\n", this, _pointers.writer.complete, _pointers.reader.complete);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns the number of itens that have been read */
|
|
||||||
unsigned int Ringbuffer_traits::traits_consume(const char * buffer, char * value, unsigned int amount, bool atomic_mode)
|
|
||||||
{
|
|
||||||
/* avoid using different values */
|
|
||||||
Buffer_table cache = _pointers;
|
|
||||||
|
|
||||||
const unsigned int available = used_blocks(cache);
|
|
||||||
|
|
||||||
if (atomic_mode && amount > available)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const unsigned int rd = _pointers.reader.complete;
|
|
||||||
|
|
||||||
unsigned int total = std::min(amount, available);
|
|
||||||
|
|
||||||
/* should we go around the buffer for reading? */
|
|
||||||
if ((rd + total) >= _size)
|
|
||||||
{
|
|
||||||
unsigned int rd1 = _size - rd;
|
|
||||||
unsigned int rd2 = total - rd1;
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> partial read: (%d/%d) %d/%d [%d/%d]\n", this, rd1, rd2, total, _size, reader, writer);
|
|
||||||
|
|
||||||
/* two partial consumes (one at the end, another at the beginning) */
|
|
||||||
memcpy((void *) (value), (const void *) &(buffer[rd]), _block * rd1);
|
|
||||||
memcpy((void *) &(value[rd1]), (const void *) (buffer), _block * rd2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// fprintf(stderr, "%p> full read: %d/%d [%d/%d]\n", this, total, _size, reader, writer);
|
|
||||||
|
|
||||||
/* we are talking about buffers here, man! */
|
|
||||||
memcpy((void *) value, (const void *) &(buffer[rd]), _block * total);
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* jump the reader forward */
|
|
||||||
Buffer_pointer index((cache.reader.complete + total) % _size, 0);
|
|
||||||
|
|
||||||
if (update(cache.reader, index))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
while (true);
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> read end: %d [block=%d]\n", this, reader, _block);
|
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********** TWO-PHASE BUFFER FUNCTIONS ***********/
|
|
||||||
|
|
||||||
/* returns the number of itens that have been read */
|
|
||||||
unsigned int Ringbuffer_traits::traits_consume_begins(const char * buffer, char * value, unsigned int amount, bool atomic_mode)
|
|
||||||
{
|
|
||||||
/* avoid using different values */
|
|
||||||
Buffer_table cache = _pointers;
|
|
||||||
|
|
||||||
const unsigned int available = used_blocks(cache);
|
|
||||||
|
|
||||||
if (amount > available)
|
|
||||||
{
|
|
||||||
if (atomic_mode)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned int rd = _pointers.reader.complete;
|
|
||||||
|
|
||||||
unsigned int total = std::min(amount, available);
|
|
||||||
|
|
||||||
/* should we go around the buffer for reading? */
|
|
||||||
if ((rd + total) >= _size)
|
|
||||||
{
|
|
||||||
unsigned int rd1 = _size - rd;
|
|
||||||
unsigned int rd2 = total - rd1;
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> partial read: (%d/%d) %d/%d [%d/%d]\n", this, rd1, rd2, total, _size, reader, writer);
|
|
||||||
|
|
||||||
/* two partial consumes (one at the end, another at the beginning) */
|
|
||||||
memcpy((void *) (value), (const void *) &(buffer[rd]), _block * rd1);
|
|
||||||
memcpy((void *) &(value[rd1]), (const void *) (buffer), _block * rd2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// fprintf(stderr, "%p> full read: %d/%d [%d/%d]\n", this, total, _size, reader, writer);
|
|
||||||
|
|
||||||
/* we are talking about buffers here, man! */
|
|
||||||
memcpy((void *) value, (const void *) &(buffer[rd]), _block * total);
|
|
||||||
}
|
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Ringbuffer_traits::traits_consume_commit(unsigned int amount)
|
|
||||||
{
|
|
||||||
if (amount == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/* avoid using different values */
|
|
||||||
Buffer_table cache = _pointers;
|
|
||||||
|
|
||||||
const unsigned int available = used_blocks(cache);
|
|
||||||
|
|
||||||
/* cannot commit more than available! */
|
|
||||||
if (amount > available)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
unsigned int total = std::min(amount, available);
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* jump the reader forward */
|
|
||||||
Buffer_pointer index((cache.reader.complete + total) % _size, 0);
|
|
||||||
|
|
||||||
if (update(cache.reader, index))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
while (true);
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> read end: %d [block=%d]\n", this, reader, _block);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********** PARTIAL BUFFER FUNCTIONS (bytes) ***********/
|
|
||||||
|
|
||||||
/* writes everything or nothing */
|
|
||||||
bool Ringbuffer_traits::traits_provide_partial(char * buffer, const char * value, unsigned int amount)
|
|
||||||
{
|
|
||||||
/* avoid using different values */
|
|
||||||
Buffer_table cache = _pointers;
|
|
||||||
|
|
||||||
const unsigned int memsize = (_size * _block);
|
|
||||||
|
|
||||||
if (amount > (free_blocks(cache) * _block))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const unsigned int wr = ((cache.writer.complete - 1) * _block) + cache.writer.partial;
|
|
||||||
const unsigned int wp = wr - 1;
|
|
||||||
|
|
||||||
/* should we go around the buffer for writing? */
|
|
||||||
if ((wr + amount) > memsize)
|
|
||||||
{
|
|
||||||
// fprintf(stderr, "%p> first if matched\n", this);
|
|
||||||
|
|
||||||
unsigned int wr1 = memsize - wr + 1; /* writer is already 1 position after */
|
|
||||||
unsigned int wr2 = amount - wr1;
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> partial write: (%d/%d) %d/%d [%d/%d]\n", this, wr1, wr2, amount, _size, reader, writer);
|
|
||||||
|
|
||||||
/* two partial writes (one at the end, another at the beginning) */
|
|
||||||
memcpy((void *) &(buffer[wp]), (const void *) (value), wr1);
|
|
||||||
memcpy((void *) (buffer), (const void *) &(value[wr1]), wr2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// fprintf(stderr, "%p> second if matched\n", this);
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> full write: a=%d/s=%d [r=%d/w=%d]\n", this, amount, _size, reader, writer);
|
|
||||||
|
|
||||||
/* we are talking about buffers here, man! */
|
|
||||||
memcpy((void *) &(buffer[wp]), (const void *) value, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned int new_wp = (wp + amount) % memsize;
|
|
||||||
|
|
||||||
_pointers.writer.complete = (unsigned int)(floor((double)new_wp / (double)_block) + 1);
|
|
||||||
_pointers.writer.partial = (new_wp % _block) + 1;
|
|
||||||
|
|
||||||
// if (need_overwrite)
|
|
||||||
// fprintf(stdout, "%p> write end: w=%d/r=%d\n", this, _pointers.writer.complete, _pointers.reader.complete);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns the number of bytes that have been read */
|
|
||||||
unsigned int Ringbuffer_traits::traits_consume_partial(const char * buffer, char * value, unsigned int amount)
|
|
||||||
{
|
|
||||||
/* avoid using different values */
|
|
||||||
Buffer_table cache = _pointers;
|
|
||||||
|
|
||||||
const unsigned int available = used_blocks(cache) * _block;
|
|
||||||
|
|
||||||
const unsigned int rd = (_pointers.reader.complete * _block) + _pointers.reader.partial;
|
|
||||||
|
|
||||||
const unsigned int memsize = _size * _block;
|
|
||||||
|
|
||||||
unsigned int total = std::min(amount, available);
|
|
||||||
|
|
||||||
/* should we go around the buffer for reading? */
|
|
||||||
if ((rd + total) >= _size)
|
|
||||||
{
|
|
||||||
unsigned int rd1 = memsize - rd;
|
|
||||||
unsigned int rd2 = total - rd1;
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> partial read: (%d/%d) %d/%d [%d/%d]\n", this, rd1, rd2, total, _size, reader, writer);
|
|
||||||
|
|
||||||
/* two partial consumes (one at the end, another at the beginning) */
|
|
||||||
memcpy((void *) (value), (const void *) &(buffer[rd]), rd1);
|
|
||||||
memcpy((void *) &(value[rd1]), (const void *) (buffer), rd2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// fprintf(stderr, "%p> full read: %d/%d [%d/%d]\n", this, total, _size, reader, writer);
|
|
||||||
|
|
||||||
/* we are talking about buffers here, man! */
|
|
||||||
memcpy((void *) value, (const void *) &(buffer[rd]), total);
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
const unsigned int new_rd = (((cache.reader.complete * _block) + cache.reader.partial) + total) % memsize;
|
|
||||||
|
|
||||||
/* jump the reader forward */
|
|
||||||
Buffer_pointer index((unsigned int)floor((double)new_rd / (double)_block), (unsigned short)(new_rd % _block));
|
|
||||||
|
|
||||||
if (update(cache.reader, index))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
while (true);
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> read end: %d [block=%d]\n", this, reader, _block);
|
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********** IO FUNCTIONS **********/
|
|
||||||
|
|
||||||
/* returns the number of items written to from buffer to stream */
|
|
||||||
unsigned int Ringbuffer_traits::traits_put(const char * buffer, std::ostream &fd, unsigned int amount)
|
|
||||||
{
|
|
||||||
/* avoid using different values */
|
|
||||||
Buffer_table cache = _pointers;
|
|
||||||
|
|
||||||
const unsigned int available = used_blocks(cache);
|
|
||||||
|
|
||||||
if (amount > available)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const unsigned int wr = _pointers.writer.complete;
|
|
||||||
const unsigned int rd = _pointers.reader.complete;
|
|
||||||
|
|
||||||
unsigned int total = std::min(amount, available);
|
|
||||||
|
|
||||||
/* should we go around the buffer for reading? */
|
|
||||||
if ((rd + total) >= _size)
|
|
||||||
{
|
|
||||||
unsigned int rd1 = _size - rd;
|
|
||||||
unsigned int rd2 = total - rd1;
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> partial read: (%d/%d) %d/%d [%d/%d]\n", this, rd1, rd2, total, _size, reader, writer);
|
|
||||||
|
|
||||||
/* two partial consumes (one at the end, another at the beginning) */
|
|
||||||
fd.write((const char *) &(buffer[rd]), _block * rd1);
|
|
||||||
fd.write((const char *) (buffer), _block * rd2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// fprintf(stderr, "%p> full read: %d/%d [%d/%d]\n", this, total, _size, reader, writer);
|
|
||||||
fd.write((const char *) &(buffer[rd]), _block * total);
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* jump the reader forward */
|
|
||||||
Buffer_pointer index((cache.reader.complete + total) % _size, 0);
|
|
||||||
|
|
||||||
if (update(cache.reader, index))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
while (true);
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> read end: %d [block=%d]\n", this, reader, _block);
|
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns number of items read from stream to buffer */
|
|
||||||
unsigned int Ringbuffer_traits::traits_get(char * buffer, std::istream &fd, unsigned int amount)
|
|
||||||
{
|
|
||||||
/* avoid using different values */
|
|
||||||
Buffer_table cache = _pointers;
|
|
||||||
|
|
||||||
if (amount > free_blocks(cache))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const unsigned int wr = cache.writer.complete;
|
|
||||||
const unsigned int wp = cache.writer.complete - 1;
|
|
||||||
|
|
||||||
unsigned int real_amount = 0;
|
|
||||||
|
|
||||||
/* should we go around the buffer for writing? */
|
|
||||||
if ((wr + amount) > _size)
|
|
||||||
{
|
|
||||||
// fprintf(stderr, "%p> first if matched\n", this);
|
|
||||||
|
|
||||||
unsigned int wr1 = _size - wr + 1; /* writer is already 1 position after */
|
|
||||||
unsigned int wr2 = amount - wr1;
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> partial write: (%d/%d) %d/%d [%d/%d]\n", this, wr1, wr2, amount, _size, reader, writer);
|
|
||||||
|
|
||||||
/* two partial writes (one at the end, another at the beginning) */
|
|
||||||
unsigned int char_amount = 0;
|
|
||||||
|
|
||||||
/* one partial write on the buffer (at the end) */
|
|
||||||
fd.read((char *) &(buffer[wp]), _block * wr1);
|
|
||||||
char_amount += fd.gcount();
|
|
||||||
|
|
||||||
if (fd.gcount() == (int)(_block * wr1))
|
|
||||||
{
|
|
||||||
/* another partial write on the buffer (at the beginning) */
|
|
||||||
fd.read((char *) (buffer), _block * wr2);
|
|
||||||
char_amount += fd.gcount();
|
|
||||||
}
|
|
||||||
|
|
||||||
real_amount = char_amount / _block;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// fprintf(stderr, "%p> second if matched\n", this);
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> full write: a=%d/s=%d [r=%d/w=%d]\n", this, amount, _size, reader, writer);
|
|
||||||
|
|
||||||
/* we are talking about buffers here, man! */
|
|
||||||
fd.read((char *) &(buffer[wp]), _block * amount);
|
|
||||||
|
|
||||||
real_amount = fd.gcount() / _block;
|
|
||||||
}
|
|
||||||
|
|
||||||
_pointers.writer.complete = ((wp + amount) % _size) + 1;
|
|
||||||
_pointers.writer.partial = 1;
|
|
||||||
|
|
||||||
// fprintf(stdout, "%p> write end: %d\n", this, _pointers.writer.complete);
|
|
||||||
|
|
||||||
return real_amount;
|
|
||||||
}
|
|
|
@ -1,448 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* WARNING: This is a generic ringbuffer abstraction, which works for single-sized elements,
|
|
||||||
partial elements, single/multi-elements read/writes. It is not wise to mix some
|
|
||||||
functions (partial element write / full element write), since it was not designed
|
|
||||||
with this use in mind.
|
|
||||||
|
|
||||||
Also, it works only for single-reader + single-writer, since it does not depends
|
|
||||||
on external mutex functions.
|
|
||||||
|
|
||||||
NOTE: for single element provide/consume, this abstraction has standard C++ semantics.
|
|
||||||
|
|
||||||
for multiple and partial element provide/consume, memcpy is used - thus complex C++
|
|
||||||
objects which need correct copy constructor semantics should not copied this way.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <noncopyable.hpp>
|
|
||||||
#include <atomic.hpp>
|
|
||||||
|
|
||||||
#ifndef _RINGBUFFER_HPP_
|
|
||||||
#define _RINGBUFFER_HPP_
|
|
||||||
|
|
||||||
struct Buffer_pointer
|
|
||||||
{
|
|
||||||
Buffer_pointer(unsigned int _complete, unsigned short _partial)
|
|
||||||
: complete(_complete), partial(_partial)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Buffer_pointer(const Buffer_pointer & o)
|
|
||||||
: complete(o.complete), partial(o.partial)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Buffer_pointer(const volatile Buffer_pointer & o)
|
|
||||||
: complete(o.complete), partial(o.partial)
|
|
||||||
{};
|
|
||||||
|
|
||||||
void operator=(const volatile Buffer_pointer o)
|
|
||||||
{
|
|
||||||
complete = o.complete;
|
|
||||||
partial = o.partial;
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator=(const Buffer_pointer o) volatile
|
|
||||||
{
|
|
||||||
complete = o.complete;
|
|
||||||
partial = o.partial;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const Buffer_pointer & o)
|
|
||||||
{
|
|
||||||
return (complete == o.complete && partial == o.partial);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int complete:20;
|
|
||||||
unsigned short partial:12;
|
|
||||||
}
|
|
||||||
__attribute__((packed));
|
|
||||||
|
|
||||||
struct Buffer_table
|
|
||||||
{
|
|
||||||
Buffer_table()
|
|
||||||
: reader(0,0),
|
|
||||||
writer(1,1)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Buffer_table(const Buffer_table & o)
|
|
||||||
: reader(o.reader), writer(o.writer)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Buffer_table(const volatile Buffer_table & o)
|
|
||||||
: reader(o.reader), writer(o.writer)
|
|
||||||
{};
|
|
||||||
|
|
||||||
void operator=(const volatile Buffer_table o)
|
|
||||||
{
|
|
||||||
reader = o.reader;
|
|
||||||
writer = o.writer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator=(const Buffer_table o) volatile
|
|
||||||
{
|
|
||||||
reader = o.reader;
|
|
||||||
writer = o.writer;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const Buffer_table & o)
|
|
||||||
{
|
|
||||||
return (reader == o.reader && writer == o.writer);
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer_pointer reader;
|
|
||||||
Buffer_pointer writer;
|
|
||||||
}
|
|
||||||
__attribute__((packed));
|
|
||||||
|
|
||||||
struct Ringbuffer_traits
|
|
||||||
{
|
|
||||||
struct BufferFull {};
|
|
||||||
struct BufferEmpty {};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Ringbuffer_traits(unsigned int block, unsigned int size)
|
|
||||||
: _block(block), _size(size)
|
|
||||||
{};
|
|
||||||
|
|
||||||
bool traits_provide( char *, const char *, unsigned int, bool);
|
|
||||||
unsigned int traits_consume(const char *, char *, unsigned int, bool);
|
|
||||||
|
|
||||||
unsigned int traits_consume_begins(const char *, char *, unsigned int, bool);
|
|
||||||
bool traits_consume_commit(unsigned int);
|
|
||||||
|
|
||||||
bool traits_provide_partial( char *, const char *, unsigned int);
|
|
||||||
unsigned int traits_consume_partial(const char *, char *, unsigned int);
|
|
||||||
|
|
||||||
unsigned int traits_get( char *, std::istream &, unsigned int);
|
|
||||||
unsigned int traits_put(const char *, std::ostream &, unsigned int);
|
|
||||||
|
|
||||||
bool update(Buffer_pointer & cache, Buffer_pointer & update)
|
|
||||||
{
|
|
||||||
return Atomic::doCAS(&(_pointers.reader), &cache, update);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned int free_blocks(const Buffer_table & cache) const
|
|
||||||
{
|
|
||||||
const unsigned int r = cache.reader.complete;
|
|
||||||
const unsigned int w = cache.writer.complete;
|
|
||||||
|
|
||||||
if (r >= w)
|
|
||||||
return (r - w);
|
|
||||||
|
|
||||||
return _size - (w - r);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned int used_blocks(const Buffer_table & cache) const
|
|
||||||
{
|
|
||||||
const unsigned int r = cache.reader.complete;
|
|
||||||
const unsigned int w = cache.writer.complete;
|
|
||||||
|
|
||||||
if (r >= w)
|
|
||||||
return (_size - (r - w)) - 1;
|
|
||||||
|
|
||||||
return (w - r) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const unsigned int _block;
|
|
||||||
const unsigned int _size;
|
|
||||||
|
|
||||||
volatile Buffer_table _pointers;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct Ringbuffer: public Ringbuffer_traits, public NonCopyable
|
|
||||||
{
|
|
||||||
Ringbuffer(unsigned int size)
|
|
||||||
: Ringbuffer_traits(sizeof(T), size)
|
|
||||||
{
|
|
||||||
_buffer = new T[_size];
|
|
||||||
_malloc = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
Ringbuffer(unsigned int size, T * buffer)
|
|
||||||
: Ringbuffer_traits(sizeof(T), size)
|
|
||||||
{
|
|
||||||
_buffer = buffer;
|
|
||||||
_malloc = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
~Ringbuffer()
|
|
||||||
{
|
|
||||||
if (_malloc)
|
|
||||||
delete[] _buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** GENERIC RANGE/INDEX CALCULATION FUNCTIONS *****/
|
|
||||||
|
|
||||||
protected:
|
|
||||||
inline bool may_write(const Buffer_table & cache) const
|
|
||||||
{
|
|
||||||
const unsigned int r = cache.reader.complete;
|
|
||||||
const unsigned int w = cache.writer.complete;
|
|
||||||
|
|
||||||
return (((r - w) != 0) && (!(r == 0 && w == _size)));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool may_read(const Buffer_table & cache) const
|
|
||||||
{
|
|
||||||
if ((cache.writer.complete - cache.reader.complete) == 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned int writer_next(const Buffer_pointer & cache, Buffer_pointer & index) const
|
|
||||||
{
|
|
||||||
unsigned int dest = cache.complete - 1,
|
|
||||||
temp = cache.complete + 1;
|
|
||||||
|
|
||||||
if (temp > _size) index.complete = 1;
|
|
||||||
else index.complete = temp;
|
|
||||||
|
|
||||||
index.partial = 1;
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void reader_next(const Buffer_pointer & cache, Buffer_pointer & index) const
|
|
||||||
{
|
|
||||||
unsigned int temp = cache.complete + 1;
|
|
||||||
|
|
||||||
if (temp == _size) index.complete = 0;
|
|
||||||
else index.complete = temp;
|
|
||||||
|
|
||||||
index.partial = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** BUFFER FUNCTIONS *****/
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool provide(const T & value)
|
|
||||||
{
|
|
||||||
Buffer_table cache = _pointers;
|
|
||||||
Buffer_pointer index = _pointers.writer;
|
|
||||||
|
|
||||||
if (!may_write(cache))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> provide %d/%d!\n", this, reader, writer);
|
|
||||||
|
|
||||||
unsigned int dest = writer_next(cache.writer, index);
|
|
||||||
|
|
||||||
_buffer[dest] = value;
|
|
||||||
|
|
||||||
_pointers.writer = index;
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> write: %d/%d [%d/%d]\n", this, _pointers.reader, _pointers.writer, _pointers.reader_partial, _pointers.writer_partial);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool consume(T & value)
|
|
||||||
{
|
|
||||||
Buffer_table cache = _pointers;
|
|
||||||
Buffer_pointer index = _pointers.reader;
|
|
||||||
|
|
||||||
if (!may_read(cache))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> consume %d/%d!\n", this, reader, writer);
|
|
||||||
|
|
||||||
value = _buffer[index.complete];
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
reader_next(cache.reader, index);
|
|
||||||
|
|
||||||
if (update(cache.reader, index))
|
|
||||||
break;
|
|
||||||
|
|
||||||
cache.reader = index;
|
|
||||||
}
|
|
||||||
while (true);
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> read: %d/%d [%d/%d]\n", this, _pointers.reader, _pointers.writer, _pointers.reader_partial, _pointers.writer_partial);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* writes everything or nothing */
|
|
||||||
inline bool provide(const T * value, unsigned int amount, bool do_not_overwrite = true)
|
|
||||||
{
|
|
||||||
return traits_provide((char *)_buffer, (const char *) value, amount, do_not_overwrite);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns the number of items that have been read (atomic_mode == true means 'all or nothing') */
|
|
||||||
inline unsigned int consume(T * value, unsigned int amount, bool atomic_mode = false)
|
|
||||||
{
|
|
||||||
return traits_consume((const char *)_buffer, (char *) value, amount, atomic_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** TWO-PHASE BUFFER FUNCTIONS *****/
|
|
||||||
|
|
||||||
/* returns the number of items that have been read (atomic_mode == true means 'all or nothing') */
|
|
||||||
inline unsigned int consume_begins(T * value, unsigned int amount, bool atomic_mode = false)
|
|
||||||
{
|
|
||||||
return traits_consume_begins((const char *)_buffer, (char *) value, amount, atomic_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns true if we could commit that much of buffer (use only after consume_begins). *
|
|
||||||
* note: you may commit less bytes that have been read to keep some data inside the buffer */
|
|
||||||
inline bool consume_commit(unsigned int amount)
|
|
||||||
{
|
|
||||||
return traits_consume_commit(amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** TWO-PHASE SINGLE-ELEMENT BUFFER FUNCTIONS *****/
|
|
||||||
|
|
||||||
T & provider_start(void)
|
|
||||||
{
|
|
||||||
Buffer_table cache = _pointers;
|
|
||||||
|
|
||||||
if (!may_write(cache))
|
|
||||||
throw BufferFull();
|
|
||||||
|
|
||||||
unsigned writer = _pointers.writer.complete - 1;
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> provider start %d/%d!\n", this, reader, writer);
|
|
||||||
|
|
||||||
return _buffer[writer];
|
|
||||||
}
|
|
||||||
|
|
||||||
void provider_commit(void)
|
|
||||||
{
|
|
||||||
unsigned int temp = _pointers.writer.complete + 1;
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> provider commit %d!\n", this, temp);
|
|
||||||
|
|
||||||
if (temp > _size)
|
|
||||||
temp = 1;
|
|
||||||
|
|
||||||
_pointers.writer.complete = temp;
|
|
||||||
_pointers.writer.partial = 1;
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> write: %d/%d [%d/%d]\n", this, _pointers.reader, _pointers.writer, _pointers.reader_partial, _pointers.writer_partial);
|
|
||||||
}
|
|
||||||
|
|
||||||
const T & consumer_start(void)
|
|
||||||
{
|
|
||||||
Buffer_table cache = _pointers;
|
|
||||||
|
|
||||||
if (!may_read(cache))
|
|
||||||
throw BufferEmpty();
|
|
||||||
|
|
||||||
unsigned int reader = _pointers.reader.complete;
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> consumer start %d/%d!\n", this, reader, writer);
|
|
||||||
|
|
||||||
return _buffer[reader];
|
|
||||||
}
|
|
||||||
|
|
||||||
void consumer_commit(void)
|
|
||||||
{
|
|
||||||
Buffer_pointer cache = _pointers.reader;
|
|
||||||
Buffer_pointer index(cache);
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
reader_next(cache, index);
|
|
||||||
|
|
||||||
if (update(cache, index))
|
|
||||||
break;
|
|
||||||
|
|
||||||
cache = index;
|
|
||||||
}
|
|
||||||
while (true);
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> consumer commit %d!\n", this, temp);
|
|
||||||
|
|
||||||
// fprintf(stderr, "%p> read: %d/%d [%d/%d]\n", this, _pointers.reader, _pointers.writer, _pointers.reader_partial, _pointers.writer_partial);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* writes everything or nothing, but works on bytes (may write incomplete elements) */
|
|
||||||
/* WARNING: do not mix this with full element provider */
|
|
||||||
inline bool provider_partial(const char *buffer, unsigned int amount)
|
|
||||||
{
|
|
||||||
return traits_provide_partial((char *)_buffer, buffer, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns the number of bytes that have been read (may read incomplete elements) */
|
|
||||||
/* WARNING: do not mix this with full element consumer */
|
|
||||||
inline unsigned int consumer_partial(char *buffer, unsigned int amount)
|
|
||||||
{
|
|
||||||
return traits_consume_partial((const char *)_buffer, buffer, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** IO FUNCTIONS *****/
|
|
||||||
|
|
||||||
/* returns the number of items written to from buffer to stream */
|
|
||||||
inline unsigned int put(std::ostream &fd, unsigned int amount)
|
|
||||||
{
|
|
||||||
return traits_put((const char *)_buffer, fd, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns number of items read from stream to buffer */
|
|
||||||
inline unsigned int get(std::istream &fd, unsigned int amount)
|
|
||||||
{
|
|
||||||
return traits_get((char *)_buffer, fd, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
_pointers.reader.complete = 0;
|
|
||||||
_pointers.reader.partial = 0;
|
|
||||||
_pointers.writer.complete = 1;
|
|
||||||
_pointers.writer.partial = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
T * _buffer;
|
|
||||||
bool _malloc;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _RINGBUFFER_HPP_ */
|
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <config_commons.hpp>
|
|
||||||
|
|
||||||
#include COMMONS_INCLUDE(saved_condition.cpp)
|
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _SAVED_CONDITION_COMMON_HPP_
|
|
||||||
#define _SAVED_CONDITION_COMMON_HPP_
|
|
||||||
|
|
||||||
#include <config_commons.hpp>
|
|
||||||
|
|
||||||
//#include <refcounter.hpp>
|
|
||||||
|
|
||||||
struct SavedConditionCommon
|
|
||||||
{
|
|
||||||
SavedConditionCommon() : _signaled(false) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool _signaled;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#include COMMONS_INCLUDE(saved_condition.hpp)
|
|
||||||
|
|
||||||
#endif /* _SAVED_CONDITION_COMMON_HPP_ */
|
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <simple_lock.hpp>
|
|
||||||
|
|
||||||
struct ScopedLockBasic
|
|
||||||
{
|
|
||||||
ScopedLockBasic(void)
|
|
||||||
: _locked(true) {};
|
|
||||||
|
|
||||||
ScopedLockBasic(bool locked)
|
|
||||||
: _locked(locked) {};
|
|
||||||
|
|
||||||
virtual ~ScopedLockBasic() {};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool _locked;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct ScopedLock : public ScopedLockBasic
|
|
||||||
{
|
|
||||||
struct LockFailed {};
|
|
||||||
|
|
||||||
ScopedLock(SimpleLock & mutex)
|
|
||||||
: ScopedLockBasic(false), _mutex(mutex)
|
|
||||||
{
|
|
||||||
switch (_mutex.lock())
|
|
||||||
{
|
|
||||||
case SimpleLock::ISINUSE:
|
|
||||||
case SimpleLock::FAILURE:
|
|
||||||
throw LockFailed();
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_locked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
~ScopedLock()
|
|
||||||
{
|
|
||||||
unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void unlock()
|
|
||||||
{
|
|
||||||
if (_locked)
|
|
||||||
{
|
|
||||||
_locked = false;
|
|
||||||
_mutex.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
SimpleLock & _mutex;
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _SIMPLE_LOCK_COMMON_HPP_
|
|
||||||
#define _SIMPLE_LOCK_COMMON_HPP_
|
|
||||||
|
|
||||||
#include <config_commons.hpp>
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <noncopyable.hpp>
|
|
||||||
|
|
||||||
#include <refcounter.hpp>
|
|
||||||
|
|
||||||
/* This struct uses static polymorphism, and derived classes should implement *
|
|
||||||
* the "lock/trylock/unlock()" methods for correct code compilation. *
|
|
||||||
* The base class also features reference counting, so derived classes should *
|
|
||||||
* implement the "unreference_data()" method for releasing resources. */
|
|
||||||
|
|
||||||
template < typename Implementor >
|
|
||||||
struct SimpleLockCommon: COUNTER_SUPER( SimpleLockCommon < Implementor > )
|
|
||||||
{
|
|
||||||
friend class ReferenceCounter < SimpleLockCommon < Implementor > >;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
ISINUSE = 0, // operation not succeded (no error)
|
|
||||||
SUCCESS = 1, // operation succeded (no error)
|
|
||||||
FAILURE = 2, // mutex or state is somehow invalid (error! run for your life!)
|
|
||||||
}
|
|
||||||
Result;
|
|
||||||
|
|
||||||
SimpleLockCommon()
|
|
||||||
{};
|
|
||||||
|
|
||||||
SimpleLockCommon(const SimpleLockCommon & o)
|
|
||||||
: COUNTER_REFER(o, SimpleLockCommon)
|
|
||||||
{};
|
|
||||||
|
|
||||||
virtual ~SimpleLockCommon()
|
|
||||||
{};
|
|
||||||
|
|
||||||
inline Result lock()
|
|
||||||
{
|
|
||||||
return static_cast<Implementor*>(this)->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Result trylock()
|
|
||||||
{
|
|
||||||
return static_cast<Implementor*>(this)->trylock();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void unlock()
|
|
||||||
{
|
|
||||||
static_cast<Implementor*>(this)->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void unreference(void)
|
|
||||||
{
|
|
||||||
static_cast<Implementor*>(this)->unreference_data();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#include COMMONS_INCLUDE(simple_lock.hpp)
|
|
||||||
|
|
||||||
#endif /* _SIMPLE_LOCK_COMMON_HPP_ */
|
|
|
@ -1,267 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <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);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int Strings::tokenize(const std::string & str, Strings::vector_type & tokens,
|
|
||||||
const std::string & delims, long int max_tokens, bool keep_empty)
|
|
||||||
{
|
|
||||||
std::string::size_type base = 0;
|
|
||||||
|
|
||||||
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 (keep_empty && base < init)
|
|
||||||
{
|
|
||||||
std::string::size_type cur_empty = init - base;
|
|
||||||
|
|
||||||
while (cur_empty && cur_token < max_tokens)
|
|
||||||
{
|
|
||||||
tokens.push_back("");
|
|
||||||
|
|
||||||
++cur_token;
|
|
||||||
--cur_empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (std::string::npos != fini && cur_token < max_tokens)
|
|
||||||
{
|
|
||||||
base = fini + 1;
|
|
||||||
|
|
||||||
tokens.push_back(str.substr(init, fini - init));
|
|
||||||
++cur_token;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
base = str.size(); // find_first_of(delims, init);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keep_empty && base != str.size())
|
|
||||||
{
|
|
||||||
std::string::size_type cur_empty = str.size() - base + 1;
|
|
||||||
|
|
||||||
while (cur_empty && cur_token < max_tokens)
|
|
||||||
{
|
|
||||||
tokens.push_back("");
|
|
||||||
|
|
||||||
++cur_token;
|
|
||||||
--cur_empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur_empty)
|
|
||||||
{
|
|
||||||
std::string::size_type pos = base + cur_empty - 1;
|
|
||||||
tokens.push_back(str.substr(pos, str.size() - pos));
|
|
||||||
++cur_token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (cur_token - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
long Strings::tolong(const std::string & str, int base)
|
|
||||||
{
|
|
||||||
return tolong(str.c_str(), base);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long Strings::toulong(const std::string & str, int base)
|
|
||||||
{
|
|
||||||
return toulong(str.c_str(), base);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long long Strings::toulonglong(const std::string & str, int base)
|
|
||||||
{
|
|
||||||
return toulonglong(str.c_str(), base);
|
|
||||||
}
|
|
||||||
|
|
||||||
double Strings::todouble(const std::string & str)
|
|
||||||
{
|
|
||||||
return todouble(str.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
long Strings::tolong(const char * str, int base)
|
|
||||||
{
|
|
||||||
char *str_end = 0;
|
|
||||||
|
|
||||||
unsigned long value = strtol(str, &str_end, base);
|
|
||||||
|
|
||||||
if (str_end && *str_end == 0)
|
|
||||||
return value;
|
|
||||||
|
|
||||||
throw invalid_value(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long Strings::toulong(const char * str, int base)
|
|
||||||
{
|
|
||||||
char *str_end = 0;
|
|
||||||
|
|
||||||
unsigned long value = strtoul(str, &str_end, base);
|
|
||||||
|
|
||||||
if (str_end && *str_end == 0)
|
|
||||||
return value;
|
|
||||||
|
|
||||||
throw invalid_value(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long long Strings::toulonglong(const char * 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, &str_end, base);
|
|
||||||
|
|
||||||
if (str_end && *str_end == 0)
|
|
||||||
return value;
|
|
||||||
|
|
||||||
throw invalid_value(str);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
double Strings::todouble(const char * str)
|
|
||||||
{
|
|
||||||
char *str_end = 0;
|
|
||||||
|
|
||||||
double value = strtod(str, &str_end);
|
|
||||||
|
|
||||||
if (str_end && *str_end == 0)
|
|
||||||
return value;
|
|
||||||
|
|
||||||
throw invalid_value(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,113 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include <list>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <types.hpp>
|
|
||||||
|
|
||||||
#include <format.hpp>
|
|
||||||
|
|
||||||
/* Generic string funcions */
|
|
||||||
|
|
||||||
#ifndef _STRINGS_HPP_
|
|
||||||
#define _STRINGS_HPP_
|
|
||||||
|
|
||||||
struct Strings
|
|
||||||
{
|
|
||||||
typedef std::list<std::string> list_type;
|
|
||||||
typedef std::vector<std::string> vector_type;
|
|
||||||
|
|
||||||
struct Merger
|
|
||||||
{
|
|
||||||
void add(std::string);
|
|
||||||
|
|
||||||
std::string merge(const std::string &);
|
|
||||||
std::string merge(const char *);
|
|
||||||
|
|
||||||
bool empty() { return _list.empty(); };
|
|
||||||
|
|
||||||
const list_type & list() { return _list; };
|
|
||||||
|
|
||||||
protected:
|
|
||||||
list_type _list;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
struct invalid_value
|
|
||||||
{
|
|
||||||
invalid_value(const char * value): _value(value) {};
|
|
||||||
invalid_value(const std::string & value): _value(value) {};
|
|
||||||
|
|
||||||
std::string & value() { return _value; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string _value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct not_implemented {};
|
|
||||||
|
|
||||||
static unsigned int tokenize(const std::string &, vector_type &, const std::string & delims = ",;:",
|
|
||||||
long int max_toxens = LONG_MAX, bool keep_empty = true);
|
|
||||||
|
|
||||||
static bool toboolean(std::string);
|
|
||||||
static std::string fromboolean(bool);
|
|
||||||
|
|
||||||
static long tolong(const std::string &, int base = 10);
|
|
||||||
static unsigned long toulong(const std::string &, int base = 10);
|
|
||||||
static unsigned long long toulonglong(const std::string &, int base = 10);
|
|
||||||
static double todouble(const std::string &);
|
|
||||||
|
|
||||||
static long tolong(const char *, int base = 10);
|
|
||||||
static unsigned long toulong(const char *, int base = 10);
|
|
||||||
static unsigned long long toulonglong(const char *, int base = 10);
|
|
||||||
static double todouble(const char *);
|
|
||||||
|
|
||||||
static std::string lower(std::string);
|
|
||||||
static std::string hexadecimal(std::string);
|
|
||||||
|
|
||||||
static std::string trim(const std::string&, const std::string& trim_chars = " \f\n\r\t\v");
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _STRINGS_HPP_ //
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "saved_condition.hpp"
|
|
||||||
|
|
||||||
bool SavedCondition::wait(unsigned int msec)
|
|
||||||
{
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
switch_mutex_lock(_mutex);
|
|
||||||
|
|
||||||
if (!_signaled)
|
|
||||||
{
|
|
||||||
/* msec * 1000 = The amount of time in microseconds to wait. */
|
|
||||||
if (switch_thread_cond_timedwait(_condition, _mutex, (switch_interval_time_t)msec * 1000) != 0)
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_signaled = false;
|
|
||||||
|
|
||||||
switch_mutex_unlock(_mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
|
@ -1,136 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _SAVED_CONDITION_
|
|
||||||
#define _SAVED_CONDITION_
|
|
||||||
|
|
||||||
#include <saved_condition.hpp>
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#include <switch.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SavedCondition : public SavedConditionCommon// : public RefCounter < SavedCondition >
|
|
||||||
{
|
|
||||||
typedef switch_thread_cond_t BaseConditionType;
|
|
||||||
typedef switch_mutex_t BaseMutexType;
|
|
||||||
|
|
||||||
SavedCondition(switch_memory_pool_t *pool=NULL):
|
|
||||||
_pool(pool),
|
|
||||||
_can_delete_pool(false)
|
|
||||||
{
|
|
||||||
if(!_pool)
|
|
||||||
{
|
|
||||||
switch_core_new_memory_pool(&_pool);
|
|
||||||
_can_delete_pool = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_thread_cond_create(&_condition, _pool);
|
|
||||||
switch_mutex_init(&_mutex, SWITCH_MUTEX_DEFAULT, _pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
//SavedCondition(const SavedCondition &);
|
|
||||||
~SavedCondition()
|
|
||||||
{
|
|
||||||
switch_thread_cond_destroy(_condition);
|
|
||||||
switch_mutex_destroy(_mutex);
|
|
||||||
|
|
||||||
if(_can_delete_pool)
|
|
||||||
switch_core_destroy_memory_pool(&_pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
void signal(void)
|
|
||||||
{
|
|
||||||
switch_mutex_lock(_mutex);
|
|
||||||
|
|
||||||
_signaled = true;
|
|
||||||
switch_thread_cond_signal(_condition);
|
|
||||||
|
|
||||||
switch_mutex_unlock(_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void broadcast(void)
|
|
||||||
{
|
|
||||||
switch_mutex_lock(_mutex);
|
|
||||||
|
|
||||||
_signaled = true;
|
|
||||||
switch_thread_cond_broadcast(_condition);
|
|
||||||
|
|
||||||
switch_mutex_unlock(_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wait(void)
|
|
||||||
{
|
|
||||||
switch_mutex_lock(_mutex);
|
|
||||||
|
|
||||||
if (!_signaled)
|
|
||||||
switch_thread_cond_wait(_condition, _mutex);
|
|
||||||
|
|
||||||
_signaled = false;
|
|
||||||
|
|
||||||
switch_mutex_unlock(_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wait(unsigned int);
|
|
||||||
|
|
||||||
void reset(void)
|
|
||||||
{
|
|
||||||
switch_mutex_lock(_mutex);
|
|
||||||
|
|
||||||
_signaled = false;
|
|
||||||
|
|
||||||
switch_mutex_unlock(_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseMutexType * mutex() { return _mutex; };
|
|
||||||
BaseConditionType * condition() { return _condition; };
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
BaseConditionType *_condition;
|
|
||||||
BaseMutexType *_mutex;
|
|
||||||
switch_memory_pool_t *_pool;
|
|
||||||
bool _can_delete_pool;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _SAVED_CONDITION_ */
|
|
||||||
|
|
|
@ -1,177 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _SIMPLE_LOCK_HPP_
|
|
||||||
#define _SIMPLE_LOCK_HPP_
|
|
||||||
|
|
||||||
#include <simple_lock.hpp>
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#include <switch.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Implementor >
|
|
||||||
struct SimpleLockBasic: public SimpleLockCommon < Implementor >
|
|
||||||
{
|
|
||||||
typedef SimpleLockCommon < Implementor > Super;
|
|
||||||
typedef typename Super::Result Result;
|
|
||||||
|
|
||||||
typedef switch_mutex_t BaseMutexType;
|
|
||||||
|
|
||||||
SimpleLockBasic(switch_memory_pool_t *pool = NULL)
|
|
||||||
: _pool(pool), _can_delete_pool( (_pool == NULL) )
|
|
||||||
|
|
||||||
{
|
|
||||||
if(!_pool)
|
|
||||||
switch_core_new_memory_pool(&_pool);
|
|
||||||
|
|
||||||
//switch_mutex_init(&_mutex, SWITCH_MUTEX_DEFAULT, _pool);
|
|
||||||
switch_mutex_init(&_mutex, SWITCH_MUTEX_NESTED, _pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~SimpleLockBasic()
|
|
||||||
{
|
|
||||||
/* do nothing */
|
|
||||||
};
|
|
||||||
|
|
||||||
void unreference_data()
|
|
||||||
{
|
|
||||||
switch_mutex_destroy(_mutex);
|
|
||||||
|
|
||||||
if (_can_delete_pool)
|
|
||||||
switch_core_destroy_memory_pool(&_pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result trylock()
|
|
||||||
{
|
|
||||||
switch (switch_mutex_trylock(_mutex))
|
|
||||||
{
|
|
||||||
case SWITCH_STATUS_SUCCESS:
|
|
||||||
return Super::SUCCESS;
|
|
||||||
case SWITCH_STATUS_FALSE:
|
|
||||||
case SWITCH_STATUS_TERM:
|
|
||||||
case SWITCH_STATUS_NOTIMPL:
|
|
||||||
case SWITCH_STATUS_MEMERR:
|
|
||||||
case SWITCH_STATUS_GENERR:
|
|
||||||
case SWITCH_STATUS_SOCKERR:
|
|
||||||
case SWITCH_STATUS_NOTFOUND:
|
|
||||||
case SWITCH_STATUS_UNLOAD:
|
|
||||||
case SWITCH_STATUS_NOUNLOAD:
|
|
||||||
case SWITCH_STATUS_NOT_INITALIZED:
|
|
||||||
return Super::FAILURE;
|
|
||||||
//case SWITCH_STATUS_INUSE:
|
|
||||||
default:
|
|
||||||
return Super::ISINUSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void unlock()
|
|
||||||
{
|
|
||||||
switch_mutex_unlock(_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseMutexType * mutex() { return _mutex; };
|
|
||||||
|
|
||||||
protected:
|
|
||||||
BaseMutexType *_mutex;
|
|
||||||
switch_memory_pool_t *_pool;
|
|
||||||
bool _can_delete_pool;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SimpleLock: public SimpleLockBasic < SimpleLock >
|
|
||||||
{
|
|
||||||
typedef SimpleLockBasic < SimpleLock > Super;
|
|
||||||
typedef Super::Result Result;
|
|
||||||
|
|
||||||
SimpleLock(switch_memory_pool_t *pool = NULL)
|
|
||||||
: Super(pool) {};
|
|
||||||
|
|
||||||
Result lock()
|
|
||||||
{
|
|
||||||
switch (switch_mutex_lock(_mutex))
|
|
||||||
{
|
|
||||||
case SWITCH_STATUS_SUCCESS:
|
|
||||||
return Super::SUCCESS;
|
|
||||||
case SWITCH_STATUS_FALSE:
|
|
||||||
case SWITCH_STATUS_TERM:
|
|
||||||
case SWITCH_STATUS_NOTIMPL:
|
|
||||||
case SWITCH_STATUS_MEMERR:
|
|
||||||
case SWITCH_STATUS_GENERR:
|
|
||||||
case SWITCH_STATUS_SOCKERR:
|
|
||||||
case SWITCH_STATUS_NOTFOUND:
|
|
||||||
case SWITCH_STATUS_UNLOAD:
|
|
||||||
case SWITCH_STATUS_NOUNLOAD:
|
|
||||||
case SWITCH_STATUS_NOT_INITALIZED:
|
|
||||||
return Super::FAILURE;
|
|
||||||
//case SWITCH_STATUS_INUSE:
|
|
||||||
default:
|
|
||||||
return Super::ISINUSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template < unsigned int Retries = 10, unsigned int Interval = 50 >
|
|
||||||
struct SimpleNonBlockLock: public SimpleLockBasic < SimpleNonBlockLock < Retries, Interval > >
|
|
||||||
{
|
|
||||||
typedef SimpleLockBasic < SimpleNonBlockLock < Retries, Interval > > Super;
|
|
||||||
typedef typename Super::Result Result;
|
|
||||||
|
|
||||||
SimpleNonBlockLock(switch_memory_pool_t *pool = NULL)
|
|
||||||
: Super(pool) {};
|
|
||||||
|
|
||||||
inline Result lock()
|
|
||||||
{
|
|
||||||
for (unsigned int i = 0; i < Retries; i++)
|
|
||||||
{
|
|
||||||
Result ret = Super::trylock();
|
|
||||||
|
|
||||||
if (ret != Super::ISINUSE)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
usleep(Interval * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Super::ISINUSE;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _SIMPLE_LOCK_HPP_ */
|
|
|
@ -1,330 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _THREAD_HPP_
|
|
||||||
#define _THREAD_HPP_
|
|
||||||
|
|
||||||
#include <thread.hpp>
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#include <switch.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Thread : ThreadCommon
|
|
||||||
{
|
|
||||||
typedef switch_thread_t BaseThreadType;
|
|
||||||
|
|
||||||
template<typename T, typename R, typename A>
|
|
||||||
struct ThreadData : ThreadDataCommon
|
|
||||||
{
|
|
||||||
ThreadData(T data, A arg) : _data(data), _arg(arg) {}
|
|
||||||
|
|
||||||
int run()
|
|
||||||
{
|
|
||||||
return _data(_arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
T _data;
|
|
||||||
A _arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename R>
|
|
||||||
struct ThreadData < T, R, void > : ThreadDataCommon
|
|
||||||
{
|
|
||||||
ThreadData(T data) : _data(data) {}
|
|
||||||
|
|
||||||
int run()
|
|
||||||
{
|
|
||||||
return _data();
|
|
||||||
}
|
|
||||||
|
|
||||||
T _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename A>
|
|
||||||
struct ThreadData < T, void, A > : ThreadDataCommon
|
|
||||||
{
|
|
||||||
ThreadData(T data, A arg) : _data(data), _arg(arg) {}
|
|
||||||
|
|
||||||
int run()
|
|
||||||
{
|
|
||||||
_data(_arg);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
T _data;
|
|
||||||
A _arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct ThreadData < T, void, void > : ThreadDataCommon
|
|
||||||
{
|
|
||||||
ThreadData(T data) : _data(data) {}
|
|
||||||
|
|
||||||
int run()
|
|
||||||
{
|
|
||||||
_data();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
T _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
Thread(T obj, switch_memory_pool_t *pool=NULL) :
|
|
||||||
_thread_info(new ThreadData<T, typename DecomposeFunction<T>::Return, void>(obj)),
|
|
||||||
_pool(pool),
|
|
||||||
_can_delete_pool(false)
|
|
||||||
{
|
|
||||||
if(!_pool)
|
|
||||||
{
|
|
||||||
switch_core_new_memory_pool(&_pool);
|
|
||||||
_can_delete_pool = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_thread_info->_thread = this;
|
|
||||||
_thread_info->_self = NULL;
|
|
||||||
_thread_info->_attribute = NULL;
|
|
||||||
|
|
||||||
if(switch_threadattr_create(
|
|
||||||
(switch_threadattr_t **)&_thread_info->_attribute, _pool) != 0)
|
|
||||||
{
|
|
||||||
_thread_info->_attribute = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_threadattr_stacksize_set(
|
|
||||||
(switch_threadattr_t *)_thread_info->_attribute,
|
|
||||||
SWITCH_THREAD_STACKSIZE);
|
|
||||||
|
|
||||||
if(!priority())
|
|
||||||
{
|
|
||||||
_thread_info->_attribute = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename A>
|
|
||||||
Thread(T obj, A arg, switch_memory_pool_t *pool=NULL) :
|
|
||||||
_thread_info(new ThreadData<T, typename DecomposeFunction<T>::Return, A>(obj, arg)),
|
|
||||||
_pool(pool),
|
|
||||||
_can_delete_pool(false)
|
|
||||||
{
|
|
||||||
if(!_pool)
|
|
||||||
{
|
|
||||||
switch_core_new_memory_pool(&_pool);
|
|
||||||
_can_delete_pool = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_thread_info->_thread = this;
|
|
||||||
_thread_info->_self = NULL;
|
|
||||||
_thread_info->_attribute = NULL;
|
|
||||||
|
|
||||||
if(switch_threadattr_create(
|
|
||||||
(switch_threadattr_t **)&_thread_info->_attribute, _pool) != 0)
|
|
||||||
{
|
|
||||||
_thread_info->_attribute = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_threadattr_stacksize_set(
|
|
||||||
(switch_threadattr_t *)_thread_info->_attribute,
|
|
||||||
SWITCH_THREAD_STACKSIZE);
|
|
||||||
|
|
||||||
if(!priority())
|
|
||||||
{
|
|
||||||
_thread_info->_attribute = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
~Thread()
|
|
||||||
{
|
|
||||||
if(_thread_info)
|
|
||||||
delete _thread_info;
|
|
||||||
|
|
||||||
if (_can_delete_pool)
|
|
||||||
switch_core_destroy_memory_pool(&_pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
void detach(bool d = true)
|
|
||||||
{
|
|
||||||
if(!_thread_info->_attribute)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Non-zero if detached threads should be created. */
|
|
||||||
switch_threadattr_detach_set(
|
|
||||||
(switch_threadattr_t *)_thread_info->_attribute, d ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool start()
|
|
||||||
{
|
|
||||||
if(!_pool || !_thread_info->_attribute)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch_thread_create((switch_thread_t**)&_thread_info->_self,
|
|
||||||
(switch_threadattr_t *)_thread_info->_attribute,
|
|
||||||
run,
|
|
||||||
_thread_info,
|
|
||||||
_pool);
|
|
||||||
|
|
||||||
if(!_thread_info->_self)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int join()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* block until the desired thread stops executing.
|
|
||||||
* @param retval The return value from the dead thread.
|
|
||||||
* @param thd The thread to join
|
|
||||||
*
|
|
||||||
* SWITCH_DECLARE(switch_status_t) switch_thread_join(switch_status_t *retval, switch_thread_t *thd);
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(!_thread_info->_self)
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
int retval = 0;
|
|
||||||
|
|
||||||
if(switch_thread_join((switch_status_t*)&retval,
|
|
||||||
(switch_thread_t *)_thread_info->_self) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseThreadType * self()
|
|
||||||
{
|
|
||||||
//switch_thread_self();
|
|
||||||
//apr_os_thread_current();
|
|
||||||
return (BaseThreadType *)_thread_info->_self;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void exit(int status)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* stop the current thread
|
|
||||||
* @param thd The thread to stop
|
|
||||||
* @param retval The return value to pass back to any thread that cares
|
|
||||||
*/
|
|
||||||
//SWITCH_DECLARE(switch_status_t) switch_thread_exit(switch_thread_t *thd, switch_status_t retval);
|
|
||||||
switch_thread_exit((switch_thread_t *)_thread_info->_self, (switch_status_t)status);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
struct apr_threadattr_t {
|
|
||||||
apr_pool_t *pool;
|
|
||||||
pthread_attr_t attr;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool priority()
|
|
||||||
{
|
|
||||||
#ifndef WIN32
|
|
||||||
struct sched_param param;
|
|
||||||
|
|
||||||
struct apr_threadattr_t *myattr = (struct apr_threadattr_t *)_thread_info->_attribute;
|
|
||||||
|
|
||||||
if (pthread_attr_setschedpolicy(
|
|
||||||
(pthread_attr_t *)&myattr->attr, SCHED_RR) < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (pthread_attr_getschedparam(
|
|
||||||
(pthread_attr_t *)&myattr->attr, ¶m) < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
param.sched_priority = sched_get_priority_max(SCHED_RR);
|
|
||||||
|
|
||||||
if (pthread_attr_setschedparam(
|
|
||||||
(pthread_attr_t *)&myattr->attr, ¶m) < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
//BUG in Freeswitch
|
|
||||||
|
|
||||||
THANKS FOR NOT REPORTING IT SO WE MUST LIVE WITH A PROBLEM YOU KNOW ABOUT .....
|
|
||||||
|
|
||||||
if(switch_threadattr_priority_increase(
|
|
||||||
(switch_threadattr_t *)_thread_info->_attribute) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ThreadDataCommon * _thread_info;
|
|
||||||
switch_memory_pool_t *_pool;
|
|
||||||
bool _can_delete_pool;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
static void *SWITCH_THREAD_FUNC run(BaseThreadType *thread, void * obj)
|
|
||||||
{
|
|
||||||
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
|
||||||
// "Starting new Thread\n");
|
|
||||||
|
|
||||||
ThreadDataCommon * data = (ThreadDataCommon *)obj;
|
|
||||||
int retval = data->run();
|
|
||||||
|
|
||||||
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
|
||||||
// "Stopping new Thread = %d\n", retval);
|
|
||||||
|
|
||||||
((Thread *)(data->_thread))->exit(retval);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _THREAD_HPP_ */
|
|
|
@ -1,313 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _TAGGED_UNION_HPP_
|
|
||||||
#define _TAGGED_UNION_HPP_
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <typeinfo>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <format.hpp>
|
|
||||||
|
|
||||||
namespace Tagged
|
|
||||||
{
|
|
||||||
struct EmptyUnion
|
|
||||||
{
|
|
||||||
friend class Value;
|
|
||||||
|
|
||||||
EmptyUnion()
|
|
||||||
: _adjusted(false) {};
|
|
||||||
|
|
||||||
// copy constructor
|
|
||||||
EmptyUnion(const EmptyUnion & o)
|
|
||||||
: _adjusted(o._adjusted) {};
|
|
||||||
|
|
||||||
// copy assignment operator
|
|
||||||
EmptyUnion & operator=(const EmptyUnion & o)
|
|
||||||
{
|
|
||||||
_adjusted = o._adjusted;
|
|
||||||
return *this;
|
|
||||||
};
|
|
||||||
|
|
||||||
~EmptyUnion() { _adjusted = false; };
|
|
||||||
|
|
||||||
bool operator==(const EmptyUnion & o) const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
void clear(void) { _adjusted = false; };
|
|
||||||
protected:
|
|
||||||
void setup(void) { _adjusted = true; };
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool value_set(void) const { return false; };
|
|
||||||
bool value_get(void) const { return false; };
|
|
||||||
|
|
||||||
bool value_check(void) const { return false; };
|
|
||||||
|
|
||||||
template < typename S >
|
|
||||||
bool value_visit(S & visitor, typename S::ReturnType & ret) const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename S >
|
|
||||||
bool value_visit_void(S & visitor) const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool adjusted() const { return _adjusted; };
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool _adjusted;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename V, typename E = EmptyUnion >
|
|
||||||
struct Union: public E
|
|
||||||
{
|
|
||||||
friend class Value;
|
|
||||||
|
|
||||||
// default constructor
|
|
||||||
Union()
|
|
||||||
: _value(0) {};
|
|
||||||
|
|
||||||
// constructor with initializer
|
|
||||||
template < typename U >
|
|
||||||
Union(U value)
|
|
||||||
: _value(0)
|
|
||||||
{
|
|
||||||
set(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
// copy constructor
|
|
||||||
Union(const Union & o)
|
|
||||||
: E(static_cast<const E&>(o)),
|
|
||||||
_value( (o._value ? new V(*(o._value)) : 0) )
|
|
||||||
{};
|
|
||||||
|
|
||||||
// copy assignment operator
|
|
||||||
Union & operator=(const Union & o)
|
|
||||||
{
|
|
||||||
if (_value)
|
|
||||||
{
|
|
||||||
delete _value;
|
|
||||||
_value = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o._value)
|
|
||||||
{
|
|
||||||
_value = new V(*(o._value));
|
|
||||||
}
|
|
||||||
|
|
||||||
E::operator=(static_cast<const E&>(o));
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
};
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
~Union()
|
|
||||||
{
|
|
||||||
if (_value)
|
|
||||||
{
|
|
||||||
delete _value;
|
|
||||||
_value = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// equal sign operator
|
|
||||||
template < typename U >
|
|
||||||
void operator=(U value)
|
|
||||||
{
|
|
||||||
set(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename U >
|
|
||||||
bool check(void) const
|
|
||||||
{
|
|
||||||
return value_check(static_cast< const U * const>(0));
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename U >
|
|
||||||
U & get(void) const
|
|
||||||
{
|
|
||||||
U * res = 0;
|
|
||||||
|
|
||||||
if (!E::adjusted())
|
|
||||||
throw std::runtime_error("tagged union empty!");
|
|
||||||
|
|
||||||
if (!value_get(&res) || !res)
|
|
||||||
throw std::runtime_error(STG(FMT("type mismatch when asked for '%s'") % typeid(U).name()));
|
|
||||||
|
|
||||||
return *res;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename U >
|
|
||||||
void set(U val)
|
|
||||||
{
|
|
||||||
if (E::adjusted())
|
|
||||||
clear();
|
|
||||||
|
|
||||||
if (!value_set(val))
|
|
||||||
throw std::runtime_error("unable to set value of invalid type");
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename S >
|
|
||||||
typename S::ReturnType visit(S visitor) const
|
|
||||||
{
|
|
||||||
typename S::ReturnType ret;
|
|
||||||
|
|
||||||
if (!value_visit(visitor, ret))
|
|
||||||
throw std::runtime_error("unable to visit empty value");
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename S >
|
|
||||||
void visit_void(S visitor) const
|
|
||||||
{
|
|
||||||
if (!value_visit_void(visitor))
|
|
||||||
throw std::runtime_error("unable to visit empty value");
|
|
||||||
};
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
if (_value)
|
|
||||||
{
|
|
||||||
delete _value;
|
|
||||||
_value = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
E::clear();
|
|
||||||
};
|
|
||||||
|
|
||||||
// compare (equal) operator
|
|
||||||
bool operator==(const Union & o) const
|
|
||||||
{
|
|
||||||
bool are_equal = false;
|
|
||||||
|
|
||||||
if (!_value && !(o._value))
|
|
||||||
are_equal = true;
|
|
||||||
|
|
||||||
if (_value && o._value)
|
|
||||||
are_equal = (*_value == *(o._value));
|
|
||||||
|
|
||||||
if (are_equal)
|
|
||||||
return E::operator==(static_cast<const E&>(o));
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// compare types
|
|
||||||
bool sameType(const Union & o) const
|
|
||||||
{
|
|
||||||
if ((!(_value) && !(o._value)) || (_value && o._value))
|
|
||||||
return E::operator==(static_cast<const E&>(o));
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
using E::value_set;
|
|
||||||
using E::value_get;
|
|
||||||
|
|
||||||
using E::value_check;
|
|
||||||
using E::value_visit;
|
|
||||||
using E::value_visit_void;
|
|
||||||
|
|
||||||
bool value_set(V val)
|
|
||||||
{
|
|
||||||
_value = new V(val);
|
|
||||||
E::setup();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool value_get(V ** val) const
|
|
||||||
{
|
|
||||||
if (!_value)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*val = _value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool value_check(const V * const junk) const
|
|
||||||
{
|
|
||||||
(void)junk;
|
|
||||||
return (_value != 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename S >
|
|
||||||
bool value_visit(S & visitor, typename S::ReturnType & ret) const
|
|
||||||
{
|
|
||||||
if (_value)
|
|
||||||
{
|
|
||||||
ret = visitor(*const_cast<V*>(_value));
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return E::value_visit(visitor, ret);
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename S >
|
|
||||||
bool value_visit_void(S & visitor) const
|
|
||||||
{
|
|
||||||
if (_value)
|
|
||||||
{
|
|
||||||
visitor(*const_cast<V*>(_value));
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return E::value_visit_void(visitor);
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
V * _value;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _TAGGED_UNION_HPP_ */
|
|
|
@ -1,103 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _THREAD_COMMON_HPP_
|
|
||||||
#define _THREAD_COMMON_HPP_
|
|
||||||
|
|
||||||
#include <config_commons.hpp>
|
|
||||||
|
|
||||||
#include <types.hpp>
|
|
||||||
//#include <function.hpp>
|
|
||||||
|
|
||||||
struct ThreadCommon
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
template<typename FuncPtrType>
|
|
||||||
struct DecomposeFuncPtr;
|
|
||||||
|
|
||||||
template<typename ReturnType, typename ArgType>
|
|
||||||
struct DecomposeFuncPtr<ReturnType(*)(ArgType)>
|
|
||||||
{
|
|
||||||
typedef ReturnType Return;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename SomeClass>
|
|
||||||
struct DecomposeFuncPtr
|
|
||||||
{
|
|
||||||
typedef void Return;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ReturnType>
|
|
||||||
struct DecomposeFuncPtr<ReturnType(*)()>
|
|
||||||
{
|
|
||||||
typedef ReturnType Return;
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename FunctionType >
|
|
||||||
struct DecomposeFunction
|
|
||||||
{
|
|
||||||
typedef typename Select < IsClass< FunctionType >::Result, int,
|
|
||||||
typename DecomposeFuncPtr< FunctionType >::Return >::Result
|
|
||||||
Return;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
struct ThreadDataCommon
|
|
||||||
{
|
|
||||||
ThreadDataCommon() {}
|
|
||||||
|
|
||||||
virtual ~ThreadDataCommon() {}
|
|
||||||
|
|
||||||
virtual int run() = 0;
|
|
||||||
|
|
||||||
ThreadCommon * _thread;
|
|
||||||
|
|
||||||
void * _self;
|
|
||||||
void * _attribute;
|
|
||||||
};
|
|
||||||
|
|
||||||
ThreadCommon() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#include COMMONS_INCLUDE(thread.hpp)
|
|
||||||
|
|
||||||
#endif /* _THREAD_COMMON_HPP_ */
|
|
|
@ -1,366 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <timer.hpp>
|
|
||||||
|
|
||||||
TimerTraits::TimerTraits()
|
|
||||||
: _thread((Thread*)0), _purify(false), _last_tick(0), _age_count(0), _shutdown(false)
|
|
||||||
{};
|
|
||||||
|
|
||||||
bool TimerTraits::start (void)
|
|
||||||
{
|
|
||||||
_shutdown = false;
|
|
||||||
|
|
||||||
_condition.reset();
|
|
||||||
_finalized.reset();
|
|
||||||
|
|
||||||
if (!_thread)
|
|
||||||
{
|
|
||||||
_thread = new Thread(TimerTraits::loop_thread(this));
|
|
||||||
_purify = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_WINDOWS) || defined(_Windows) || defined(_WIN32) || defined(WIN32)
|
|
||||||
// set priority ...
|
|
||||||
#else
|
|
||||||
pthread_attr_t attrs;
|
|
||||||
sched_param param;
|
|
||||||
|
|
||||||
if (pthread_attr_init(&attrs) < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (pthread_attr_setschedpolicy(&attrs, SCHED_RR) < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (pthread_attr_getschedparam(&attrs, ¶m) < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
param.sched_priority = sched_get_priority_max(SCHED_RR);
|
|
||||||
|
|
||||||
if (pthread_attr_setschedparam(&attrs, ¶m) < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// set priority...
|
|
||||||
|
|
||||||
// if (pthread_create(&_thread, &attrs, TimerTraits::loop_thread, NULL) < 0)
|
|
||||||
// return false;
|
|
||||||
|
|
||||||
_thread->start();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TimerTraits::stop (void)
|
|
||||||
{
|
|
||||||
_shutdown = true;
|
|
||||||
|
|
||||||
_condition.signal();
|
|
||||||
|
|
||||||
_finalized.wait(10000); /* 10 seconds max wait */
|
|
||||||
|
|
||||||
if (_thread && _purify)
|
|
||||||
{
|
|
||||||
delete _thread;
|
|
||||||
|
|
||||||
_thread = (Thread *)0;
|
|
||||||
_purify = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------
|
|
||||||
|
|
||||||
int TimerTraits::loop_thread::operator()(void)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_timer->loop();
|
|
||||||
}
|
|
||||||
catch( ... )
|
|
||||||
{
|
|
||||||
/* something wrong happened! */
|
|
||||||
}
|
|
||||||
|
|
||||||
_timer->_finalized.signal();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimerTraits::execute(ControlSet::iterator init, const TimerTraits::Control & ctrl)
|
|
||||||
{
|
|
||||||
volatile CallbackFuncType func = (volatile CallbackFuncType) ctrl._func;
|
|
||||||
volatile CallbackDataType data = (volatile CallbackDataType) ctrl._data;
|
|
||||||
|
|
||||||
_timer_set.erase(init);
|
|
||||||
|
|
||||||
_mutex.unlock();
|
|
||||||
|
|
||||||
func(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimerTraits::loop (void)
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (_shutdown) break;
|
|
||||||
|
|
||||||
_mutex.lock();
|
|
||||||
|
|
||||||
ControlSet::iterator init = _timer_set.begin();
|
|
||||||
|
|
||||||
if (init == _timer_set.end())
|
|
||||||
{
|
|
||||||
_mutex.unlock();
|
|
||||||
_condition.wait();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const Control & ctrl = *init;
|
|
||||||
|
|
||||||
unsigned int ts_now = TimerTraits::tick();
|
|
||||||
|
|
||||||
if (_age_count == ctrl._age)
|
|
||||||
{
|
|
||||||
if (ts_now < ctrl._msecs)
|
|
||||||
{
|
|
||||||
/* age is right, but it is not time to expire yet... */
|
|
||||||
volatile unsigned int wait_time = ctrl._msecs - ts_now;
|
|
||||||
_mutex.unlock();
|
|
||||||
_condition.wait(wait_time); /* expire - now */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* age is right, and we should expire! */
|
|
||||||
execute(init, ctrl); /* called locked, return unlocked */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_age_count < ctrl._age)
|
|
||||||
{
|
|
||||||
/* age is not there yet (need some time to overlap)... */
|
|
||||||
volatile unsigned int wait_time = (UINT_MAX - ts_now) + ctrl._msecs;
|
|
||||||
_mutex.unlock();
|
|
||||||
_condition.wait(wait_time); /* MAX - now + expire */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* age has passed, we should have expired before! */
|
|
||||||
execute(init, ctrl); /* called locked, return unlocked */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_finalized.signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int TimerTraits::tick()
|
|
||||||
{
|
|
||||||
#if defined(_WINDOWS) || defined(_Windows) || defined(_WIN32) || defined(WIN32)
|
|
||||||
unsigned int tick = GetTickCount();
|
|
||||||
#else
|
|
||||||
struct timespec ticks;
|
|
||||||
|
|
||||||
// error condition, make the user notice this..
|
|
||||||
if (clock_gettime(CLOCK_MONOTONIC, &ticks) < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
unsigned int tick = ( ticks.tv_sec * 1000 ) + ( ticks.tv_nsec / 1000000 );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (_last_tick > tick)
|
|
||||||
++_age_count;
|
|
||||||
|
|
||||||
_last_tick = tick;
|
|
||||||
|
|
||||||
return tick;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------
|
|
||||||
|
|
||||||
TimerTraits::Index TimerTraits::traits_add_unlocked (unsigned int msecs, const void * func, const void * data, unsigned int value)
|
|
||||||
{
|
|
||||||
unsigned int ms_tick = TimerTraits::tick();
|
|
||||||
|
|
||||||
unsigned int ms_left = UINT_MAX - ms_tick;
|
|
||||||
unsigned int ms_real = msecs;
|
|
||||||
|
|
||||||
unsigned int age_num = _age_count;
|
|
||||||
|
|
||||||
if (ms_left < msecs)
|
|
||||||
{
|
|
||||||
ms_real -= ms_left;
|
|
||||||
++age_num;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ms_real += ms_tick;
|
|
||||||
}
|
|
||||||
|
|
||||||
ControlSet::iterator it = _timer_set.insert(Control(age_num,ms_real,func,data,value));
|
|
||||||
|
|
||||||
if (_timer_set.size() == 1 || _timer_set.begin() == it)
|
|
||||||
{
|
|
||||||
_condition.signal();
|
|
||||||
};
|
|
||||||
|
|
||||||
return Index(age_num, ms_real, msecs, func, data, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
TimerTraits::Index TimerTraits::traits_add (unsigned int msecs, const void * func, const void * data, unsigned int value)
|
|
||||||
{
|
|
||||||
_mutex.lock();
|
|
||||||
|
|
||||||
Index idx = traits_add_unlocked(msecs, func, data, value);
|
|
||||||
|
|
||||||
_mutex.unlock();
|
|
||||||
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TimerTraits::traits_restart (TimerTraits::Index & idx, bool force)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
_mutex.lock();
|
|
||||||
|
|
||||||
if (idx.valid)
|
|
||||||
{
|
|
||||||
if (traits_del_unlocked(idx) || force)
|
|
||||||
{
|
|
||||||
idx = traits_add_unlocked(idx.delta, idx.func, idx.data, idx.value);
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_mutex.unlock();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimerTraits::traits_setup(TimerTraits::Index * idx, unsigned int msecs, const void * func, void * data, unsigned int value)
|
|
||||||
{
|
|
||||||
_mutex.lock();
|
|
||||||
|
|
||||||
if (idx->valid)
|
|
||||||
{
|
|
||||||
(void)traits_del_unlocked(*idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
*idx = traits_add_unlocked(msecs, func, data, value);
|
|
||||||
|
|
||||||
_mutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TimerTraits::traits_del_unlocked (TimerTraits::Index & idx)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
if (idx.valid)
|
|
||||||
{
|
|
||||||
ControlSet::iterator i = _timer_set.lower_bound(Control(idx.era, idx.msec));
|
|
||||||
ControlSet::iterator j = _timer_set.upper_bound(Control(idx.era, idx.msec));
|
|
||||||
|
|
||||||
for (; i != j; i++)
|
|
||||||
{
|
|
||||||
const Control & ctrl = (*i);
|
|
||||||
|
|
||||||
if ((idx.value && !(ctrl._value & idx.value)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (((idx.func && ctrl._func == idx.func) || !idx.func) && ((idx.data && ctrl._data == idx.data) || !idx.data))
|
|
||||||
{
|
|
||||||
if (_timer_set.begin() == i)
|
|
||||||
_condition.signal();
|
|
||||||
|
|
||||||
_timer_set.erase(i);
|
|
||||||
|
|
||||||
ret = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
idx.valid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TimerTraits::traits_del (TimerTraits::Index & idx)
|
|
||||||
{
|
|
||||||
_mutex.lock();
|
|
||||||
|
|
||||||
bool ret = traits_del_unlocked(idx);
|
|
||||||
|
|
||||||
_mutex.unlock();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TimerTraits::traits_del (const void * func, const void * data, unsigned int value)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
_mutex.lock();
|
|
||||||
|
|
||||||
for (ControlSet::iterator i = _timer_set.begin(); i != _timer_set.end(); i++)
|
|
||||||
{
|
|
||||||
const Control & ctrl = (*i);
|
|
||||||
|
|
||||||
if ((value && !(ctrl._value & value)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (((func && ctrl._func == func) || !func) && ((data && ctrl._data == data) || !data))
|
|
||||||
{
|
|
||||||
if (_timer_set.begin() == i)
|
|
||||||
_condition.signal();
|
|
||||||
|
|
||||||
_timer_set.erase(i);
|
|
||||||
|
|
||||||
ret = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_mutex.unlock();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
|
@ -1,231 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(_WINDOWS) || defined(_Windows) || defined(_WIN32) || defined(WIN32)
|
|
||||||
#include <windows.h>
|
|
||||||
#else
|
|
||||||
#include <sched.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
#include <simple_lock.hpp>
|
|
||||||
#include <saved_condition.hpp>
|
|
||||||
#include <thread.hpp>
|
|
||||||
#include <refcounter.hpp>
|
|
||||||
|
|
||||||
#ifndef _TIMER_HPP_
|
|
||||||
#define _TIMER_HPP_
|
|
||||||
|
|
||||||
struct TimerTraits
|
|
||||||
{
|
|
||||||
typedef bool (* CallbackFuncType)(const void * volatile);
|
|
||||||
typedef const void * CallbackDataType;
|
|
||||||
|
|
||||||
TimerTraits();
|
|
||||||
|
|
||||||
virtual ~TimerTraits() {};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/* pre-declaration, used below */
|
|
||||||
struct ControlCompare;
|
|
||||||
|
|
||||||
struct Control
|
|
||||||
{
|
|
||||||
Control(unsigned int age, unsigned int msecs, const void * func = 0, const void * data = 0, unsigned int value = 0)
|
|
||||||
: _age(age), _msecs(msecs), _func(func), _data(data), _value(value) {}
|
|
||||||
|
|
||||||
unsigned int _age;
|
|
||||||
|
|
||||||
unsigned int _msecs;
|
|
||||||
|
|
||||||
const void * _func;
|
|
||||||
const void * _data;
|
|
||||||
|
|
||||||
unsigned int _value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ControlCompare
|
|
||||||
{
|
|
||||||
bool operator()(const Control & c1, const Control & c2) const
|
|
||||||
{
|
|
||||||
return (c1._age < c2._age ? true : c1._msecs < c2._msecs);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::multiset < Control, ControlCompare > ControlSet;
|
|
||||||
|
|
||||||
public:
|
|
||||||
struct Index
|
|
||||||
{
|
|
||||||
Index(): era(0), msec(0), valid(false) {};
|
|
||||||
|
|
||||||
Index(unsigned int _era, unsigned int _msec, unsigned int _delta, const void * _func, const void * _data, unsigned int _value)
|
|
||||||
: era(_era), msec(_msec), delta(_delta), func(_func), data(_data), value(_value), valid(true) {};
|
|
||||||
|
|
||||||
unsigned int era;
|
|
||||||
unsigned int msec;
|
|
||||||
|
|
||||||
unsigned int delta;
|
|
||||||
|
|
||||||
const void * func;
|
|
||||||
const void * data;
|
|
||||||
|
|
||||||
unsigned int value;
|
|
||||||
|
|
||||||
bool valid;
|
|
||||||
|
|
||||||
void reset(void) { era = 0; msec = 0; valid = false; };
|
|
||||||
};
|
|
||||||
|
|
||||||
/* timer add/remove functions */
|
|
||||||
Index traits_add (unsigned int msecs, const void * func, const void * data = 0, unsigned int value = 0);
|
|
||||||
|
|
||||||
bool traits_restart (Index & idx, bool force);
|
|
||||||
|
|
||||||
bool traits_del (Index & idx);
|
|
||||||
bool traits_del (const void * func, const void * data = 0, unsigned int value = 0);
|
|
||||||
|
|
||||||
void traits_setup(Index * idx, unsigned int msecs, const void * func, void * data = 0, unsigned int value = 0);
|
|
||||||
|
|
||||||
/* timer start/stop functions */
|
|
||||||
bool start(void);
|
|
||||||
bool stop(void);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Index traits_add_unlocked (unsigned int msecs, const void * func, const void * data, unsigned int value);
|
|
||||||
|
|
||||||
bool traits_del_unlocked (Index & idx);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void execute(ControlSet::iterator, const Control &);
|
|
||||||
|
|
||||||
void loop(void);
|
|
||||||
|
|
||||||
struct loop_thread
|
|
||||||
{
|
|
||||||
loop_thread(TimerTraits *timer) : _timer(timer) {};
|
|
||||||
|
|
||||||
int operator()(void);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
TimerTraits * _timer;
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned int tick();
|
|
||||||
|
|
||||||
/* variables */
|
|
||||||
|
|
||||||
SavedCondition _condition;
|
|
||||||
|
|
||||||
SimpleLock _mutex;
|
|
||||||
Thread * _thread;
|
|
||||||
bool _purify;
|
|
||||||
|
|
||||||
ControlSet _timer_set;
|
|
||||||
|
|
||||||
unsigned int _last_tick;
|
|
||||||
unsigned int _age_count;
|
|
||||||
|
|
||||||
SavedCondition _finalized;
|
|
||||||
bool _shutdown;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename F, typename D >
|
|
||||||
struct TimerTemplate: COUNTER_SUPER(TimerTemplate< F, D >)
|
|
||||||
{
|
|
||||||
typedef TimerTraits::Index Index;
|
|
||||||
typedef TimerTraits::Control Control;
|
|
||||||
|
|
||||||
TimerTemplate()
|
|
||||||
: _timer(new TimerTraits())
|
|
||||||
{};
|
|
||||||
|
|
||||||
TimerTemplate(const TimerTemplate< F, D > & o)
|
|
||||||
: COUNTER_REFER(o, TimerTemplate< F, D >),
|
|
||||||
_timer(o._timer)
|
|
||||||
{};
|
|
||||||
|
|
||||||
void unreference(void)
|
|
||||||
{
|
|
||||||
if (_timer)
|
|
||||||
delete _timer;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool start() { return _timer->start(); }
|
|
||||||
bool stop() { return _timer->stop(); }
|
|
||||||
|
|
||||||
inline void setup(Index * idx, unsigned int msecs, F * func, D data = 0, unsigned int value = 0)
|
|
||||||
{
|
|
||||||
_timer->traits_setup(idx, msecs, (const void *)func, (void *)(data), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Index add(unsigned int msecs, F * func, D data = 0, unsigned int value = 0)
|
|
||||||
{
|
|
||||||
return _timer->traits_add(msecs, (const void *)func, (void *)(data), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool restart(Index & idx, bool force = false)
|
|
||||||
{
|
|
||||||
return _timer->traits_restart(idx, force);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool del(Index & idx)
|
|
||||||
{
|
|
||||||
return _timer->traits_del(idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool del(F * func, D data, unsigned int value = 0)
|
|
||||||
{
|
|
||||||
return _timer->traits_del((const void *)func, (void *)(data), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool del(unsigned int value)
|
|
||||||
{
|
|
||||||
return _timer->traits_del((const void *)0, (void *)0, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
TimerTraits * _timer;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _TIMER_HPP_ */
|
|
|
@ -1,99 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _TYPES_HPP_
|
|
||||||
#define _TYPES_HPP_
|
|
||||||
|
|
||||||
/*** Used for conditional compilation based on K3L version ***/
|
|
||||||
|
|
||||||
#define K3L_AT_LEAST(major,minor,build) \
|
|
||||||
(((k3lApiMajorVersion == major) && ((k3lApiMinorVersion == minor) && (k3lApiBuildVersion >= build)) || \
|
|
||||||
((k3lApiMajorVersion == major) && (k3lApiMinorVersion > minor))) || \
|
|
||||||
(k3lApiMajorVersion > major))
|
|
||||||
|
|
||||||
#define K3L_EXACT(major,minor,build) \
|
|
||||||
((k3lApiMajorVersion == major) && (k3lApiMinorVersion == minor) && (k3lApiBuildVersion >= build))
|
|
||||||
|
|
||||||
/*** Used for checking information on classes and stuff.. ***/
|
|
||||||
|
|
||||||
template< typename T >
|
|
||||||
struct IsClass
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
template < typename X > static char ( &A( void(X::*)() ) )[1];
|
|
||||||
template < typename X > static char ( &A( X ) )[2];
|
|
||||||
public:
|
|
||||||
static bool const Result = sizeof( A< T >(0) ) == 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
struct IsConst
|
|
||||||
{
|
|
||||||
static bool const Result = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
struct IsConst< const T >
|
|
||||||
{
|
|
||||||
static bool const Result = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
struct IsConst< T const * >
|
|
||||||
{
|
|
||||||
static bool const Result = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*** Used for template metaprogramming ***/
|
|
||||||
|
|
||||||
template < bool Value, typename Then, typename Else >
|
|
||||||
struct Select
|
|
||||||
{
|
|
||||||
typedef Then Result;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename Then, typename Else >
|
|
||||||
struct Select < false, Then, Else >
|
|
||||||
{
|
|
||||||
typedef Else Result;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _TYPES_HPP_ */
|
|
|
@ -1,124 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the "LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <refcounter.hpp>
|
|
||||||
|
|
||||||
#ifndef _VARIABLE_HPP_
|
|
||||||
#define _VARIABLE_HPP_
|
|
||||||
|
|
||||||
template < typename R >
|
|
||||||
struct VariableBaseTable
|
|
||||||
{
|
|
||||||
R value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EmptyVariable {};
|
|
||||||
|
|
||||||
template < typename R >
|
|
||||||
struct Variable
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
typedef VariableBaseTable< R > BaseType;
|
|
||||||
|
|
||||||
typedef const BaseType * ConstObjType;
|
|
||||||
typedef BaseType * ObjType;
|
|
||||||
typedef R BaseType::* VarType;
|
|
||||||
|
|
||||||
public:
|
|
||||||
template < typename ConstructorObjType >
|
|
||||||
Variable(R ConstructorObjType::* v)
|
|
||||||
: _adjusted(true),
|
|
||||||
_variable(reinterpret_cast<const VarType>(v))
|
|
||||||
{};
|
|
||||||
|
|
||||||
Variable()
|
|
||||||
: _adjusted(false)
|
|
||||||
{};
|
|
||||||
|
|
||||||
template < typename MemberType >
|
|
||||||
void operator=(const MemberType v)
|
|
||||||
{
|
|
||||||
_adjusted = true;
|
|
||||||
_variable = reinterpret_cast<const VarType>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Type >
|
|
||||||
R & operator()(Type * obj) const
|
|
||||||
{
|
|
||||||
if (!_adjusted)
|
|
||||||
throw EmptyVariable();
|
|
||||||
|
|
||||||
return (reinterpret_cast< ObjType >(obj))->*(_variable);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Type >
|
|
||||||
R & operator()(Type & obj) const
|
|
||||||
{
|
|
||||||
if (!_adjusted)
|
|
||||||
throw EmptyVariable();
|
|
||||||
|
|
||||||
return (reinterpret_cast< ObjType >(&obj))->*(_variable);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Type >
|
|
||||||
const R & operator()(const Type * obj) const
|
|
||||||
{
|
|
||||||
if (!_adjusted)
|
|
||||||
throw EmptyVariable();
|
|
||||||
|
|
||||||
return (reinterpret_cast< ConstObjType >(obj))->*(_variable);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename Type >
|
|
||||||
const R & operator()(const Type & obj) const
|
|
||||||
{
|
|
||||||
if (!_adjusted)
|
|
||||||
throw EmptyVariable();
|
|
||||||
|
|
||||||
return (reinterpret_cast< ConstObjType >(&obj))->*(_variable);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool _adjusted;
|
|
||||||
VarType _variable;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _VARIABLE_HPP_ */
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,303 +0,0 @@
|
||||||
/*
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
||||||
(the "License"); you may not use this file except in compliance with the
|
|
||||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file under
|
|
||||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the LGPL License. If you do not
|
|
||||||
delete the provisions above, a recipient may use your version of this file under
|
|
||||||
either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _VERBOSE_HPP_
|
|
||||||
#define _VERBOSE_HPP_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include <k3l.h>
|
|
||||||
|
|
||||||
// k3lApiMajorVersion
|
|
||||||
#ifndef CM_PING
|
|
||||||
# include <k3lVersion.h>
|
|
||||||
# include <KTools.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <types.hpp>
|
|
||||||
#include <k3lapi.hpp>
|
|
||||||
#include <format.hpp>
|
|
||||||
|
|
||||||
#include <verbose_traits.hpp>
|
|
||||||
|
|
||||||
struct Verbose
|
|
||||||
{
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
R2_COUNTRY_BRA = 1,
|
|
||||||
R2_COUNTRY_ARG = 2,
|
|
||||||
R2_COUNTRY_CHI = 3,
|
|
||||||
R2_COUNTRY_MEX = 4,
|
|
||||||
R2_COUNTRY_URY = 5,
|
|
||||||
R2_COUNTRY_VEN = 6
|
|
||||||
}
|
|
||||||
R2CountryType;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
HUMAN,
|
|
||||||
EXACT
|
|
||||||
}
|
|
||||||
Presentation;
|
|
||||||
|
|
||||||
/* dynamic (object) stuff */
|
|
||||||
|
|
||||||
Verbose(const K3LAPI & api)
|
|
||||||
: _api(api) {};
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(2,0,0)
|
|
||||||
std::string event(const int32, const K3L_EVENT * const,
|
|
||||||
const R2CountryType r2_country = R2_COUNTRY_BRA,
|
|
||||||
const Presentation fmt = HUMAN) const;
|
|
||||||
#else
|
|
||||||
std::string event(const int32, const K3L_EVENT * const,
|
|
||||||
const Presentation fmt = HUMAN) const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::string channelStatus(const int32, const int32, const int32,
|
|
||||||
const Presentation fmt = HUMAN) const;
|
|
||||||
|
|
||||||
/* end of dynamic (object) stuff */
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const K3LAPI & _api;
|
|
||||||
|
|
||||||
/* used internally */
|
|
||||||
struct internal_not_found {};
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/* static (class) stuff */
|
|
||||||
|
|
||||||
static std::string echoLocation(const KEchoLocation, const Presentation fmt = HUMAN);
|
|
||||||
static std::string echoCancellerConfig(const KEchoCancellerConfig, const Presentation fmt = HUMAN);
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(2,0,0)
|
|
||||||
static std::string event(const KSignaling, const int32, const K3L_EVENT * const,
|
|
||||||
const R2CountryType = R2_COUNTRY_BRA, Presentation fmt = HUMAN);
|
|
||||||
#else
|
|
||||||
static std::string event(const KSignaling, const int32, const K3L_EVENT * const,
|
|
||||||
const Presentation fmt = HUMAN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(2,0,0)
|
|
||||||
static std::string command(const int32, const K3L_COMMAND * const,
|
|
||||||
const R2CountryType = R2_COUNTRY_BRA,
|
|
||||||
const Presentation fmt = HUMAN);
|
|
||||||
|
|
||||||
static std::string command(const int32, const int32, const int32, const char * const,
|
|
||||||
const R2CountryType = R2_COUNTRY_BRA,
|
|
||||||
const Presentation fmt = HUMAN);
|
|
||||||
#else
|
|
||||||
static std::string command(const int32, const K3L_COMMAND * const,
|
|
||||||
const Presentation fmt = HUMAN);
|
|
||||||
|
|
||||||
static std::string command(const int32, const int32, const int32, const char * const,
|
|
||||||
const Presentation fmt = HUMAN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static std::string deviceName(const KDeviceType, const int32, const int32 count = 0, const Presentation fmt = HUMAN);
|
|
||||||
static std::string deviceName(const KDeviceType, const int32, const Presentation fmt);
|
|
||||||
|
|
||||||
static std::string deviceType(const KDeviceType, const int32 count = 0, const Presentation fmt = HUMAN);
|
|
||||||
static std::string deviceType(const KDeviceType, const Presentation fmt);
|
|
||||||
|
|
||||||
static std::string deviceModel(const KDeviceType, const int32, const int32 count = 0, const Presentation fmt = HUMAN);
|
|
||||||
static std::string deviceModel(const KDeviceType, const int32, const Presentation fmt);
|
|
||||||
|
|
||||||
static std::string channelFeatures(const int32, const Presentation fmt = HUMAN);
|
|
||||||
static std::string signaling(const KSignaling, const Presentation fmt = HUMAN);
|
|
||||||
static std::string systemObject(const KSystemObject, const Presentation fmt = HUMAN);
|
|
||||||
static std::string mixerTone(const KMixerTone, const Presentation fmt = HUMAN);
|
|
||||||
static std::string mixerSource(const KMixerSource, const Presentation fmt = HUMAN);
|
|
||||||
|
|
||||||
static std::string seizeFail(const KSeizeFail, const Presentation fmt = HUMAN);
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(2,0,0)
|
|
||||||
static std::string callFail(const KSignaling, const R2CountryType, const int32, const Presentation fmt = HUMAN);
|
|
||||||
#else
|
|
||||||
static std::string callFail(const KSignaling, const int32, const Presentation fmt = HUMAN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static std::string channelFail(const KSignaling, const int32, const Presentation fmt = HUMAN);
|
|
||||||
static std::string internalFail(const KInternalFail, const Presentation fmt = HUMAN);
|
|
||||||
|
|
||||||
static std::string linkErrorCounter(const KLinkErrorCounter, const Presentation fmt = HUMAN);
|
|
||||||
|
|
||||||
static std::string linkStatus(const KSignaling, const int32, const Presentation fmt = HUMAN, const bool simpleStatus = false);
|
|
||||||
static std::string channelStatus(const KSignaling, const int32, const Presentation fmt = HUMAN);
|
|
||||||
static std::string callStatus(const KCallStatus, const Presentation fmt = HUMAN);
|
|
||||||
static std::string status(const KLibraryStatus, const Presentation fmt = HUMAN);
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(2,0,0)
|
|
||||||
static std::string signGroupB(const KSignGroupB, const R2CountryType contry = R2_COUNTRY_BRA,
|
|
||||||
Presentation fmt = HUMAN);
|
|
||||||
#else
|
|
||||||
static std::string signGroupB(const KSignGroupB, const Presentation fmt = HUMAN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(2,0,0)
|
|
||||||
static std::string signGroupII(const KSignGroupII, const R2CountryType contry = R2_COUNTRY_BRA,
|
|
||||||
Presentation fmt = HUMAN);
|
|
||||||
#else
|
|
||||||
static std::string signGroupII(const KSignGroupII, const Presentation fmt = HUMAN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static std::string h100configIndex(const KH100ConfigIndex, const Presentation fmt = HUMAN);
|
|
||||||
|
|
||||||
static std::string eventName(const int32 value)
|
|
||||||
{
|
|
||||||
return VerboseTraits::eventName((VerboseTraits::Event)value);
|
|
||||||
};
|
|
||||||
|
|
||||||
static std::string commandName(const int32 value)
|
|
||||||
{
|
|
||||||
return VerboseTraits::commandName((VerboseTraits::Command)value);
|
|
||||||
};
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(1,5,0)
|
|
||||||
static std::string sipFailures(const KSIP_Failures, const Presentation fmt = HUMAN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(1,5,1)
|
|
||||||
static std::string isdnCause(const KQ931Cause, const Presentation fmt = HUMAN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(1,5,2)
|
|
||||||
static std::string isdnDebug(const int32, const Presentation fmt = HUMAN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(1,6,0)
|
|
||||||
static std::string callStartInfo(const KCallStartInfo, const Presentation fmt = HUMAN);
|
|
||||||
|
|
||||||
static std::string gsmCallCause(const KGsmCallCause, const Presentation fmt = HUMAN);
|
|
||||||
static std::string gsmMobileCause(const KGsmMobileCause, const Presentation fmt = HUMAN);
|
|
||||||
static std::string gsmSmsCause(const KGsmSmsCause, const Presentation fmt = HUMAN);
|
|
||||||
|
|
||||||
static std::string q931ProgressIndication(const KQ931ProgressIndication,
|
|
||||||
Presentation fmt = HUMAN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(2,1,0)
|
|
||||||
static std::string faxResult(const KFaxResult code, const Presentation fmt = HUMAN);
|
|
||||||
static std::string faxFileErrorCause(const KFaxFileErrorCause code, const Presentation fmt = HUMAN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* end of static (class) stuff */
|
|
||||||
|
|
||||||
private:
|
|
||||||
static std::string internal_deviceType(const KDeviceType, const int32);
|
|
||||||
static std::string internal_deviceModel(const KDeviceType, const int32, const int32);
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(1,5,0)
|
|
||||||
static std::string internal_sipFailures(const KSIP_Failures, const Presentation fmt = HUMAN);
|
|
||||||
#endif
|
|
||||||
#if K3L_AT_LEAST(1,5,1)
|
|
||||||
static std::string internal_isdnCause(const KQ931Cause, const Presentation fmt = HUMAN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(2,0,0)
|
|
||||||
static std::string internal_signGroupB(const KSignGroupB, const R2CountryType contry, const Presentation fmt = HUMAN);
|
|
||||||
static std::string internal_signGroupII(const KSignGroupII, const R2CountryType contry, const Presentation fmt = HUMAN);
|
|
||||||
#else
|
|
||||||
static std::string internal_signGroupB(const KSignGroupB, const Presentation fmt = HUMAN);
|
|
||||||
static std::string internal_signGroupII(const KSignGroupII, const Presentation fmt = HUMAN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if K3L_AT_LEAST(1,6,0)
|
|
||||||
static std::string internal_gsmCallCause(const KGsmCallCause, const Presentation fmt = HUMAN);
|
|
||||||
static std::string internal_gsmMobileCause(const KGsmMobileCause, const Presentation fmt = HUMAN);
|
|
||||||
static std::string internal_gsmSmsCause(const KGsmSmsCause, const Presentation fmt = HUMAN);
|
|
||||||
|
|
||||||
static std::string internal_q931ProgressIndication(const KQ931ProgressIndication, const Presentation fmt = HUMAN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum Type
|
|
||||||
{
|
|
||||||
DEVICE,
|
|
||||||
CHANNEL,
|
|
||||||
PLAYER,
|
|
||||||
MIXER,
|
|
||||||
LINK,
|
|
||||||
NONE
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Target
|
|
||||||
{
|
|
||||||
Target(Type _type)
|
|
||||||
: type(_type), device(-1), object(-1)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Target(Type _type, int32 _device)
|
|
||||||
: type(_type), device(_device), object(-1)
|
|
||||||
{};
|
|
||||||
|
|
||||||
Target(Type _type, int32 _device, int32 _object)
|
|
||||||
: type(_type), device(_device), object(_object)
|
|
||||||
{};
|
|
||||||
|
|
||||||
const Type type;
|
|
||||||
const int32 device;
|
|
||||||
const int32 object;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void generate(std::string &, const std::string &, const Target, const std::string &);
|
|
||||||
|
|
||||||
static std::string show(std::string &, const std::string &, const Target, const std::string &);
|
|
||||||
static std::string show(std::string &, const std::string &, const Target);
|
|
||||||
|
|
||||||
template < typename ReturnType >
|
|
||||||
static ReturnType presentation(const Presentation fmt, ReturnType str_exact, ReturnType str_human)
|
|
||||||
{
|
|
||||||
switch (fmt)
|
|
||||||
{
|
|
||||||
case HUMAN: return str_human;
|
|
||||||
case EXACT: return str_exact;
|
|
||||||
};
|
|
||||||
|
|
||||||
return str_exact;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _VERBOSE_HPP_ */
|
|
|
@ -1,183 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
cut_defines ()
|
|
||||||
{
|
|
||||||
cut -b9- | cut -f1 | cut -d' ' -f1
|
|
||||||
}
|
|
||||||
|
|
||||||
list_commands ()
|
|
||||||
{
|
|
||||||
egrep -h 'define.+CM_' "$@" | cut_defines
|
|
||||||
}
|
|
||||||
|
|
||||||
list_events ()
|
|
||||||
{
|
|
||||||
# list and remove deprecations
|
|
||||||
egrep -h 'define.+EV_' "$@" | cut_defines | \
|
|
||||||
grep -v 'EV_CALL_PROGRESS\|EV_FAX_MESSAGE_CONFIRMATION'
|
|
||||||
}
|
|
||||||
|
|
||||||
make_enumeration_one_by_one ()
|
|
||||||
{
|
|
||||||
while read line
|
|
||||||
do
|
|
||||||
local size=$[50 - $(expr length "${line}")]
|
|
||||||
|
|
||||||
echo -n " K_${line}"
|
|
||||||
|
|
||||||
for ((i=0;i<size;i++))
|
|
||||||
do
|
|
||||||
echo -n " "
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "= ${line},"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
make_enumeration ()
|
|
||||||
{
|
|
||||||
local name="$1"; shift
|
|
||||||
local func="$1"; shift
|
|
||||||
|
|
||||||
echo " typedef enum"
|
|
||||||
echo " {"
|
|
||||||
"${func}" "$@" | make_enumeration_one_by_one
|
|
||||||
echo " }"
|
|
||||||
echo " ${name};"
|
|
||||||
}
|
|
||||||
|
|
||||||
make_switch_case_one_by_one ()
|
|
||||||
{
|
|
||||||
while read line
|
|
||||||
do
|
|
||||||
local size=$[50 - $(expr length "${line}")]
|
|
||||||
|
|
||||||
echo -n " case K_${line}:"
|
|
||||||
|
|
||||||
for ((i=0;i<size;i++))
|
|
||||||
do
|
|
||||||
echo -n " "
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "return \"${line}\";"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
make_switch_case ()
|
|
||||||
{
|
|
||||||
local type="$1"; shift
|
|
||||||
local name="$1"; shift
|
|
||||||
local func="$1"; shift
|
|
||||||
|
|
||||||
echo "std::string VerboseTraits::${name}Name(const ${type} value)"
|
|
||||||
echo "{"
|
|
||||||
echo " switch(value)"
|
|
||||||
echo " {"
|
|
||||||
"${func}" "$@" | make_switch_case_one_by_one
|
|
||||||
echo " }"
|
|
||||||
echo " return STG(FMT(\"${name}=%d\") % ((int)value));"
|
|
||||||
echo "}"
|
|
||||||
}
|
|
||||||
|
|
||||||
make_license ()
|
|
||||||
{
|
|
||||||
echo '/*'
|
|
||||||
echo ' KHOMP generic endpoint/channel library.'
|
|
||||||
echo ' Copyright (C) 2007-2010 Khomp Ind. & Com.'
|
|
||||||
echo ''
|
|
||||||
echo ' The contents of this file are subject to the Mozilla Public License Version 1.1'
|
|
||||||
echo ' (the "License"); you may not use this file except in compliance with the'
|
|
||||||
echo ' License. You may obtain a copy of the License at http://www.mozilla.org/MPL/'
|
|
||||||
echo ''
|
|
||||||
echo ' Software distributed under the License is distributed on an "AS IS" basis,'
|
|
||||||
echo ' WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for'
|
|
||||||
echo ' the specific language governing rights and limitations under the License.'
|
|
||||||
echo ''
|
|
||||||
echo ' Alternatively, the contents of this file may be used under the terms of the'
|
|
||||||
echo ' "GNU Lesser General Public License 2.1" license (the “LGPL" License), in which'
|
|
||||||
echo ' case the provisions of "LGPL License" are applicable instead of those above.'
|
|
||||||
echo ''
|
|
||||||
echo ' If you wish to allow use of your version of this file only under the terms of'
|
|
||||||
echo ' the LGPL License and not to allow others to use your version of this file under'
|
|
||||||
echo ' the MPL, indicate your decision by deleting the provisions above and replace them'
|
|
||||||
echo ' with the notice and other provisions required by the LGPL License. If you do not'
|
|
||||||
echo ' delete the provisions above, a recipient may use your version of this file under'
|
|
||||||
echo ' either the MPL or the LGPL License.'
|
|
||||||
echo ''
|
|
||||||
echo ' The LGPL header follows below:'
|
|
||||||
echo ''
|
|
||||||
echo ' This library is free software; you can redistribute it and/or'
|
|
||||||
echo ' modify it under the terms of the GNU Lesser General Public'
|
|
||||||
echo ' License as published by the Free Software Foundation; either'
|
|
||||||
echo ' version 2.1 of the License, or (at your option) any later version.'
|
|
||||||
echo ''
|
|
||||||
echo ' This library is distributed in the hope that it will be useful,'
|
|
||||||
echo ' but WITHOUT ANY WARRANTY; without even the implied warranty of'
|
|
||||||
echo ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU'
|
|
||||||
echo ' Lesser General Public License for more details.'
|
|
||||||
echo ''
|
|
||||||
echo ' You should have received a copy of the GNU Lesser General Public License'
|
|
||||||
echo ' along with this library; if not, write to the Free Software Foundation, Inc.,'
|
|
||||||
echo ' 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA'
|
|
||||||
echo ''
|
|
||||||
echo '*/'
|
|
||||||
|
|
||||||
echo "/* ****************************************************************************** */"
|
|
||||||
echo "/* ******************* AUTO GENERATED FILE - DO NOT EDIT! *********************** */"
|
|
||||||
echo "/* ****************************************************************************** */"
|
|
||||||
echo
|
|
||||||
}
|
|
||||||
|
|
||||||
make_header ()
|
|
||||||
{
|
|
||||||
make_license
|
|
||||||
|
|
||||||
echo "#ifndef _VERBOSE_TRAITS_H_"
|
|
||||||
echo "#define _VERBOSE_TRAITS_H_"
|
|
||||||
echo
|
|
||||||
echo "#include <string>"
|
|
||||||
echo
|
|
||||||
echo "#include <format.hpp>"
|
|
||||||
echo
|
|
||||||
echo "#include <k3l.h>"
|
|
||||||
echo
|
|
||||||
echo "struct VerboseTraits"
|
|
||||||
echo "{"
|
|
||||||
make_enumeration "Command" list_commands "$@" || return 1
|
|
||||||
echo
|
|
||||||
make_enumeration "Event" list_events "$@" || return 1
|
|
||||||
echo
|
|
||||||
echo " static std::string eventName(const Event);"
|
|
||||||
echo " static std::string commandName(const Command);"
|
|
||||||
echo "};"
|
|
||||||
echo
|
|
||||||
echo "#endif /* _VERBOSE_TRAITS_H_ */"
|
|
||||||
}
|
|
||||||
|
|
||||||
make_source ()
|
|
||||||
{
|
|
||||||
make_license
|
|
||||||
|
|
||||||
echo "#include <verbose_traits.hpp>"
|
|
||||||
echo
|
|
||||||
|
|
||||||
make_switch_case "Event" "event" list_events "$@" || return 1
|
|
||||||
echo
|
|
||||||
make_switch_case "Command" "command" list_commands "$@" || return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
make_run ()
|
|
||||||
{
|
|
||||||
local destdir="$1"; shift
|
|
||||||
|
|
||||||
if [ ! -d "${destdir}" ]
|
|
||||||
then
|
|
||||||
echo "ERROR: First argument is not a directory!"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
make_header "$@" > "${destdir}/verbose_traits.hpp"
|
|
||||||
make_source "$@" > "${destdir}/verbose_traits.cpp"
|
|
||||||
}
|
|
||||||
|
|
||||||
make_run "$@"
|
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -1,39 +0,0 @@
|
||||||
<html><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><title>Mod Khomp: README</title></head><body><a name="Guia_R.C3.A1pido" id="Guia_R.C3.A1pido"></a><h1> <span class="mw-headline"> Guia Rápido </span></h1>
|
|
||||||
<p>Depois de instalar a placa no sistema, e executar o programa de instalação pela primeira vez, os <i>drivers</i> e serviços da Khomp serão adicionados na inicialização do sistema, e automaticamente carregados.
|
|
||||||
</p><p>Se o sistema possuir pelo menos uma placa de tronco E1 e/ou uma placa FXO, uma tela de configuração básica deverá ser apresentada ao final do processo, questionando parâmetros de sinalização - no caso de existirem placas E1 - e/ou realizando o ajuste de cadências - no caso de existirem placas FXO.
|
|
||||||
</p><p>Se todas estas etapas foram executadas com sucesso, prossiga para o item <b>Utilizando o <i>Endpoint</i> da Khomp</b>. Caso algum problema ocorra, consulte o <a href=".htmlMod_Khomp/Manual" title="Mod Khomp/Manual">Manual do Endpoint</a>, seguindo para a seção de <a href=".htmlMod_Khomp/Manual#Solu.C3.A7.C3.A3o_de_problemas" title="Mod Khomp/Manual">Solução de problemas</a>.
|
|
||||||
</p>
|
|
||||||
<a name="Utilizando_o_Endpoint_da_Khomp" id="Utilizando_o_Endpoint_da_Khomp"></a><h1> <span class="mw-headline"> Utilizando o <i>Endpoint</i> da Khomp </span></h1>
|
|
||||||
<p>Após a instalação e inicialização dos serviços necessários pela Khomp, o FreeSWITCH já pode ser carregado ou inicializado.
|
|
||||||
</p>
|
|
||||||
<ul><li> <b>AVISO</b>: Evite usar a opção <b>-nort</b>, pois ela desabilita escalonamento em tempo real, é imprescindível que o <b>FreeSWITCH</b> esteja utilizando o escalonamento em tempo real, especialmente se este estiver sendo executado lado-a-lado com servidores <i>web</i> ou servidores de banco de dados. Utilizar a opção <b>-nort</b> pode resultar em perda de qualidade do áudio, gerando um sério comprometimento nas ligações do sistema.
|
|
||||||
</li></ul>
|
|
||||||
<p>Após a inicialização do FreeSWITCH, pode-se verificar se o módulo da Khomp foi carregado através do seguinte comando:<br />
|
|
||||||
</p>
|
|
||||||
<pre> freeswitch@hostname> module_exists mod_khomp
|
|
||||||
</pre>
|
|
||||||
<p>A próxima linha deverá responder algo tipo:
|
|
||||||
</p>
|
|
||||||
<pre> true
|
|
||||||
</pre>
|
|
||||||
<p>Para verificar se o FreeSWITCH reconheceu todas as placas, digite:
|
|
||||||
</p>
|
|
||||||
<pre> freeswitch@hostname> khomp summary
|
|
||||||
</pre>
|
|
||||||
<p>A saída desse comando mostrará detalhes de todas placas reconhecidas.
|
|
||||||
</p><p>No caso de uma placa de tronco E1, pode-se verificar o estado dos links com o seguinte comando:
|
|
||||||
</p>
|
|
||||||
<pre> freeswitch@hostname> khomp show links
|
|
||||||
</pre>
|
|
||||||
<p>O estado dos canais individuais, por sua vez, pode ser aferido com o comando:
|
|
||||||
</p>
|
|
||||||
<pre> freeswitch@hostname> khomp show channels
|
|
||||||
</pre>
|
|
||||||
<p>Para mais detalhes sobre os comandos do Endpoint da khomp digite no console do FreeSWITCH:
|
|
||||||
</p>
|
|
||||||
<pre> freeswitch@hostname> help khomp
|
|
||||||
</pre>
|
|
||||||
<ul><li> <b>IMPORTANTE</b>: Para fazer completo uso da sua placa Khomp, será preciso configurar suas regras de discagem, seja através do arquivo <i>default.xml</i> ou de um aplicativo externo, definindo regras específicas para realizar ao receber ligações.<br /><br />No <a href=".htmlMod_Khomp/Manual" title="Mod Khomp/Manual">Manual do Endpoint</a>, podem ser encontradas informações sobre o formato dos contextos de entrada (responsáveis por receber as ligações) e sobre as opções disponíveis no application Bridge (responsável por realizar ligações) que podem ser utilizadas com o Endpoint da Khomp, além de outras funcionalidades especiais providas pelo mesmo.
|
|
||||||
</li></ul>
|
|
||||||
<p><br />
|
|
||||||
</p></body></html>
|
|
Binary file not shown.
|
@ -1,39 +0,0 @@
|
||||||
<html><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><title>Mod Khomp: README: en</title></head><body><a name="Quick_guide" id="Quick_guide"></a><h1> <span class="mw-headline"> Quick guide </span></h1>
|
|
||||||
<p>After installing the card in the system and run the installation program for the first time, the <i>drivers</i> and Khomp services will be added at system startup, and automatically loaded.
|
|
||||||
</p><p>If your system has at least one E1 trunk card and / or an FXO card, a basic setup screen will be presented at the end of the process, questioning signaling parameters - if there are signs E1 - and/or performing the adjustment cadences - where that FXO cards.
|
|
||||||
</p><p>If all these steps were performed successfully, proceed to the item <b>Using Khomp Endpoint</b>. If a problem occurs, see the <a href=".htmlMod_Khomp/User_Guide" title="Mod Khomp/User Guide">User Guide</a>, in the section <a href=".htmlMod_Khomp/User_Guide#Troubleshooting" title="Mod Khomp/User Guide">Troubleshooting</a>.
|
|
||||||
</p>
|
|
||||||
<a name="Using_the_Khomp_Endpoint" id="Using_the_Khomp_Endpoint"></a><h1> <span class="mw-headline"> Using the Khomp Endpoint </span></h1>
|
|
||||||
<p>After installation and startup services required by Khomp, FreeSWITCH can now be loaded or initialized.
|
|
||||||
</p>
|
|
||||||
<ul><li><b>WARNING</b>: Avoid using the <b>-nort</b>, as it disables real-time scheduling, it is essential that the <b>FreeSwitch</b> are using real-time scheduling, especially if it is running side-by-side with <i>web</i> servers or database . Use the <b>-nort</b> may result in loss of audio quality, causing a serious commitment on the progress of system connections.
|
|
||||||
</li></ul>
|
|
||||||
<p>After initialization of FreeSWITCH, you can verify that the module was loaded Khomp through the following command: <br />
|
|
||||||
</p>
|
|
||||||
<pre> freeswitch@hostname> module_exists mod_khomp
|
|
||||||
</pre>
|
|
||||||
<p>The next line should answer something like:
|
|
||||||
</p>
|
|
||||||
<pre> true
|
|
||||||
</pre>
|
|
||||||
<p>To verify that the FreeSwitch recognize all the cards, type:
|
|
||||||
</p>
|
|
||||||
<pre> freeswitch@hostname> khomp summary
|
|
||||||
</pre>
|
|
||||||
<p>The output of this command will show details of all cards accepted.
|
|
||||||
</p><p>In the case of an E1 card, you can check the status of links with the following command:
|
|
||||||
</p>
|
|
||||||
<pre> freeswitch@hostname> khomp show links
|
|
||||||
</pre>
|
|
||||||
<p>The state of individual channels, in turn, can be measured with the command:
|
|
||||||
</p>
|
|
||||||
<pre> freeswitch@hostname> khomp show channels
|
|
||||||
</pre>
|
|
||||||
<p>For more details on the commands of the Endpoint khomp type in the console of FreeSWITCH:
|
|
||||||
</p>
|
|
||||||
<pre> freeswitch@hostname> help khomp
|
|
||||||
</pre>
|
|
||||||
<ul><li><b>IMPORTANT</b>: To make full use of your card Khomp, you must configure your dialing rules, either through the extension.conf or from an external application by setting specific rules for conduct by receiving connections. <br /> In the <a href=".htmlMod_Khomp/User_Guide" title="Mod Khomp/User Guide">User Guide</a>, information can be found on the format of input contexts (responsible for receiving calls) and on the options available on application Dial (responsible for make calls) that can be used with the Endpoint Khomp, and other special features provided by it.
|
|
||||||
</li></ul>
|
|
||||||
<p><br />
|
|
||||||
</p></body></html>
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -1,26 +0,0 @@
|
||||||
<include>
|
|
||||||
|
|
||||||
<!-- ########################### FXS Context ############################### -->
|
|
||||||
<context name="khomp-fxs-00">
|
|
||||||
|
|
||||||
<extension name="main">
|
|
||||||
<condition field="destination_number" expression="^(\d{4})$">
|
|
||||||
<action application="set" data="called_party_callgroup=1"/>
|
|
||||||
<action application="db" data="insert/last_dial/${called_party_callgroup}/${uuid}"/>
|
|
||||||
<action application="bridge" data="khomp/r$1"/>
|
|
||||||
</condition>
|
|
||||||
</extension>
|
|
||||||
|
|
||||||
<extension name="intercept">
|
|
||||||
<condition field="destination_number" expression="^55$">
|
|
||||||
<action application="answer"/>
|
|
||||||
<action application="set" data="intercept_unbridged_only=true"/>
|
|
||||||
<action application="intercept" data="${db(select/last_dial/1)}"/>
|
|
||||||
</condition>
|
|
||||||
</extension>
|
|
||||||
|
|
||||||
</context>
|
|
||||||
<!-- ####################################################################### -->
|
|
||||||
|
|
||||||
</include>
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
<include>
|
|
||||||
|
|
||||||
<!-- ########################### FXS Context ############################### -->
|
|
||||||
<context name="khomp-fxs-00">
|
|
||||||
|
|
||||||
<extension name="main">
|
|
||||||
<condition field="destination_number" expression="^(\d{4})$">
|
|
||||||
<action application="set" data="continue_on_fail=true"/>
|
|
||||||
<action application="set" data="dialed_extension=$1"/>
|
|
||||||
<action application="export" data="dialed_extension=$1"/>
|
|
||||||
<action application="bind_meta_app" data="1 b s execute_extension::attented_xfer XML khomp-features"/>
|
|
||||||
<action application="set" data="transfer_ringback=$${hold_music}"/>
|
|
||||||
<action application="set" data="call_timeout=10"/>
|
|
||||||
<action application="set" data="hangup_after_bridge=true"/>
|
|
||||||
<action application="bridge" data="khomp/r$1"/>
|
|
||||||
<action application="bridge" data="sofia/external/$1@169.1.1.1"/>
|
|
||||||
<action application="hangup"/>
|
|
||||||
</condition>
|
|
||||||
</extension>
|
|
||||||
|
|
||||||
</context>
|
|
||||||
<!-- ####################################################################### -->
|
|
||||||
<!-- ########################## Features ################################### -->
|
|
||||||
<context name="khomp-features">
|
|
||||||
|
|
||||||
<extension name="attented_xfer">
|
|
||||||
<condition field="destination_number" expression="^attented_xfer$">
|
|
||||||
<action application="set" data="continue_on_fail=true"/>
|
|
||||||
<action application="set" data="ringback=${us-ring}"/>
|
|
||||||
|
|
||||||
<action application="read" data="3 4 misc/8000/transfer1.wav attxfer_callthis 30000 #"/>
|
|
||||||
<action application="set" data="origination_cancel_key=#" />
|
|
||||||
|
|
||||||
<action application="att_xfer" data="khomp/r${attxfer_callthis}"/>
|
|
||||||
<action application="att_xfer" data="sofia/external/${attxfer_callthis}@169.1.1.1" />
|
|
||||||
</condition>
|
|
||||||
</extension>
|
|
||||||
|
|
||||||
</context>
|
|
||||||
<!-- ####################################################################### -->
|
|
||||||
|
|
||||||
</include>
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,210 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _DEFS_H_
|
|
||||||
#define _DEFS_H_
|
|
||||||
|
|
||||||
/* formatation macros */
|
|
||||||
#include "revision.h"
|
|
||||||
|
|
||||||
#define KHOMP_LOG __FILE__, __SWITCH_FUNC__, __LINE__
|
|
||||||
#define KHOMP_EVENT_MAINT "khomp::maintenance"
|
|
||||||
|
|
||||||
#define OBJ_FMT(dev,obj,msg) \
|
|
||||||
FMT("%s (d=%02d,c=%03d) " msg) % __SWITCH_FUNC__ % dev % obj
|
|
||||||
|
|
||||||
#define OBJ_MSG(dev,obj,msg) \
|
|
||||||
"%s (d=%02d,c=%03d) " msg, __SWITCH_FUNC__, dev, obj
|
|
||||||
|
|
||||||
#define PVT_FMT(tgt,msg) \
|
|
||||||
FMT("%s (d=%02d,c=%03d) " msg) % __SWITCH_FUNC__ % tgt.device % tgt.object
|
|
||||||
|
|
||||||
#define PVT_MSG(tgt,msg) \
|
|
||||||
"%s (d=%02d,c=%03d) " msg, __SWITCH_FUNC__, tgt.device, tgt.object
|
|
||||||
|
|
||||||
#define D(x) ( FMT( "%s: " x ) % __func__ )
|
|
||||||
|
|
||||||
#define STR(fmt) \
|
|
||||||
STG(fmt).c_str()
|
|
||||||
|
|
||||||
/* version controller macro */
|
|
||||||
#define SWITCH_LESS_THAN(x,y,z) \
|
|
||||||
(FS_VERSION_MICRO != -1) && \
|
|
||||||
(((FS_VERSION_MAJOR == x) && (FS_VERSION_MINOR == y) && (FS_VERSION_MICRO <= z)) || \
|
|
||||||
((FS_VERSION_MAJOR == x) && (FS_VERSION_MINOR < y)) || (FS_VERSION_MAJOR < x))
|
|
||||||
|
|
||||||
/* signalling groups macro */
|
|
||||||
#define CASE_R2_SIG \
|
|
||||||
case ksigR2Digital: \
|
|
||||||
case ksigContinuousEM: \
|
|
||||||
case ksigPulsedEM: \
|
|
||||||
case ksigUserR2Digital: \
|
|
||||||
case ksigOpenCAS: \
|
|
||||||
case ksigOpenR2
|
|
||||||
/*
|
|
||||||
case ksigLineSide: \
|
|
||||||
case ksigCAS_EL7: \
|
|
||||||
case ksigE1LC
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define CASE_RDSI_SIG \
|
|
||||||
case ksigPRI_EndPoint: \
|
|
||||||
case ksigPRI_Network: \
|
|
||||||
case ksigPRI_Passive: \
|
|
||||||
case ksigOpenCCS
|
|
||||||
|
|
||||||
#define CASE_FLASH_GRP \
|
|
||||||
case ksigLineSide: \
|
|
||||||
case ksigCAS_EL7: \
|
|
||||||
case ksigE1LC
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
/* Buffering size constants */
|
|
||||||
|
|
||||||
#define SILENCE_PACKS 2
|
|
||||||
|
|
||||||
#define KHOMP_READ_PACKET_TIME 16 // board sample (ms)
|
|
||||||
|
|
||||||
#define KHOMP_READ_PACKET_SIZE (KHOMP_READ_PACKET_TIME * 8) // asterisk sample size (bytes)
|
|
||||||
|
|
||||||
#define KHOMP_MIN_READ_PACKET_SIZE (10 * 8) // min size to return on khomp_read
|
|
||||||
#define KHOMP_MAX_READ_PACKET_SIZE (30 * 8) // max size to return on khomp_read
|
|
||||||
|
|
||||||
#define KHOMP_AUDIO_BUFFER_SIZE (KHOMP_READ_PACKET_SIZE * 8) // buffer size (bytes)
|
|
||||||
|
|
||||||
/* debug and log macros */
|
|
||||||
#define DBG(x,y) \
|
|
||||||
{ \
|
|
||||||
if (K::Logger::Logg.classe( C_DBG_##x ).enabled()) \
|
|
||||||
K::Logger::Logg( C_DBG_##x , y ); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LOG(x,y) \
|
|
||||||
{ \
|
|
||||||
K::Logger::Logg( C_##x , y ); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LOGC(x,y) \
|
|
||||||
{ \
|
|
||||||
if (K::Logger::Logg.classe( C_##x ).enabled()) \
|
|
||||||
LOG( x , y ); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* useful to debug arguments */
|
|
||||||
#define DEBUG_CLI_CMD() \
|
|
||||||
{ \
|
|
||||||
K::Logger::Logg2(C_CLI,stream,FMT("argc: %d ") % argc); \
|
|
||||||
for(int i = 0;i< argc;i++) \
|
|
||||||
K::Logger::Logg2(C_CLI,stream,FMT("argv[%d]:%s ") % i % argv[i]); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* macros to cli commands */
|
|
||||||
#define ARG_CMP(a,b) (argv[a] && !strncasecmp(argv[a],b,sizeof(b)))
|
|
||||||
#define EXEC_CLI_CMD(command) Cli::command.execute(argc,argv)
|
|
||||||
|
|
||||||
/* macro to string treats */
|
|
||||||
#define SAFE_sprintf(a, ...) snprintf(a,sizeof(a), __VA_ARGS__)
|
|
||||||
#define SAFE_strcasecmp(a,b) strncasecmp(a, b, sizeof(b))
|
|
||||||
|
|
||||||
/* tags for timers */
|
|
||||||
#define TM_VAL_CALL (unsigned int)0x01
|
|
||||||
#define TM_VAL_CHANNEL (unsigned int)0x02
|
|
||||||
|
|
||||||
/* macro to creating contexts */
|
|
||||||
#define BEGIN_CONTEXT do
|
|
||||||
#define END_CONTEXT while(false);
|
|
||||||
|
|
||||||
/* Define log type */
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
C_CLI, /* cli msgs */
|
|
||||||
|
|
||||||
C_ERROR, /* errors */
|
|
||||||
C_WARNING, /* warnings */
|
|
||||||
C_MESSAGE, /* normal msgs */
|
|
||||||
|
|
||||||
C_EVENT, /* k3l events */
|
|
||||||
C_COMMAND, /* k3l commands */
|
|
||||||
|
|
||||||
C_AUDIO_EV, /* k3l audio events */
|
|
||||||
C_MODEM_EV, /* gsm modem events */
|
|
||||||
C_LINK_STT, /* link status msgs */
|
|
||||||
C_CAS_MSGS, /* cas events msgs */
|
|
||||||
|
|
||||||
C_DBG_FUNC,
|
|
||||||
C_DBG_LOCK,
|
|
||||||
C_DBG_THRD,
|
|
||||||
C_DBG_STRM,
|
|
||||||
|
|
||||||
C_DBG_CONF,
|
|
||||||
}
|
|
||||||
class_type;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
O_CONSOLE,
|
|
||||||
O_GENERIC,
|
|
||||||
O_R2TRACE,
|
|
||||||
}
|
|
||||||
output_type;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
SCE_SHOW_WARNING,
|
|
||||||
SCE_SHOW_DEBUG,
|
|
||||||
SCE_SHOW_SAME,
|
|
||||||
SCE_HIDE
|
|
||||||
}
|
|
||||||
send_cmd_error_type;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
T_UNKNOWN = 2,
|
|
||||||
T_TRUE = 1,
|
|
||||||
T_FALSE = 0,
|
|
||||||
}
|
|
||||||
TriState;
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,160 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _FRAME_HPP_
|
|
||||||
#define _FRAME_HPP_
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include <ringbuffer.hpp>
|
|
||||||
|
|
||||||
#include "globals.h"
|
|
||||||
|
|
||||||
struct FrameStorage
|
|
||||||
{
|
|
||||||
static const unsigned int frame_count = 24;//6;
|
|
||||||
static const unsigned int audio_count = 24;//4;
|
|
||||||
|
|
||||||
FrameStorage(switch_codec_t * codec, int packet_size);
|
|
||||||
virtual ~FrameStorage();
|
|
||||||
|
|
||||||
inline switch_frame_t * next_frame(void)
|
|
||||||
{
|
|
||||||
return &(_frames[next_index()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned int next_index()
|
|
||||||
{
|
|
||||||
unsigned int tmp = _index;
|
|
||||||
|
|
||||||
if (++_index >= frame_count)
|
|
||||||
_index = 0;
|
|
||||||
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline switch_frame_t * cng_frame(void)
|
|
||||||
{
|
|
||||||
return &_cng_frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * audio_buffer()
|
|
||||||
{
|
|
||||||
return _buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
switch_frame_t _cng_frame;
|
|
||||||
|
|
||||||
switch_frame_t * _frames;
|
|
||||||
char * _buffer;
|
|
||||||
|
|
||||||
unsigned int _index;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Internal frame array structure. */
|
|
||||||
template < int S >
|
|
||||||
struct FrameManager: protected FrameStorage
|
|
||||||
{
|
|
||||||
typedef const char Packet[ S ];
|
|
||||||
|
|
||||||
typedef Ringbuffer < Packet > AudioBuffer;
|
|
||||||
|
|
||||||
FrameManager(switch_codec_t * codec)
|
|
||||||
: FrameStorage(codec, S),
|
|
||||||
_audio(audio_count, (Packet*)audio_buffer())
|
|
||||||
{};
|
|
||||||
|
|
||||||
// ~FrameManager();
|
|
||||||
|
|
||||||
// may throw Ringbuffer::BufferEmpty
|
|
||||||
switch_frame_t * pick(void)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
/* try to consume from buffer.. */
|
|
||||||
Packet & a = _audio.consumer_start();
|
|
||||||
|
|
||||||
switch_frame * f = next_frame();
|
|
||||||
|
|
||||||
/* adjust pointer */
|
|
||||||
f->data = (char *)(&a);
|
|
||||||
|
|
||||||
/* advance now */
|
|
||||||
_audio.consumer_commit();
|
|
||||||
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
catch (...) // AudioBuffer::BufferEmpty & e)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// may throw Ringbuffer::BufferFull
|
|
||||||
bool give(const char * buf, unsigned int size)
|
|
||||||
{
|
|
||||||
return _audio.provider_partial(buf, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_frame_t * cng(void)
|
|
||||||
{
|
|
||||||
return cng_frame();
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
_audio.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
AudioBuffer _audio;
|
|
||||||
|
|
||||||
unsigned int _index;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef FrameManager < Globals::switch_packet_size > FrameSwitchManager;
|
|
||||||
typedef FrameManager < Globals::boards_packet_size > FrameBoardsManager;
|
|
||||||
|
|
||||||
#endif /* _FRAME_HPP_ */
|
|
|
@ -1,121 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _GLOBALS_H_
|
|
||||||
#define _GLOBALS_H_
|
|
||||||
#include "k3lapi.hpp"
|
|
||||||
|
|
||||||
#include <config_options.hpp>
|
|
||||||
#include <k3lutil.hpp>
|
|
||||||
#include <verbose.hpp>
|
|
||||||
#include <regex.hpp>
|
|
||||||
#include <timer.hpp>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include <simple_lock.hpp>
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#include <switch.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
/* As this is a static-variable-only struct, member variable *
|
|
||||||
* names need not to get "_" in front of the name */
|
|
||||||
|
|
||||||
struct Globals
|
|
||||||
{
|
|
||||||
typedef void * global_timer_data;
|
|
||||||
typedef void (global_timer_func)(global_timer_data);
|
|
||||||
typedef TimerTemplate < global_timer_func, global_timer_data > GlobalTimer;
|
|
||||||
|
|
||||||
typedef SimpleNonBlockLock<25,100> Mutex;
|
|
||||||
|
|
||||||
/* FreeSWITCH variables for packets and buffer */
|
|
||||||
// in ms
|
|
||||||
static const unsigned int switch_packet_duration = 30;
|
|
||||||
static const unsigned int boards_packet_duration = 24;
|
|
||||||
// in bytes
|
|
||||||
static const unsigned int switch_packet_size = switch_packet_duration * 8;
|
|
||||||
static const unsigned int boards_packet_size = boards_packet_duration * 8;
|
|
||||||
static const unsigned int cng_buffer_size = (switch_packet_size > boards_packet_size ? switch_packet_size : boards_packet_size);
|
|
||||||
|
|
||||||
/* Father */
|
|
||||||
static K3LAPI k3lapi;
|
|
||||||
|
|
||||||
/* Son */
|
|
||||||
static K3LUtil k3lutil;
|
|
||||||
|
|
||||||
/* Holy Spirit */
|
|
||||||
static Verbose verbose;
|
|
||||||
|
|
||||||
/* Global timer */
|
|
||||||
static GlobalTimer * global_timer;
|
|
||||||
|
|
||||||
/* Mutex to KhompPvt allocation */
|
|
||||||
static Mutex khomp_alloc_mutex;
|
|
||||||
|
|
||||||
/* Config options class */
|
|
||||||
static Config::Options options;
|
|
||||||
|
|
||||||
static const Regex::Expression regex_allocation;
|
|
||||||
|
|
||||||
/* FreeSWITCH Articular Ligaments */
|
|
||||||
static switch_endpoint_interface_t * khomp_endpoint_interface;
|
|
||||||
static switch_endpoint_interface_t * khomp_sms_endpoint_interface;
|
|
||||||
static switch_endpoint_interface_t * khomp_pr_endpoint_interface;
|
|
||||||
static switch_application_interface_t * khomp_app_inteface;
|
|
||||||
static switch_api_interface_t * api_interface;
|
|
||||||
static switch_memory_pool_t * module_pool;
|
|
||||||
|
|
||||||
/* Still a nice workaround */
|
|
||||||
volatile static bool logs_being_rotated;
|
|
||||||
|
|
||||||
/* Trace flags */
|
|
||||||
static bool flag_trace_rdsi;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _GLOBALS_H_ */
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,395 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _KHOMP_PVT_FXO_H_
|
|
||||||
#define _KHOMP_PVT_FXO_H_
|
|
||||||
|
|
||||||
#include "khomp_pvt.h"
|
|
||||||
#include "applications.h"
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/********************************* FXO Board **********************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
struct BoardFXO: public Board
|
|
||||||
{
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************** FXO Channel *********************************/
|
|
||||||
struct KhompPvtFXO: public KhompPvt
|
|
||||||
{
|
|
||||||
/********************************** FXO Call **********************************/
|
|
||||||
struct CallFXO : public Call
|
|
||||||
{
|
|
||||||
CallFXO() {}
|
|
||||||
|
|
||||||
bool process(std::string name, std::string value = "")
|
|
||||||
{
|
|
||||||
if (name == "pre")
|
|
||||||
{
|
|
||||||
DBG(FUNC, D("pre digits adjusted (%s).") % value);
|
|
||||||
_pre_digits = value;
|
|
||||||
}
|
|
||||||
else if (name == "answer_info")
|
|
||||||
{
|
|
||||||
_call_info_report = true;
|
|
||||||
}
|
|
||||||
else if (name == "drop_on")
|
|
||||||
{
|
|
||||||
_call_info_report = true;
|
|
||||||
|
|
||||||
Strings::vector_type drop_item;
|
|
||||||
Strings::tokenize (value, drop_item, ".+");
|
|
||||||
|
|
||||||
for (Strings::vector_type::iterator i = drop_item.begin(); i != drop_item.end(); i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
if ((*i) == "message_box") _call_info_drop |= CI_MESSAGE_BOX;
|
|
||||||
else if ((*i) == "human_answer") _call_info_drop |= CI_HUMAN_ANSWER;
|
|
||||||
else if ((*i) == "answering_machine") _call_info_drop |= CI_ANSWERING_MACHINE;
|
|
||||||
else if ((*i) == "carrier_message") _call_info_drop |= CI_CARRIER_MESSAGE;
|
|
||||||
else if ((*i) == "unknown") _call_info_drop |= CI_UNKNOWN;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG(ERROR, FMT("unknown paramenter to 'calldrop' Dial option: '%s'.") % (*i));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, FMT("droping call on '%s'.") % (*i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (name == "usr_xfer")
|
|
||||||
{
|
|
||||||
_user_xfer_digits = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Call::process(name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool clear()
|
|
||||||
{
|
|
||||||
_pre_digits.clear();
|
|
||||||
_call_info_report = false;
|
|
||||||
_call_info_drop = 0;
|
|
||||||
|
|
||||||
_user_xfer_digits = Opt::_options._user_xfer_digits();
|
|
||||||
_user_xfer_buffer.clear();
|
|
||||||
_digits_buffer.clear();
|
|
||||||
|
|
||||||
_var_fax_adjust = T_UNKNOWN;
|
|
||||||
|
|
||||||
return Call::clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string _pre_digits;
|
|
||||||
|
|
||||||
/* report what we got? */
|
|
||||||
bool _call_info_report;
|
|
||||||
|
|
||||||
/* what call info flags should make us drop the call? */
|
|
||||||
long int _call_info_drop;
|
|
||||||
|
|
||||||
/* used for xfer on user signaling */
|
|
||||||
std::string _user_xfer_digits;
|
|
||||||
std::string _user_xfer_buffer;
|
|
||||||
std::string _digits_buffer;
|
|
||||||
|
|
||||||
TriState _var_fax_adjust;
|
|
||||||
|
|
||||||
ChanTimer::Index _busy_disconnect;
|
|
||||||
};
|
|
||||||
/******************************************************************************/
|
|
||||||
KhompPvtFXO(K3LAPIBase::GenericTarget & target) : KhompPvt(target)
|
|
||||||
{
|
|
||||||
_fax = new Fax(this);
|
|
||||||
_transfer = new Transfer<CallFXO>(this);
|
|
||||||
command(KHOMP_LOG, CM_ENABLE_CALL_ANSWER_INFO);
|
|
||||||
}
|
|
||||||
|
|
||||||
~KhompPvtFXO()
|
|
||||||
{
|
|
||||||
delete _fax;
|
|
||||||
delete _transfer;
|
|
||||||
}
|
|
||||||
|
|
||||||
CallFXO * callFXO()
|
|
||||||
{
|
|
||||||
return (CallFXO *)call();
|
|
||||||
}
|
|
||||||
|
|
||||||
int makeCall(std::string params = "");
|
|
||||||
bool doChannelAnswer(CommandRequest &);
|
|
||||||
|
|
||||||
bool onNewCall(K3L_EVENT *e);
|
|
||||||
bool onDisconnect(K3L_EVENT *e);
|
|
||||||
bool onChannelRelease(K3L_EVENT *e);
|
|
||||||
bool onCallSuccess(K3L_EVENT *e);
|
|
||||||
bool onCallFail(K3L_EVENT *e);
|
|
||||||
bool onAudioStatus(K3L_EVENT *e);
|
|
||||||
bool onSeizeSuccess(K3L_EVENT *e);
|
|
||||||
bool onDtmfDetected(K3L_EVENT *e);
|
|
||||||
bool onDtmfSendFinish(K3L_EVENT *);
|
|
||||||
bool onCallAnswerInfo(K3L_EVENT *e);
|
|
||||||
|
|
||||||
virtual bool eventHandler(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(STRM, D("(FXO) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
switch(e->Code)
|
|
||||||
{
|
|
||||||
case EV_NEW_CALL:
|
|
||||||
ret = onNewCall(e);
|
|
||||||
break;
|
|
||||||
case EV_DISCONNECT:
|
|
||||||
ret = onDisconnect(e);
|
|
||||||
break;
|
|
||||||
case EV_CHANNEL_FREE:
|
|
||||||
case EV_CHANNEL_FAIL:
|
|
||||||
ret = onChannelRelease(e);
|
|
||||||
break;
|
|
||||||
case EV_CALL_SUCCESS:
|
|
||||||
ret = onCallSuccess(e);
|
|
||||||
break;
|
|
||||||
case EV_CALL_FAIL:
|
|
||||||
ret = onCallFail(e);
|
|
||||||
break;
|
|
||||||
case EV_AUDIO_STATUS:
|
|
||||||
ret = onAudioStatus(e);
|
|
||||||
break;
|
|
||||||
case EV_SEIZE_SUCCESS:
|
|
||||||
ret = onSeizeSuccess(e);
|
|
||||||
break;
|
|
||||||
case EV_DTMF_DETECTED:
|
|
||||||
case EV_PULSE_DETECTED:
|
|
||||||
ret = onDtmfDetected(e);
|
|
||||||
break;
|
|
||||||
case EV_DTMF_SEND_FINISH:
|
|
||||||
ret = onDtmfSendFinish(e);
|
|
||||||
break;
|
|
||||||
case EV_CALL_ANSWER_INFO:
|
|
||||||
ret = onCallAnswerInfo(e);
|
|
||||||
break;
|
|
||||||
case EV_FAX_CHANNEL_FREE:
|
|
||||||
ret = _fax->onFaxChannelRelease(e);
|
|
||||||
break;
|
|
||||||
case EV_FAX_FILE_SENT:
|
|
||||||
case EV_FAX_FILE_FAIL:
|
|
||||||
case EV_FAX_TX_TIMEOUT:
|
|
||||||
case EV_FAX_PAGE_CONFIRMATION:
|
|
||||||
case EV_FAX_REMOTE_INFO:
|
|
||||||
break;
|
|
||||||
case EV_POLARITY_REVERSAL:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = KhompPvt::eventHandler(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(STRM, D("(FXO) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool application(ApplicationType type, switch_core_session_t * session, const char *data);
|
|
||||||
|
|
||||||
bool setupConnection();
|
|
||||||
bool autoGainControl(bool enable);
|
|
||||||
void setAnswerInfo(int answer_info);
|
|
||||||
bool indicateBusyUnlocked(int cause, bool sent_signaling = false);
|
|
||||||
static void busyDisconnect(Board::KhompPvt * pvt);
|
|
||||||
void reportFailToReceive(int fail_code);
|
|
||||||
bool validContexts(MatchExtension::ContextListType & contexts,
|
|
||||||
std::string extra_context = "");
|
|
||||||
|
|
||||||
bool isOK(void);
|
|
||||||
|
|
||||||
bool isPhysicalFree()
|
|
||||||
{
|
|
||||||
K3L_CHANNEL_STATUS status;
|
|
||||||
|
|
||||||
if (k3lGetDeviceStatus (_target.device, _target.object + ksoChannel, &status, sizeof (status)) != ksSuccess)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bool physically_free = (status.AddInfo == kfcsEnabled);
|
|
||||||
|
|
||||||
if(status.CallStatus != kcsFree || !physically_free)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "call status not free, or not physically free!"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool cleanup(CleanupType type = CLN_HARD)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Board::board(_target.device)->_timers.del(callFXO()->_busy_disconnect);
|
|
||||||
}
|
|
||||||
catch (K3LAPITraits::invalid_device & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "Unable to get device: %d!") % err.device);
|
|
||||||
}
|
|
||||||
|
|
||||||
call()->_flags.clear(Kflags::CALL_WAIT_SEIZE);
|
|
||||||
call()->_flags.clear(Kflags::EARLY_RINGBACK);
|
|
||||||
|
|
||||||
_transfer->clear();
|
|
||||||
callFXO()->_busy_disconnect.reset();
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case CLN_HARD:
|
|
||||||
case CLN_FAIL:
|
|
||||||
call()->_flags.clear(Kflags::FAX_DETECTED);
|
|
||||||
break;
|
|
||||||
case CLN_SOFT:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return KhompPvt::cleanup(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void getSpecialVariables()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
const char * str_fax = getFSChannelVar("KAdjustForFax");
|
|
||||||
|
|
||||||
callFXO()->_var_fax_adjust = (str_fax ? (!SAFE_strcasecmp(str_fax, "true") ? T_TRUE : T_FALSE) : T_UNKNOWN);
|
|
||||||
}
|
|
||||||
catch(Board::KhompPvt::InvalidSwitchChannel & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_target, "(FXO) %s") % err._msg.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
KhompPvt::getSpecialVariables();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sendDtmf(std::string digit);
|
|
||||||
|
|
||||||
/* used by app FAX */
|
|
||||||
Fax * _fax;
|
|
||||||
|
|
||||||
Transfer<CallFXO> * _transfer;
|
|
||||||
|
|
||||||
// static void delayedDisconnect(Board::KhompPvt * pvt);
|
|
||||||
|
|
||||||
void cleanupIndications(bool force)
|
|
||||||
{
|
|
||||||
if (call()->_indication == INDICA_BUSY && !force)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "skipping busy indication cleanup on FXO channel."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
KhompPvt::cleanupIndications(force);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
BoardFXO(int id) : Board(id) {}
|
|
||||||
|
|
||||||
void initializeChannels(void)
|
|
||||||
{
|
|
||||||
LOG(MESSAGE, "(FXO) loading channels ...");
|
|
||||||
|
|
||||||
for (unsigned obj = 0; obj < Globals::k3lapi.channel_count(_device_id); obj++)
|
|
||||||
{
|
|
||||||
K3LAPIBase::GenericTarget tgt(Globals::k3lapi, K3LAPIBase::GenericTarget::CHANNEL, _device_id, obj);
|
|
||||||
KhompPvt * pvt;
|
|
||||||
|
|
||||||
switch(Globals::k3lapi.channel_config(_device_id, obj).Signaling)
|
|
||||||
{
|
|
||||||
case ksigAnalog:
|
|
||||||
pvt = new BoardFXO::KhompPvtFXO(tgt);
|
|
||||||
pvt->_call = new BoardFXO::KhompPvtFXO::CallFXO();
|
|
||||||
DBG(FUNC, "(FXO) FXO channel");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
pvt = new Board::KhompPvt(tgt);
|
|
||||||
pvt->_call = new Board::KhompPvt::Call();
|
|
||||||
DBG(FUNC, FMT("(FXO) signaling %d unknown") % Globals::k3lapi.channel_config(_device_id, obj).Signaling);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_channels.push_back(pvt);
|
|
||||||
|
|
||||||
pvt->cleanup();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
virtual bool eventHandler(const int obj, K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(STRM, D("(FXO Board) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
switch(e->Code)
|
|
||||||
{
|
|
||||||
case :
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = Board::eventHandler(obj, e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(STRM, D("(FXO Board) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
};
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
#endif /* _KHOMP_PVT_FXO_H_*/
|
|
||||||
|
|
|
@ -1,333 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _KHOMP_PVT_GSM_H_
|
|
||||||
#define _KHOMP_PVT_GSM_H_
|
|
||||||
|
|
||||||
#include "khomp_pvt.h"
|
|
||||||
#include "applications.h"
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/********************************* GSM Board **********************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
struct BoardGSM: public Board
|
|
||||||
{
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************** GSM Channel *********************************/
|
|
||||||
struct KhompPvtGSM: public KhompPvt
|
|
||||||
{
|
|
||||||
/********************************** GSM Call **********************************/
|
|
||||||
struct CallGSM : public Call
|
|
||||||
{
|
|
||||||
CallGSM() {}
|
|
||||||
|
|
||||||
bool process(std::string name, std::string value = "")
|
|
||||||
{
|
|
||||||
if (name == "answer_info")
|
|
||||||
{
|
|
||||||
_call_info_report = true;
|
|
||||||
}
|
|
||||||
else if (name == "drop_on")
|
|
||||||
{
|
|
||||||
_call_info_report = true;
|
|
||||||
|
|
||||||
Strings::vector_type drop_item;
|
|
||||||
Strings::tokenize (value, drop_item, ".+");
|
|
||||||
|
|
||||||
for (Strings::vector_type::iterator i = drop_item.begin(); i != drop_item.end(); i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
if ((*i) == "message_box") _call_info_drop |= CI_MESSAGE_BOX;
|
|
||||||
else if ((*i) == "human_answer") _call_info_drop |= CI_HUMAN_ANSWER;
|
|
||||||
else if ((*i) == "answering_machine") _call_info_drop |= CI_ANSWERING_MACHINE;
|
|
||||||
else if ((*i) == "carrier_message") _call_info_drop |= CI_CARRIER_MESSAGE;
|
|
||||||
else if ((*i) == "unknown") _call_info_drop |= CI_UNKNOWN;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG(ERROR, FMT("unknown paramenter to 'calldrop' Dial option: '%s'.") % (*i));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, FMT("droping call on '%s'.") % (*i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Call::process(name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool clear()
|
|
||||||
{
|
|
||||||
_call_info_report = false;
|
|
||||||
_call_info_drop = 0;
|
|
||||||
|
|
||||||
return Call::clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* report what we got? */
|
|
||||||
bool _call_info_report;
|
|
||||||
|
|
||||||
/* what call info flags should make us drop the call? */
|
|
||||||
long int _call_info_drop;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
KhompPvtGSM(K3LAPIBase::GenericTarget & target) : KhompPvt(target)
|
|
||||||
{
|
|
||||||
_sms = new SMS(this);
|
|
||||||
command(KHOMP_LOG, CM_ENABLE_CALL_ANSWER_INFO);
|
|
||||||
}
|
|
||||||
|
|
||||||
~KhompPvtGSM()
|
|
||||||
{
|
|
||||||
delete _sms;
|
|
||||||
}
|
|
||||||
|
|
||||||
CallGSM * callGSM()
|
|
||||||
{
|
|
||||||
return (CallGSM *)call();
|
|
||||||
}
|
|
||||||
|
|
||||||
int makeCall(std::string params = "");
|
|
||||||
bool doChannelAnswer(CommandRequest &);
|
|
||||||
bool doChannelHangup(CommandRequest &);
|
|
||||||
|
|
||||||
//bool onNewCall(K3L_EVENT *e);
|
|
||||||
bool onChannelRelease(K3L_EVENT *e);
|
|
||||||
bool onCallFail(K3L_EVENT *e);
|
|
||||||
bool onCallSuccess(K3L_EVENT *e);
|
|
||||||
bool onCallAnswerInfo(K3L_EVENT *e);
|
|
||||||
bool onDisconnect(K3L_EVENT *e);
|
|
||||||
//bool onDtmfDetected(K3L_EVENT *e);
|
|
||||||
|
|
||||||
virtual bool eventHandler(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(STRM, D("(GSM) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
switch(e->Code)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
case EV_NEW_CALL:
|
|
||||||
onNewCall(e);
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
case EV_CHANNEL_FREE:
|
|
||||||
case EV_CHANNEL_FAIL:
|
|
||||||
ret = onChannelRelease(e);
|
|
||||||
break;
|
|
||||||
case EV_CALL_SUCCESS:
|
|
||||||
ret = onCallSuccess(e);
|
|
||||||
break;
|
|
||||||
case EV_DISCONNECT:
|
|
||||||
ret = onDisconnect(e);
|
|
||||||
break;
|
|
||||||
case EV_CALL_FAIL:
|
|
||||||
ret = onCallFail(e);
|
|
||||||
break;
|
|
||||||
case EV_CALL_ANSWER_INFO:
|
|
||||||
ret = onCallAnswerInfo(e);
|
|
||||||
break;
|
|
||||||
case EV_RECV_FROM_MODEM:
|
|
||||||
break;
|
|
||||||
case EV_NEW_SMS:
|
|
||||||
ret = _sms->onNewSMS(e);
|
|
||||||
break;
|
|
||||||
case EV_SMS_INFO:
|
|
||||||
ret = _sms->onSMSInfo(e);
|
|
||||||
break;
|
|
||||||
case EV_SMS_DATA:
|
|
||||||
ret = _sms->onSMSData(e);
|
|
||||||
break;
|
|
||||||
case EV_SMS_SEND_RESULT:
|
|
||||||
ret = _sms->onSMSSendResult(e);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = KhompPvt::eventHandler(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(STRM, D("(GSM) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool application(ApplicationType type, switch_core_session_t * session, const char *data);
|
|
||||||
|
|
||||||
bool setupConnection();
|
|
||||||
void setAnswerInfo(int answer_info);
|
|
||||||
bool indicateBusyUnlocked(int cause, bool sent_signaling = false);
|
|
||||||
void reportFailToReceive(int fail_code);
|
|
||||||
int causeFromCallFail(int fail);
|
|
||||||
int callFailFromCause(int cause);
|
|
||||||
bool isOK(void);
|
|
||||||
|
|
||||||
bool isPhysicalFree()
|
|
||||||
{
|
|
||||||
K3L_CHANNEL_STATUS status;
|
|
||||||
|
|
||||||
if (k3lGetDeviceStatus (_target.device, _target.object + ksoChannel, &status, sizeof (status)) != ksSuccess)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bool physically_free = (status.AddInfo == kgsmIdle);
|
|
||||||
|
|
||||||
if(status.CallStatus != kcsFree || !physically_free)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "call status not free, or not physically free!"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sendPreAudio(int rb_value = RingbackDefs::RB_SEND_NOTHING)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool selectSimCard(const char * sim_card)
|
|
||||||
{
|
|
||||||
return command(KHOMP_LOG, CM_SIM_CARD_SELECT, sim_card);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getStatistics(Statistics::Type type)
|
|
||||||
{
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case Statistics::DETAILED:
|
|
||||||
{
|
|
||||||
/* buffer our data to return at the end */
|
|
||||||
std::string strBuffer;
|
|
||||||
|
|
||||||
strBuffer.append(_pvt_statistics->getDetailed());
|
|
||||||
strBuffer.append(_sms->statistics()->getDetailed());
|
|
||||||
return strBuffer;
|
|
||||||
}
|
|
||||||
case Statistics::ROW:
|
|
||||||
{
|
|
||||||
return _pvt_statistics->getRow();
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearStatistics()
|
|
||||||
{
|
|
||||||
KhompPvt::clearStatistics();
|
|
||||||
_sms->statistics()->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool validContexts(MatchExtension::ContextListType & contexts,
|
|
||||||
std::string extra_context = "");
|
|
||||||
|
|
||||||
SMS * _sms;
|
|
||||||
|
|
||||||
};
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
BoardGSM(int id) : Board(id) {}
|
|
||||||
|
|
||||||
void initializeChannels(void)
|
|
||||||
{
|
|
||||||
LOG(MESSAGE, "(GSM) loading channels ...");
|
|
||||||
|
|
||||||
for (unsigned obj = 0; obj < Globals::k3lapi.channel_count(_device_id); obj++)
|
|
||||||
{
|
|
||||||
K3LAPIBase::GenericTarget tgt(Globals::k3lapi, K3LAPIBase::GenericTarget::CHANNEL, _device_id, obj);
|
|
||||||
KhompPvt * pvt;
|
|
||||||
|
|
||||||
switch(Globals::k3lapi.channel_config(_device_id, obj).Signaling)
|
|
||||||
{
|
|
||||||
case ksigGSM:
|
|
||||||
pvt = new BoardGSM::KhompPvtGSM(tgt);
|
|
||||||
pvt->_call = new BoardGSM::KhompPvtGSM::CallGSM();
|
|
||||||
((BoardGSM::KhompPvtGSM *)pvt)->_sms->start();
|
|
||||||
DBG(FUNC, "(GSM) GSM channel");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
pvt = new Board::KhompPvt(tgt);
|
|
||||||
pvt->_call = new Board::KhompPvt::Call();
|
|
||||||
DBG(FUNC, FMT("(GSM) signaling %d unknown") % Globals::k3lapi.channel_config(_device_id, obj).Signaling);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_channels.push_back(pvt);
|
|
||||||
|
|
||||||
pvt->cleanup();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
virtual bool eventHandler(const int obj, K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(STRM, D("(GSM Board) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
switch(e->Code)
|
|
||||||
{
|
|
||||||
case :
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = Board::eventHandler(obj, e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(STRM, D("(GSM Board) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
};
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
#endif /* _KHOMP_PVT_GSM_H_*/
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,305 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _KHOMP_PVT_PASSIVE_H_
|
|
||||||
#define _KHOMP_PVT_PASSIVE_H_
|
|
||||||
|
|
||||||
#include "khomp_pvt.h"
|
|
||||||
#include "applications.h"
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************** Passive Board *******************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
struct BoardPassive: public Board
|
|
||||||
{
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************** Passive Channel *****************************/
|
|
||||||
struct KhompPvtPassive: public KhompPvt
|
|
||||||
{
|
|
||||||
/******************************** Passive Call ********************************/
|
|
||||||
/*
|
|
||||||
struct CallPassive : public Call
|
|
||||||
{
|
|
||||||
CallPassive() {}
|
|
||||||
|
|
||||||
bool process(std::string name, std::string value = "")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Call::process(name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool clear()
|
|
||||||
{
|
|
||||||
return Call::clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
/******************************************************************************/
|
|
||||||
KhompPvtPassive(K3LAPIBase::GenericTarget & target) : KhompPvt(target)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~KhompPvtPassive()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
CallPassive * callPassive()
|
|
||||||
{
|
|
||||||
return (CallPassive *)call();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
virtual bool eventHandler(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(STRM, D("(Passive) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
switch(e->Code)
|
|
||||||
{
|
|
||||||
case EV_CHANNEL_FREE:
|
|
||||||
case EV_CHANNEL_FAIL:
|
|
||||||
ret = onChannelRelease(e);
|
|
||||||
break;
|
|
||||||
/*
|
|
||||||
case EV_CALL_SUCCESS:
|
|
||||||
case EV_CALL_FAIL:
|
|
||||||
case EV_PULSE_DETECTED:
|
|
||||||
*/
|
|
||||||
case EV_DISCONNECT:
|
|
||||||
case EV_DTMF_DETECTED:
|
|
||||||
case EV_AUDIO_STATUS:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(STRM, D("(Passive) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool validContexts(MatchExtension::ContextListType & contexts,
|
|
||||||
std::string extra_context = "");
|
|
||||||
|
|
||||||
/*
|
|
||||||
virtual bool cleanup(CleanupType type = CLN_HARD)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case CLN_HARD:
|
|
||||||
case CLN_FAIL:
|
|
||||||
break;
|
|
||||||
case CLN_SOFT:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return KhompPvt::cleanup(type);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
};
|
|
||||||
/******************************************************************************/
|
|
||||||
/********************************** HI Channel ********************************/
|
|
||||||
struct KhompPvtHI: public KhompPvtPassive
|
|
||||||
{
|
|
||||||
KhompPvtHI(K3LAPIBase::GenericTarget & target) : KhompPvtPassive(target)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~KhompPvtHI()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool onSeizureStart(K3L_EVENT *e);
|
|
||||||
|
|
||||||
virtual bool eventHandler(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(STRM, D("(HI) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
switch(e->Code)
|
|
||||||
{
|
|
||||||
case EV_SEIZURE_START:
|
|
||||||
ret = onSeizureStart(e);
|
|
||||||
break;
|
|
||||||
case EV_RING_DETECTED:
|
|
||||||
case EV_POLARITY_REVERSAL:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = KhompPvtPassive::eventHandler(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(STRM, D("(HI) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
/******************************************************************************/
|
|
||||||
/********************************* KPR Channel ********************************/
|
|
||||||
struct KhompPvtKPR: public KhompPvtPassive
|
|
||||||
{
|
|
||||||
KhompPvtKPR(K3LAPIBase::GenericTarget & target) : KhompPvtPassive(target)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~KhompPvtKPR()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool onNewCall(K3L_EVENT *e);
|
|
||||||
/*
|
|
||||||
bool onConnect(K3L_EVENT *e);
|
|
||||||
*/
|
|
||||||
|
|
||||||
virtual bool eventHandler(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(STRM, D("(KPR) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
switch(e->Code)
|
|
||||||
{
|
|
||||||
case EV_NEW_CALL:
|
|
||||||
ret = onNewCall(e);
|
|
||||||
break;
|
|
||||||
case EV_CONNECT:
|
|
||||||
break;
|
|
||||||
case EV_SEIZURE_START:
|
|
||||||
case EV_CAS_MFC_RECV:
|
|
||||||
case EV_CAS_LINE_STT_CHANGED:
|
|
||||||
case EV_LINK_STATUS:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = KhompPvtPassive::eventHandler(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(STRM, D("(KPR) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool obtainBoth();
|
|
||||||
|
|
||||||
};
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
BoardPassive(int id) : Board(id) {}
|
|
||||||
|
|
||||||
void initializeChannels(void)
|
|
||||||
{
|
|
||||||
LOG(MESSAGE, "(Passive) loading channels ...");
|
|
||||||
|
|
||||||
for (unsigned obj = 0; obj < Globals::k3lapi.channel_count(_device_id); obj++)
|
|
||||||
{
|
|
||||||
K3LAPIBase::GenericTarget tgt(Globals::k3lapi, K3LAPIBase::GenericTarget::CHANNEL, _device_id, obj);
|
|
||||||
KhompPvt * pvt;
|
|
||||||
|
|
||||||
switch(Globals::k3lapi.channel_config(_device_id, obj).Signaling)
|
|
||||||
{
|
|
||||||
case ksigAnalog:
|
|
||||||
pvt = new BoardPassive::KhompPvtHI(tgt);
|
|
||||||
pvt->_call = new BoardPassive::KhompPvtHI::Call();
|
|
||||||
DBG(FUNC, "(Passive) HI channel");
|
|
||||||
break;
|
|
||||||
CASE_RDSI_SIG:
|
|
||||||
CASE_R2_SIG:
|
|
||||||
CASE_FLASH_GRP:
|
|
||||||
case ksigAnalogTerminal:
|
|
||||||
pvt = new BoardPassive::KhompPvtKPR(tgt);
|
|
||||||
pvt->_call = new BoardPassive::KhompPvtKPR::Call();
|
|
||||||
DBG(FUNC, "(Passive) KPR channel");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
pvt = new Board::KhompPvt(tgt);
|
|
||||||
pvt->_call = new Board::KhompPvt::Call();
|
|
||||||
DBG(FUNC, FMT("(Passive) signaling %d unknown") % Globals::k3lapi.channel_config(_device_id, obj).Signaling);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_channels.push_back(pvt);
|
|
||||||
|
|
||||||
pvt->cleanup();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
virtual bool eventHandler(const int obj, K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(STRM, D("(Passive Board) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
switch(e->Code)
|
|
||||||
{
|
|
||||||
case :
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = Board::eventHandler(obj, e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(STRM, D("(Passive Board) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
};
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
#endif /* _KHOMP_PVT_PASSIVE_H_*/
|
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef CHAN_LOCK_H
|
|
||||||
#define CHAN_LOCK_H
|
|
||||||
|
|
||||||
#include <scoped_lock.hpp>
|
|
||||||
#include "khomp_pvt.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct ScopedLockFailed
|
|
||||||
{
|
|
||||||
typedef enum { NULL_PVT, NULL_SOFT_CHAN, FAILED, ALLOC_FAILED } FailType;
|
|
||||||
|
|
||||||
ScopedLockFailed(FailType fail, std::string msg)
|
|
||||||
: _fail(fail), _msg(msg) {};
|
|
||||||
|
|
||||||
FailType _fail;
|
|
||||||
std::string _msg;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct ScopedPvtLock: public ScopedLockBasic
|
|
||||||
{
|
|
||||||
typedef Board::KhompPvt KhompPvt;
|
|
||||||
|
|
||||||
ScopedPvtLock(KhompPvt * pvt);
|
|
||||||
~ScopedPvtLock();
|
|
||||||
|
|
||||||
void unlock();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
KhompPvt * _pvt;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct ScopedAllocLock : public ScopedLockBasic
|
|
||||||
{
|
|
||||||
ScopedAllocLock();
|
|
||||||
~ScopedAllocLock();
|
|
||||||
|
|
||||||
void unlock();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* CHAN_LOCK_H */
|
|
|
@ -1,141 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _Logger_H_
|
|
||||||
#define _Logger_H_
|
|
||||||
|
|
||||||
#include <switch.h>
|
|
||||||
#include <string>
|
|
||||||
#include <simple_lock.hpp>
|
|
||||||
#include <logger.hpp>
|
|
||||||
#include <configurator/configfile.hpp>
|
|
||||||
#include <klog-config.hpp>
|
|
||||||
#include "defs.h"
|
|
||||||
#include "format.hpp"
|
|
||||||
|
|
||||||
namespace K
|
|
||||||
{
|
|
||||||
struct LogConfig
|
|
||||||
{
|
|
||||||
static bool set(Logfile &, const char *, const char *, bool);
|
|
||||||
static bool commit(Logfile &);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SwitchConsoleLog {};
|
|
||||||
|
|
||||||
struct SwitchPrinter: public Logger::DefaultPrinter
|
|
||||||
{
|
|
||||||
typedef Logger::DefaultPrinter Super;
|
|
||||||
typedef Tagged::Union < std::ostream *, Tagged::Union < int, Tagged::Union < SwitchConsoleLog > > > BaseType;
|
|
||||||
|
|
||||||
SwitchPrinter(std::string & msg): Super(msg) {};
|
|
||||||
|
|
||||||
using Super::operator();
|
|
||||||
|
|
||||||
bool operator()(const SwitchConsoleLog & ignored)
|
|
||||||
{
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN,SWITCH_LOG_CONSOLE,"%s",_msg.c_str());
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Log manager declaration. */
|
|
||||||
typedef Logger::Manager <class_type, output_type, SwitchPrinter, SimpleLock> LogManager;
|
|
||||||
|
|
||||||
/* Forward declaration */
|
|
||||||
struct LogInternalManager;
|
|
||||||
|
|
||||||
struct Logger
|
|
||||||
{
|
|
||||||
/* Logger instance. */
|
|
||||||
static LogManager Logg;
|
|
||||||
|
|
||||||
/* Util Logger instance. */
|
|
||||||
static LogInternalManager Logg2;
|
|
||||||
|
|
||||||
static bool start();
|
|
||||||
static void stop();
|
|
||||||
static bool rotate();
|
|
||||||
static void processLogConsole(switch_stream_handle_t *s, const std::string options, bool invert, bool unique);
|
|
||||||
static void processLogDisk(switch_stream_handle_t *s, const std::string options, bool invert, bool unique);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static std::string base_path;
|
|
||||||
static std::ofstream generic_file;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Internal logging facility declaration */
|
|
||||||
struct LogInternalManager
|
|
||||||
{
|
|
||||||
bool operator()(class_type classe, switch_stream_handle_t *stream, const char *args)
|
|
||||||
{
|
|
||||||
switch (classe)
|
|
||||||
{
|
|
||||||
case C_CLI:
|
|
||||||
stream->write_function(stream,"%s\n",args);
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return K::Logger::Logg(classe, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(class_type classe, switch_stream_handle_t *stream, Format &fmt)
|
|
||||||
{
|
|
||||||
return K::Logger::Logg2(classe,stream,(char*) STR(fmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(class_type classe, switch_stream_handle_t *stream, const char *fmt, const char *args)
|
|
||||||
{
|
|
||||||
switch (classe)
|
|
||||||
{
|
|
||||||
case C_CLI:
|
|
||||||
stream->write_function(stream,fmt,args);
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return K::Logger::Logg(classe, FMT(fmt) % args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _Logger_H_ */
|
|
|
@ -1,266 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _OPT_H_
|
|
||||||
#define _OPT_H_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <config_options.hpp>
|
|
||||||
|
|
||||||
#include "switch.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
typedef std::map < std::string, std::string > OrigToDestMapType;
|
|
||||||
typedef std::pair < std::string, std::string > OrigToDestPairType;
|
|
||||||
typedef std::vector < std::string > DestVectorType;
|
|
||||||
|
|
||||||
typedef std::map < unsigned int, std::string > BoardToOrigMapType;
|
|
||||||
typedef std::pair < unsigned int, std::string > BoardToOrigPairType;
|
|
||||||
|
|
||||||
typedef std::map < std::string, unsigned int > OrigToNseqMapType;
|
|
||||||
typedef std::pair < std::string, unsigned int > OrigToNseqPairType;
|
|
||||||
|
|
||||||
typedef std::pair < unsigned int,unsigned int > ObjectIdType;
|
|
||||||
typedef std::pair < std::string, ObjectIdType > BranchToObjectPairType;
|
|
||||||
typedef std::map < std::string, ObjectIdType > BranchToObjectMapType;
|
|
||||||
|
|
||||||
typedef std::map < std::string, std::string > BranchToOptMapType;
|
|
||||||
typedef std::pair < std::string, std::string > BranchToOptPairType;
|
|
||||||
|
|
||||||
typedef std::map < std::string, std::string > GroupToDestMapType;
|
|
||||||
typedef std::pair < std::string, std::string > GroupToDestPairType;
|
|
||||||
|
|
||||||
struct CadenceType
|
|
||||||
{
|
|
||||||
CadenceType(void)
|
|
||||||
: ring(0), ring_s(0), ring_ext(0), ring_ext_s(0) {};
|
|
||||||
|
|
||||||
CadenceType(unsigned int _ring, unsigned int _ring_s)
|
|
||||||
: ring(_ring), ring_s(_ring_s), ring_ext(0), ring_ext_s(0) {};
|
|
||||||
|
|
||||||
CadenceType(unsigned int _ring, unsigned int _ring_s, unsigned int _ring_ext, unsigned int _ring_ext_s)
|
|
||||||
: ring(_ring), ring_s(_ring_s), ring_ext(_ring_ext), ring_ext_s(_ring_ext_s) {};
|
|
||||||
|
|
||||||
unsigned int ring;
|
|
||||||
unsigned int ring_s;
|
|
||||||
unsigned int ring_ext;
|
|
||||||
unsigned int ring_ext_s;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::pair < std::string, CadenceType > CadencesPairType;
|
|
||||||
typedef std::map < std::string, CadenceType > CadencesMapType;
|
|
||||||
|
|
||||||
struct Options
|
|
||||||
{
|
|
||||||
Config::Value< bool > _debug;
|
|
||||||
Config::Value< std::string > _dialplan;
|
|
||||||
Config::Value< std::string > _context;
|
|
||||||
|
|
||||||
Config::Value< bool > _echo_canceller;
|
|
||||||
Config::Value< bool > _auto_gain_control;
|
|
||||||
Config::Value< bool > _out_of_band_dtmfs;
|
|
||||||
Config::Value< bool > _suppression_delay;
|
|
||||||
Config::Value< bool > _pulse_forwarding;
|
|
||||||
Config::Value< bool > _native_bridge;
|
|
||||||
Config::Value< bool > _recording;
|
|
||||||
Config::Value< bool > _has_ctbus;
|
|
||||||
Config::Value< bool > _fxs_bina;
|
|
||||||
Config::Value< bool > _fxs_sharp_dial;
|
|
||||||
Config::Value< bool > _drop_collect_call;
|
|
||||||
Config::Value< bool > _ignore_letter_dtmfs;
|
|
||||||
Config::Value< bool > _optimize_audio_path;
|
|
||||||
|
|
||||||
Config::Value< bool > _fxo_send_pre_audio;
|
|
||||||
Config::Value< unsigned int > _fxo_busy_disconnection;
|
|
||||||
|
|
||||||
Config::Value< bool > _auto_fax_adjustment;
|
|
||||||
Config::Value< unsigned int > _fax_adjustment_timeout;
|
|
||||||
|
|
||||||
Config::Value< bool > _r2_strict_behaviour;
|
|
||||||
Config::Value< unsigned int > _r2_preconnect_wait;
|
|
||||||
|
|
||||||
Config::Value< unsigned int > _fxs_digit_timeout;
|
|
||||||
Config::Value< unsigned int > _transferdigittimeout;
|
|
||||||
|
|
||||||
Config::Value< std::string > _flash;
|
|
||||||
Config::Value< std::string > _blindxfer;
|
|
||||||
Config::Value< std::string > _atxfer;
|
|
||||||
|
|
||||||
Config::Value< unsigned int > _ringback_co_delay;
|
|
||||||
Config::Value< unsigned int > _ringback_pbx_delay;
|
|
||||||
|
|
||||||
Config::Value< unsigned int > _disconnect_delay;
|
|
||||||
|
|
||||||
Config::Value< int > _input_volume;
|
|
||||||
Config::Value< int > _output_volume;
|
|
||||||
|
|
||||||
struct CentralOfficeDialtone : public Config::FunctionValue
|
|
||||||
{
|
|
||||||
void operator ()(const Config::StringType &);
|
|
||||||
const DestVectorType & operator()(void) const { return _value; };
|
|
||||||
void clear(void)
|
|
||||||
{
|
|
||||||
_value.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
DestVectorType _value;
|
|
||||||
} _fxs_co_dialtone;
|
|
||||||
|
|
||||||
struct LogDiskOption : public Config::FunctionValue
|
|
||||||
{
|
|
||||||
void operator ()(const Config::StringType &);
|
|
||||||
} _log_disk_option;
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct CallGroupOption: public Config::FunctionValue
|
|
||||||
{
|
|
||||||
void operator ()(const Config::StringType &);
|
|
||||||
const std::string operator()(void) const { return _groups; };
|
|
||||||
protected:
|
|
||||||
std::string _groups;
|
|
||||||
} _callgroup;
|
|
||||||
|
|
||||||
struct PickupGroupOption: public Config::FunctionValue
|
|
||||||
{
|
|
||||||
void operator ()(const Config::StringType &);
|
|
||||||
const std::string operator()(void) const { return _groups; };
|
|
||||||
protected:
|
|
||||||
std::string _groups;
|
|
||||||
} _pickupgroup; // or intercept
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct LogConsoleOption : public Config::FunctionValue
|
|
||||||
{
|
|
||||||
void operator ()(const Config::StringType &);
|
|
||||||
} _log_console_option;
|
|
||||||
|
|
||||||
struct LogTraceOption : public Config::FunctionValue
|
|
||||||
{
|
|
||||||
void operator ()(const Config::StringType &);
|
|
||||||
} _log_trace_option;
|
|
||||||
|
|
||||||
struct RecordPrefixOption: public Config::FunctionValue
|
|
||||||
{
|
|
||||||
void operator ()(const Config::StringType &);
|
|
||||||
const std::string & operator()(void) const { return _value; };
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string _value;
|
|
||||||
} _record_prefix;
|
|
||||||
|
|
||||||
Config::Value< std::string > _user_xfer_digits;
|
|
||||||
Config::Value< std::string > _fxs_global_orig_base;
|
|
||||||
|
|
||||||
Config::Value< std::string > _global_mohclass;
|
|
||||||
Config::Value< std::string > _global_language;
|
|
||||||
|
|
||||||
Config::Value< std::string > _context_gsm_call;
|
|
||||||
Config::Value< std::string > _context2_gsm_call;
|
|
||||||
Config::Value< std::string > _context_gsm_sms;
|
|
||||||
Config::Value< std::string > _context_fxo;
|
|
||||||
Config::Value< std::string > _context2_fxo;
|
|
||||||
Config::Value< std::string > _context_fxs;
|
|
||||||
Config::Value< std::string > _context2_fxs;
|
|
||||||
Config::Value< std::string > _context_digital;
|
|
||||||
Config::Value< std::string > _context_pr;
|
|
||||||
|
|
||||||
Config::Value< std::string > _callgroup;
|
|
||||||
Config::Value< std::string > _pickupgroup; /* or intercept */
|
|
||||||
Config::Value< std::string > _accountcode;
|
|
||||||
|
|
||||||
Config::Value< unsigned int > _kommuter_timeout;
|
|
||||||
Config::Value< std::string > _kommuter_activation;
|
|
||||||
|
|
||||||
Config::Value< unsigned int > _audio_packet_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Opt
|
|
||||||
{
|
|
||||||
/* here we load [cadences] */
|
|
||||||
static CadencesMapType _cadences;
|
|
||||||
|
|
||||||
/* here we load [groups] */
|
|
||||||
static GroupToDestMapType _groups;
|
|
||||||
|
|
||||||
/* here we load [fxs-hotlines] */
|
|
||||||
static OrigToDestMapType _fxs_hotline;
|
|
||||||
|
|
||||||
/* here we load [fxs-branches] */
|
|
||||||
static BoardToOrigMapType _fxs_orig_base;
|
|
||||||
|
|
||||||
/* here we load [fxs-options] */
|
|
||||||
static BranchToOptMapType _branch_options;
|
|
||||||
|
|
||||||
/* here we load ... hannnn */
|
|
||||||
static BranchToObjectMapType _fxs_branch_map;
|
|
||||||
|
|
||||||
static Options _options;
|
|
||||||
|
|
||||||
/* Member functions */
|
|
||||||
static void initialize(void);
|
|
||||||
static void obtain(void);
|
|
||||||
static void commit(void);
|
|
||||||
|
|
||||||
//TODO: reload options at reloadxml ?
|
|
||||||
static void reload(void);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void loadConfiguration(const char *, const char **, bool show_errors = true);
|
|
||||||
static void cleanConfiguration(void);
|
|
||||||
|
|
||||||
static switch_xml_t processSimpleXML(switch_xml_t &xml, const std::string& child_name);
|
|
||||||
static void processGroupXML(switch_xml_t &xml);
|
|
||||||
static void processCadenceXML(switch_xml_t &xml);
|
|
||||||
static void processFXSBranchesXML(switch_xml_t &xml);
|
|
||||||
static void processFXSHotlines(switch_xml_t &xml);
|
|
||||||
static void processFXSOptions(switch_xml_t &xml);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _OPT_H_ */
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
#define MOD_KHOMP_VERSION "1.0 - (rev: 6034)"
|
|
|
@ -1,91 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _SPEC_HPP_
|
|
||||||
#define _SPEC_HPP_
|
|
||||||
|
|
||||||
#include <function.hpp>
|
|
||||||
#include "khomp_pvt.h"
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
SPR_CONTINUE,
|
|
||||||
SPR_SUCCESS,
|
|
||||||
SPR_FAIL,
|
|
||||||
}
|
|
||||||
SpecRetType;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
SPF_FIRST = 0x01,
|
|
||||||
SPF_CYCLIC = 0x02,
|
|
||||||
}
|
|
||||||
SpecFlagType;
|
|
||||||
|
|
||||||
typedef unsigned int SpecFlagsType;
|
|
||||||
typedef Function::Function3 < bool, unsigned int, unsigned int, SpecFlagsType & > SpecFunType;
|
|
||||||
|
|
||||||
/* Request a Board::KhompPvt based on dialplan string.
|
|
||||||
|
|
||||||
-- Format of dialplan string. --
|
|
||||||
|
|
||||||
Dial(Khomp/B2C58/4832625644)
|
|
||||||
| | | |
|
|
||||||
| | | |
|
|
||||||
| | | |
|
|
||||||
| | | +- Destination number.
|
|
||||||
| | |
|
|
||||||
| | +- Identifier for board 2, channel 58.
|
|
||||||
| |
|
|
||||||
| +- Khomp channel identifier.
|
|
||||||
|
|
|
||||||
+- Dial Application.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Board::KhompPvt * processDialString(const char *, int *);
|
|
||||||
void processGroupString();
|
|
||||||
|
|
||||||
Board::KhompPvt * processSMSString(const char *, int *);
|
|
||||||
|
|
||||||
#endif /* _SPEC_HPP_ */
|
|
||||||
|
|
|
@ -1,783 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _UTILS_H_
|
|
||||||
#define _UTILS_H_
|
|
||||||
|
|
||||||
#include <bitset>
|
|
||||||
#include <refcounter.hpp>
|
|
||||||
#include <ringbuffer.hpp>
|
|
||||||
#include <simple_lock.hpp>
|
|
||||||
#include <saved_condition.hpp>
|
|
||||||
#include <thread.hpp>
|
|
||||||
#include "globals.h"
|
|
||||||
#include "logger.h"
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/************************** Defining applications *****************************/
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
FAX_ADJUST,
|
|
||||||
FAX_SEND,
|
|
||||||
FAX_RECEIVE,
|
|
||||||
USER_TRANSFER,
|
|
||||||
SMS_CHECK,
|
|
||||||
SMS_SEND,
|
|
||||||
SELECT_SIM_CARD,
|
|
||||||
}
|
|
||||||
ApplicationType;
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/***************** Abstraction for defining channel flags *********************/
|
|
||||||
|
|
||||||
struct Kflags
|
|
||||||
{
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
CONNECTED = 0,
|
|
||||||
REALLY_CONNECTED,
|
|
||||||
|
|
||||||
IS_OUTGOING,
|
|
||||||
IS_INCOMING,
|
|
||||||
|
|
||||||
STREAM_UP,
|
|
||||||
LISTEN_UP,
|
|
||||||
|
|
||||||
GEN_CO_RING,
|
|
||||||
GEN_PBX_RING,
|
|
||||||
|
|
||||||
HAS_PRE_AUDIO,
|
|
||||||
HAS_CALL_FAIL,
|
|
||||||
|
|
||||||
DROP_COLLECT,
|
|
||||||
|
|
||||||
NEEDS_RINGBACK_CMD, //R2
|
|
||||||
EARLY_RINGBACK, //FXO
|
|
||||||
|
|
||||||
FAX_DETECTED, //Digital, FXO
|
|
||||||
FAX_SENDING, //Digital, FXO
|
|
||||||
FAX_RECEIVING, //Digital, FXO
|
|
||||||
|
|
||||||
OUT_OF_BAND_DTMFS,
|
|
||||||
|
|
||||||
KEEP_DTMF_SUPPRESSION,
|
|
||||||
KEEP_ECHO_CANCELLATION,
|
|
||||||
KEEP_AUTO_GAIN_CONTROL,
|
|
||||||
|
|
||||||
WAIT_SEND_DTMF,
|
|
||||||
|
|
||||||
CALL_WAIT_SEIZE, //FXO
|
|
||||||
|
|
||||||
NUMBER_DIAL_FINISHD, //R2
|
|
||||||
NUMBER_DIAL_ONGOING, //R2
|
|
||||||
|
|
||||||
FXS_OFFHOOK, //FXS
|
|
||||||
FXS_DIAL_FINISHD, //FXS
|
|
||||||
FXS_DIAL_ONGOING, //FXS
|
|
||||||
FXS_FLASH_TRANSFER, //FXS
|
|
||||||
|
|
||||||
XFER_QSIG_DIALING, //ISDN
|
|
||||||
XFER_DIALING, //ISDN, FXO
|
|
||||||
|
|
||||||
SMS_DOING_UPLOAD, //GSM
|
|
||||||
|
|
||||||
/*
|
|
||||||
NOW LOADING ...
|
|
||||||
|
|
||||||
BRIDGED,
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Do not remove this last FLAG */
|
|
||||||
INVALID_FLAG
|
|
||||||
}
|
|
||||||
FlagType;
|
|
||||||
|
|
||||||
struct Flag
|
|
||||||
{
|
|
||||||
const char *_name;
|
|
||||||
bool _value;
|
|
||||||
};
|
|
||||||
|
|
||||||
Kflags() { init(); };
|
|
||||||
|
|
||||||
void init();
|
|
||||||
|
|
||||||
inline const char * name(FlagType bit) { return _flags[bit]._name; }
|
|
||||||
|
|
||||||
inline bool check(FlagType bit)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_FLAGS
|
|
||||||
DBG(FUNC, D("Flag %s=%s") % name(bit) %
|
|
||||||
(_flags[bit]._value ? "TRUE" : "FALSE"));
|
|
||||||
#endif
|
|
||||||
return _flags[bit]._value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set(FlagType bit)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_FLAGS
|
|
||||||
DBG(FUNC, D("Flag %s") % name(bit));
|
|
||||||
#endif
|
|
||||||
_flags[bit]._value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void clear(FlagType bit)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_FLAGS
|
|
||||||
DBG(FUNC, D("Flag %s") % name(bit));
|
|
||||||
#endif
|
|
||||||
_flags[bit]._value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void clearAll()
|
|
||||||
{
|
|
||||||
unsigned int index = 0;
|
|
||||||
for(; (FlagType)index < INVALID_FLAG; index++)
|
|
||||||
{
|
|
||||||
if(_flags[index]._value)
|
|
||||||
{
|
|
||||||
DBG(FUNC, D("Flag %s was not clean!") % name((FlagType)index));
|
|
||||||
clear((FlagType)index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Flag _flags[INVALID_FLAG+1];
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/************************* Commands and Events Handler ************************/
|
|
||||||
struct CommandRequest
|
|
||||||
{
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NONE = 0,
|
|
||||||
COMMAND,
|
|
||||||
ACTION
|
|
||||||
}
|
|
||||||
ReqType;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
CNONE = 0,
|
|
||||||
|
|
||||||
/* Commands */
|
|
||||||
CMD_CALL,
|
|
||||||
CMD_ANSWER,
|
|
||||||
CMD_HANGUP,
|
|
||||||
|
|
||||||
/* Actions */
|
|
||||||
FLUSH_REC_STREAM,
|
|
||||||
FLUSH_REC_BRIDGE,
|
|
||||||
START_RECORD,
|
|
||||||
STOP_RECORD
|
|
||||||
|
|
||||||
}
|
|
||||||
CodeType;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
RFA_CLOSE,
|
|
||||||
RFA_KEEP_OPEN,
|
|
||||||
RFA_REMOVE
|
|
||||||
}
|
|
||||||
RecFlagType;
|
|
||||||
|
|
||||||
/* "empty" constructor */
|
|
||||||
CommandRequest() :
|
|
||||||
_type(NONE),
|
|
||||||
_code(CNONE),
|
|
||||||
_obj(-1)
|
|
||||||
{}
|
|
||||||
|
|
||||||
CommandRequest(ReqType type, CodeType code, int obj) :
|
|
||||||
_type(type),
|
|
||||||
_code(code),
|
|
||||||
_obj(obj)
|
|
||||||
{}
|
|
||||||
|
|
||||||
CommandRequest(const CommandRequest & cmd) :
|
|
||||||
_type(cmd._type),
|
|
||||||
_code(cmd._code),
|
|
||||||
_obj(cmd._obj)
|
|
||||||
{}
|
|
||||||
|
|
||||||
~CommandRequest() {}
|
|
||||||
|
|
||||||
void operator=(const CommandRequest & cmd)
|
|
||||||
{
|
|
||||||
_type = cmd._type;
|
|
||||||
_code = cmd._code;
|
|
||||||
_obj = cmd._obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mirror(const CommandRequest & cmd_request)
|
|
||||||
{
|
|
||||||
_type = cmd_request._type;
|
|
||||||
_code = cmd_request._code;
|
|
||||||
_obj = cmd_request._obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
short type() { return _type; }
|
|
||||||
|
|
||||||
short code() { return _code; }
|
|
||||||
|
|
||||||
int obj() { return _obj; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
short _type;
|
|
||||||
short _code;
|
|
||||||
int _obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EventRequest
|
|
||||||
{
|
|
||||||
/* "empty" constructor */
|
|
||||||
EventRequest(bool can_delete = true) :
|
|
||||||
_delete(can_delete),
|
|
||||||
_obj(-1)
|
|
||||||
{
|
|
||||||
if(can_delete)
|
|
||||||
_event = new K3L_EVENT();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Temporary constructor */
|
|
||||||
EventRequest(int obj, K3L_EVENT * ev) :
|
|
||||||
_delete(false),
|
|
||||||
_obj(obj),
|
|
||||||
_event(ev)
|
|
||||||
{}
|
|
||||||
|
|
||||||
//EventRequest(const EventRequest & ev) : _obj(ev._obj) {}
|
|
||||||
|
|
||||||
~EventRequest()
|
|
||||||
{
|
|
||||||
|
|
||||||
if(!_delete || !_event)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(_event->ParamSize)
|
|
||||||
free(_event->Params);
|
|
||||||
|
|
||||||
delete _event;
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator=(const EventRequest & ev)
|
|
||||||
{
|
|
||||||
_delete = false;
|
|
||||||
_obj = ev._obj;
|
|
||||||
_event = ev._event;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void mirror(const EventRequest & ev_request)
|
|
||||||
{
|
|
||||||
//Checar o _event
|
|
||||||
|
|
||||||
if(_event->ParamSize)
|
|
||||||
{
|
|
||||||
free(_event->Params);
|
|
||||||
}
|
|
||||||
|
|
||||||
_event->Params = NULL;
|
|
||||||
|
|
||||||
_obj = ev_request._obj;
|
|
||||||
|
|
||||||
K3L_EVENT * ev = ev_request._event;
|
|
||||||
|
|
||||||
if(!ev)
|
|
||||||
{
|
|
||||||
clearEvent();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_event->Code = ev->Code; // API code
|
|
||||||
_event->AddInfo = ev->AddInfo; // Parameter 1
|
|
||||||
_event->DeviceId = ev->DeviceId; // Hardware information
|
|
||||||
_event->ObjectInfo = ev->ObjectInfo; // Additional object information
|
|
||||||
_event->ParamSize = ev->ParamSize; // Size of parameter buffer
|
|
||||||
_event->ObjectId = ev->ObjectId; // KEventObjectId: Event thrower object id
|
|
||||||
|
|
||||||
if(ev->ParamSize)
|
|
||||||
{
|
|
||||||
// Pointer to the parameter buffer
|
|
||||||
_event->Params = malloc(ev->ParamSize+1);
|
|
||||||
memcpy(_event->Params, ev->Params, ev->ParamSize);
|
|
||||||
((char *)(_event->Params))[ev->ParamSize] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool clearEvent()
|
|
||||||
{
|
|
||||||
_event->Code = -1;
|
|
||||||
_event->AddInfo = -1;
|
|
||||||
_event->DeviceId = -1;
|
|
||||||
_event->ObjectInfo = -1;
|
|
||||||
_event->ParamSize = 0;
|
|
||||||
_event->ObjectId = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int obj() { return _obj; }
|
|
||||||
|
|
||||||
K3L_EVENT * event() { return _event; }
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool _delete;
|
|
||||||
int _obj;
|
|
||||||
K3L_EVENT * _event;
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename R, int S >
|
|
||||||
struct GenericFifo
|
|
||||||
{
|
|
||||||
typedef R RequestType;
|
|
||||||
typedef SimpleNonBlockLock<25,100> LockType;
|
|
||||||
|
|
||||||
GenericFifo(int device) :
|
|
||||||
_device(device),
|
|
||||||
_shutdown(false),
|
|
||||||
_buffer(S),
|
|
||||||
_mutex(Globals::module_pool),
|
|
||||||
_cond(Globals::module_pool)
|
|
||||||
{};
|
|
||||||
|
|
||||||
int _device;
|
|
||||||
bool _shutdown;
|
|
||||||
Ringbuffer < RequestType > _buffer;
|
|
||||||
LockType _mutex; /* to sync write acess to event list */
|
|
||||||
SavedCondition _cond;
|
|
||||||
Thread *_thread;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef GenericFifo < CommandRequest, 250 > CommandFifo;
|
|
||||||
typedef GenericFifo < EventRequest, 500 > EventFifo;
|
|
||||||
|
|
||||||
/* Used inside KhompPvt to represent an command handler */
|
|
||||||
struct ChanCommandHandler: NEW_REFCOUNTER(ChanCommandHandler)
|
|
||||||
{
|
|
||||||
typedef int (HandlerType)(void *);
|
|
||||||
|
|
||||||
ChanCommandHandler(int device, HandlerType * handler)
|
|
||||||
{
|
|
||||||
_fifo = new CommandFifo(device);
|
|
||||||
/* device event handler */
|
|
||||||
_fifo->_thread = new Thread(handler, (void *)this, Globals::module_pool);
|
|
||||||
if(_fifo->_thread->start())
|
|
||||||
{
|
|
||||||
DBG(FUNC,"Device command handler started");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG(ERROR, "Device command handler error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ChanCommandHandler(const ChanCommandHandler & cmd)
|
|
||||||
: INC_REFCOUNTER(cmd, ChanCommandHandler),
|
|
||||||
_fifo(cmd._fifo)
|
|
||||||
{};
|
|
||||||
|
|
||||||
void unreference();
|
|
||||||
|
|
||||||
CommandFifo * fifo()
|
|
||||||
{
|
|
||||||
return _fifo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void signal()
|
|
||||||
{
|
|
||||||
_fifo->_cond.signal();
|
|
||||||
};
|
|
||||||
|
|
||||||
bool writeNoSignal(const CommandRequest &);
|
|
||||||
bool write(const CommandRequest &);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
CommandFifo * _fifo;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Used inside KhompPvt to represent an event handler */
|
|
||||||
struct ChanEventHandler: NEW_REFCOUNTER(ChanEventHandler)
|
|
||||||
{
|
|
||||||
typedef int (HandlerType)(void *);
|
|
||||||
|
|
||||||
ChanEventHandler(int device, HandlerType * handler)
|
|
||||||
{
|
|
||||||
_fifo = new EventFifo(device);
|
|
||||||
/* device event handler */
|
|
||||||
_fifo->_thread = new Thread(handler, (void *)this, Globals::module_pool);
|
|
||||||
if(_fifo->_thread->start())
|
|
||||||
{
|
|
||||||
DBG(FUNC,"Device event handler started");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG(ERROR, "Device event handler error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ChanEventHandler(const ChanEventHandler & evt)
|
|
||||||
: INC_REFCOUNTER(evt, ChanEventHandler),
|
|
||||||
_fifo(evt._fifo)
|
|
||||||
{};
|
|
||||||
|
|
||||||
void unreference();
|
|
||||||
|
|
||||||
EventFifo * fifo()
|
|
||||||
{
|
|
||||||
return _fifo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void signal()
|
|
||||||
{
|
|
||||||
_fifo->_cond.signal();
|
|
||||||
};
|
|
||||||
|
|
||||||
bool provide(const EventRequest &);
|
|
||||||
bool writeNoSignal(const EventRequest &);
|
|
||||||
bool write(const EventRequest &);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
EventFifo * _fifo;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/****************************** Internal **************************************/
|
|
||||||
struct RingbackDefs
|
|
||||||
{
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
RB_SEND_DEFAULT = -1,
|
|
||||||
RB_SEND_NOTHING = -2,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
RBST_SUCCESS,
|
|
||||||
RBST_UNSUPPORTED,
|
|
||||||
RBST_FAILURE,
|
|
||||||
}
|
|
||||||
RingbackStType;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************* Others ***************************************/
|
|
||||||
static bool checkTrueString(const char * str)
|
|
||||||
{
|
|
||||||
if (str && *str)
|
|
||||||
{
|
|
||||||
if (!SAFE_strcasecmp(str, "yes") || !SAFE_strcasecmp(str, "true") ||
|
|
||||||
!SAFE_strcasecmp(str, "enabled") || !SAFE_strcasecmp(str, "sim"))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool checkFalseString(const char * str)
|
|
||||||
{
|
|
||||||
if (str && *str)
|
|
||||||
{
|
|
||||||
if (!SAFE_strcasecmp(str, "no") || !SAFE_strcasecmp(str, "false") ||
|
|
||||||
!SAFE_strcasecmp(str, "disabled") || !SAFE_strcasecmp(str, "não"))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static TriState getTriStateValue(const char * str)
|
|
||||||
{
|
|
||||||
if (str)
|
|
||||||
{
|
|
||||||
/**/ if (checkTrueString(str)) return T_TRUE;
|
|
||||||
else if (checkFalseString(str)) return T_FALSE;
|
|
||||||
else /***********************************/ return T_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
return T_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * answerInfoToString(int answer_info);
|
|
||||||
|
|
||||||
static bool replaceTemplate(std::string & haystack, const std::string & needed, int value)
|
|
||||||
{
|
|
||||||
Regex::Expression e(std::string(needed).c_str());
|
|
||||||
Regex::Match r(haystack,e);
|
|
||||||
|
|
||||||
if(!r.matched()) return false;
|
|
||||||
|
|
||||||
int len;
|
|
||||||
std::string fmt;
|
|
||||||
std::string tmp;
|
|
||||||
|
|
||||||
// if needed isn't "SSSS" the length of needed will give string format
|
|
||||||
// if needed is "SSSS" the length of value will give string format
|
|
||||||
std::string ssss("SSSS");
|
|
||||||
|
|
||||||
if (ssss != needed)
|
|
||||||
{
|
|
||||||
len = needed.size();
|
|
||||||
fmt = STG(FMT("%%0%dd") % len);
|
|
||||||
tmp = STG(FMT(fmt) % value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
len = (STG(FMT("%d") % value)).size();
|
|
||||||
fmt = STG(FMT("%%%dd") % len);
|
|
||||||
tmp = STG(FMT(fmt) % value);
|
|
||||||
}
|
|
||||||
|
|
||||||
haystack = r.replace(STG(FMT(fmt) % value));
|
|
||||||
|
|
||||||
DBG(FUNC,FMT("haystack: %s") % haystack);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static std::string timeToString (time_t time_value)
|
|
||||||
{
|
|
||||||
int horas = (int)time_value / 3600;
|
|
||||||
|
|
||||||
if (horas > 0)
|
|
||||||
time_value -= horas * 3600;
|
|
||||||
|
|
||||||
int minutos = (int)time_value / 60;
|
|
||||||
|
|
||||||
if (minutos > 0)
|
|
||||||
time_value -= minutos * 60;
|
|
||||||
|
|
||||||
return STG(FMT("%02d:%02d:%02d") % horas % minutos % (int)time_value);
|
|
||||||
}
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************* Match functions ******************************/
|
|
||||||
struct MatchExtension
|
|
||||||
{
|
|
||||||
typedef std::vector<std::string> ContextListType;
|
|
||||||
typedef std::vector<std::string> ExtenListType;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
MATCH_NONE,
|
|
||||||
MATCH_EXACT,
|
|
||||||
MATCH_MORE
|
|
||||||
}
|
|
||||||
MatchType;
|
|
||||||
|
|
||||||
static bool canMatch(std::string & context, std::string & exten,
|
|
||||||
std::string & caller_id, bool match_more = false);
|
|
||||||
|
|
||||||
static MatchType matchExtension(std::string &, std::string &,
|
|
||||||
std::string &, bool match_only = false);
|
|
||||||
|
|
||||||
static MatchType findExtension(std::string &, std::string &,
|
|
||||||
ContextListType &, std::string &, std::string &,
|
|
||||||
bool default_ctx = true, bool default_ext = true);
|
|
||||||
|
|
||||||
};
|
|
||||||
/******************************************************************************/
|
|
||||||
/************************** Thread helper functions ***************************/
|
|
||||||
typedef int (HandlerType)(void *);
|
|
||||||
static Thread * threadCreate(HandlerType * handler,void * arg)
|
|
||||||
{
|
|
||||||
Thread *t = new Thread(handler, (void *) arg, Globals::module_pool);
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************** Kommuter ************************************/
|
|
||||||
struct Kommuter
|
|
||||||
{
|
|
||||||
Kommuter() :
|
|
||||||
_kommuter_count(-1),
|
|
||||||
_kwtd_timer_on(false)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool start()
|
|
||||||
{
|
|
||||||
/* Checks for kommuter */
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Globals::k3lapi.command(-1,-1,CM_WATCHDOG_COUNT);
|
|
||||||
}
|
|
||||||
catch(K3LAPI::failed_command & e)
|
|
||||||
{
|
|
||||||
LOG(WARNING , "libkwd.so used by Kommuter devices is not available.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool stop();
|
|
||||||
|
|
||||||
bool initialize(K3L_EVENT *e);
|
|
||||||
|
|
||||||
/* Index of the WatchDog timer */
|
|
||||||
TimerTraits::Index _kwtd_timer_index;
|
|
||||||
int _kommuter_count;
|
|
||||||
bool _kwtd_timer_on;
|
|
||||||
|
|
||||||
/* Timer to control our dog (totó) */
|
|
||||||
static void wtdKickTimer(void *);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************* Statistics ***********************************/
|
|
||||||
struct Statistics
|
|
||||||
{
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
DETAILED = 0,
|
|
||||||
ROW
|
|
||||||
}
|
|
||||||
Type;
|
|
||||||
|
|
||||||
virtual std::string getDetailed() { return ""; }
|
|
||||||
virtual void clear() {}
|
|
||||||
};
|
|
||||||
/******************************************************************************/
|
|
||||||
/****************************** ESL - Events **********************************/
|
|
||||||
|
|
||||||
struct ESL
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef std::vector <std::string> VectorEvents;
|
|
||||||
|
|
||||||
ESL(std::string type);
|
|
||||||
|
|
||||||
~ESL();
|
|
||||||
|
|
||||||
switch_event_t * create(const std::string type)
|
|
||||||
{
|
|
||||||
switch_event_t *event;
|
|
||||||
|
|
||||||
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, type.c_str()) != SWITCH_STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_event_t * create()
|
|
||||||
{
|
|
||||||
return create(_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool add(switch_event_t *event, const std::string key,
|
|
||||||
const std::string value) const
|
|
||||||
{
|
|
||||||
if(!event) return false;
|
|
||||||
|
|
||||||
switch_status_t res = switch_event_add_header_string(event,
|
|
||||||
SWITCH_STACK_BOTTOM,
|
|
||||||
key.c_str(),
|
|
||||||
value.c_str());
|
|
||||||
|
|
||||||
return (res == SWITCH_STATUS_SUCCESS ? true : false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool add(switch_event_t *event, K3LAPIBase::GenericTarget & target)
|
|
||||||
{
|
|
||||||
bool ok = add(event, "Device", STR(FMT("%d") % target.device));
|
|
||||||
|
|
||||||
if(!ok)
|
|
||||||
return ok;
|
|
||||||
|
|
||||||
std::string type;
|
|
||||||
|
|
||||||
switch(target.type)
|
|
||||||
{
|
|
||||||
case K3LAPIBase::GenericTarget::CHANNEL:
|
|
||||||
type = "Channel";
|
|
||||||
break;
|
|
||||||
case K3LAPIBase::GenericTarget::MIXER:
|
|
||||||
type = "Mixer";
|
|
||||||
break;
|
|
||||||
case K3LAPIBase::GenericTarget::LINK:
|
|
||||||
type = "Link";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
type = "Other";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return add(event, type, STR(FMT("%d") % target.object));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool fire(switch_event_t **event) const
|
|
||||||
{
|
|
||||||
if(!event || !*event) return false;
|
|
||||||
|
|
||||||
switch_status_t res = switch_event_fire(event);
|
|
||||||
|
|
||||||
*event = NULL;
|
|
||||||
|
|
||||||
return (res == SWITCH_STATUS_SUCCESS ? true : false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool registerEvents();
|
|
||||||
|
|
||||||
static bool unregisterEvents();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const std::string _type;
|
|
||||||
static VectorEvents * _events;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
#endif /* _UTILS_H_ */
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,976 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#include "applications.h"
|
|
||||||
#include "lock.h"
|
|
||||||
|
|
||||||
|
|
||||||
bool Fax::adjustForFax()
|
|
||||||
{
|
|
||||||
/* Don't worry, let the man work */
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(),"Channel is now being adjusted for fax!"));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(_pvt);
|
|
||||||
|
|
||||||
_pvt->echoCancellation(false);
|
|
||||||
_pvt->dtmfSuppression(false);
|
|
||||||
_pvt->autoGainControl(false);
|
|
||||||
|
|
||||||
_pvt->call()->_input_volume = 0;
|
|
||||||
_pvt->setVolume("input" , 0);
|
|
||||||
_pvt->call()->_output_volume = 0;
|
|
||||||
_pvt->setVolume("output", 0);
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "r (unable to lock: %s!)") % err._msg.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Fax::sendFax(switch_core_session_t * session, const char *data)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "c (%s)") % data);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
switch_channel_t *channel = _pvt->getFSChannel(session);
|
|
||||||
|
|
||||||
switch_channel_set_variable(channel, "KFaxSent", "no");
|
|
||||||
switch_channel_set_variable(channel, "KFaxResult", "none");
|
|
||||||
|
|
||||||
std::string fax_string((const char *)data);
|
|
||||||
Strings::vector_type fax_args;
|
|
||||||
Strings::vector_type fax_files;
|
|
||||||
|
|
||||||
Strings::tokenize(fax_string, fax_args, "|,");
|
|
||||||
|
|
||||||
if(fax_args.size() != 1 && fax_args.size() != 2)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "r (invalid string '%s': wrong number of separators.)") % fax_string);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Strings::tokenize(fax_args[0], fax_files, ":");
|
|
||||||
|
|
||||||
if(fax_files.size() <= 0)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "r (invalid string '%s': wrong number of separators.)") % fax_string);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedPvtLock lock(_pvt);
|
|
||||||
|
|
||||||
std::string id;
|
|
||||||
|
|
||||||
if(fax_args.size() == 2)
|
|
||||||
{
|
|
||||||
id = fax_args[1];
|
|
||||||
}
|
|
||||||
else if(!_pvt->call()->_orig_addr.empty())
|
|
||||||
{
|
|
||||||
id = _pvt->call()->_orig_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * orig_addr = id.empty() ? NULL : id.c_str();
|
|
||||||
|
|
||||||
int timeout = 5;
|
|
||||||
|
|
||||||
if(!_pvt->call()->_flags.check(Kflags::REALLY_CONNECTED) && !_pvt->loopWhileFlagTimed(Kflags::REALLY_CONNECTED, timeout, false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(!startFaxTX(orig_addr))
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "r (unable to start send fax)"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < fax_files.size() ; ++i)
|
|
||||||
{
|
|
||||||
if (!addFaxFile(fax_files[i].c_str(), (i == fax_files.size()-1)? true : false))
|
|
||||||
{
|
|
||||||
DBG(FUNC, D("unable to add fax file='%s'")
|
|
||||||
% fax_files[i].c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_fax_cond.reset();
|
|
||||||
|
|
||||||
lock.unlock();
|
|
||||||
|
|
||||||
_fax_cond.wait();
|
|
||||||
|
|
||||||
switch_channel_set_variable(channel, "KFaxSent", ((_fax_result == kfaxrEndOfTransmission) ? "yes" : "no"));
|
|
||||||
switch_channel_set_variable(channel, "KFaxResult", (Verbose::faxResult((KFaxResult)_fax_result).c_str()));
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "r (unable to lock: %s!)") % err._msg.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch(Board::KhompPvt::InvalidSwitchChannel & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "r (%s)") % err._msg.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "r"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Fax::receiveFax(switch_core_session_t * session, const char *data)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "c (%s)") % data);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
switch_channel_t *channel = _pvt->getFSChannel(session);
|
|
||||||
|
|
||||||
switch_channel_set_variable(channel, "KFaxReceived", "no");
|
|
||||||
switch_channel_set_variable(channel, "KFaxResult", "none");
|
|
||||||
|
|
||||||
std::string fax_string((const char *)data);
|
|
||||||
Strings::vector_type fax_args;
|
|
||||||
|
|
||||||
Strings::tokenize(fax_string, fax_args, "|,");
|
|
||||||
|
|
||||||
if(fax_args.size() != 1 && fax_args.size() != 2)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "r (invalid string '%s': wrong number of separators.)") % fax_string);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedPvtLock lock(_pvt);
|
|
||||||
|
|
||||||
std::string id;
|
|
||||||
|
|
||||||
if(fax_args.size() == 2)
|
|
||||||
{
|
|
||||||
id = fax_args[1];
|
|
||||||
}
|
|
||||||
else if(!_pvt->call()->_dest_addr.empty())
|
|
||||||
{
|
|
||||||
id = _pvt->call()->_dest_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * orig_addr = id.empty() ? NULL : id.c_str();
|
|
||||||
|
|
||||||
int timeout = 5;
|
|
||||||
|
|
||||||
if(!_pvt->call()->_flags.check(Kflags::REALLY_CONNECTED) && !_pvt->loopWhileFlagTimed(Kflags::REALLY_CONNECTED, timeout, false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(!startFaxRX(fax_args[0].c_str(), orig_addr))
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "r (unable to start receive fax)"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_fax_cond.reset();
|
|
||||||
|
|
||||||
lock.unlock();
|
|
||||||
|
|
||||||
_fax_cond.wait();
|
|
||||||
|
|
||||||
switch_channel_set_variable(channel, "KFaxReceived", ((_fax_result == kfaxrEndOfReception) ? "yes" : "no"));
|
|
||||||
switch_channel_set_variable(channel, "KFaxResult", (Verbose::faxResult((KFaxResult)_fax_result).c_str()));
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "r (unable to lock: %s!)") % err._msg.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch(Board::KhompPvt::InvalidSwitchChannel & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "r (%s)") % err._msg.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "r"));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Fax::onFaxChannelRelease(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "c"));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(_pvt);
|
|
||||||
|
|
||||||
if (_pvt->call()->_flags.check(Kflags::FAX_SENDING))
|
|
||||||
{
|
|
||||||
_pvt->call()->_flags.clear(Kflags::FAX_SENDING);
|
|
||||||
|
|
||||||
/* make audio come back.. */
|
|
||||||
_pvt->startStream(false);
|
|
||||||
_pvt->startListen();
|
|
||||||
}
|
|
||||||
else if (_pvt->call()->_flags.check(Kflags::FAX_RECEIVING))
|
|
||||||
{
|
|
||||||
_pvt->call()->_flags.clear(Kflags::FAX_RECEIVING);
|
|
||||||
|
|
||||||
/* make audio come back.. */
|
|
||||||
_pvt->startStream(false);
|
|
||||||
_pvt->startListen();
|
|
||||||
}
|
|
||||||
|
|
||||||
_fax_result = (KFaxResult)e->AddInfo;
|
|
||||||
|
|
||||||
_fax_cond.signal();
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "r (unable to lock %s!)") % err._msg.c_str());
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "r"));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Fax::startFaxTX(const char * orig_addr)
|
|
||||||
{
|
|
||||||
/* no audio after this point, so stop streams! */
|
|
||||||
_pvt->stopStream(false);
|
|
||||||
_pvt->stopListen();
|
|
||||||
|
|
||||||
std::string id;
|
|
||||||
|
|
||||||
if(orig_addr)
|
|
||||||
id = STG(FMT("orig_addr=\"%s\"") % orig_addr);
|
|
||||||
|
|
||||||
const char * param = id.empty() ? NULL : id.c_str();
|
|
||||||
|
|
||||||
|
|
||||||
if (!_pvt->command(KHOMP_LOG, CM_START_FAX_TX, param))
|
|
||||||
{
|
|
||||||
_pvt->startStream(false);
|
|
||||||
_pvt->startListen();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_pvt->call()->_flags.set(Kflags::FAX_SENDING);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Fax::stopFaxTX(void)
|
|
||||||
{
|
|
||||||
/* EV_FAX_CHANNEL_FREE , EV_FAX_FILE_FAIL */
|
|
||||||
if (!_pvt->command(KHOMP_LOG, CM_STOP_FAX_TX))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_pvt->call()->_flags.clear(Kflags::FAX_SENDING);
|
|
||||||
|
|
||||||
/* make audio come back.. */
|
|
||||||
_pvt->startStream(false);
|
|
||||||
_pvt->startListen();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Fax::startFaxRX(const char * filename, const char * orig_addr)
|
|
||||||
{
|
|
||||||
if(!filename)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::string param = STG(FMT("filename=\"%s\"") % filename);
|
|
||||||
|
|
||||||
if(orig_addr)
|
|
||||||
param += STG(FMT(" orig_addr=\"%s\"") % orig_addr);
|
|
||||||
|
|
||||||
/* no audio after this point, so stop streams! */
|
|
||||||
_pvt->stopStream(false);
|
|
||||||
_pvt->stopListen();
|
|
||||||
|
|
||||||
if (!_pvt->command(KHOMP_LOG, CM_START_FAX_RX, param.c_str()))
|
|
||||||
{
|
|
||||||
_pvt->startStream(false);
|
|
||||||
_pvt->startListen();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_pvt->call()->_flags.set(Kflags::FAX_RECEIVING);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Fax::stopFaxRX()
|
|
||||||
{
|
|
||||||
/* Events: EV_FAX_CHANNEL_FREE */
|
|
||||||
if (!_pvt->command(KHOMP_LOG, CM_STOP_FAX_RX))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_pvt->call()->_flags.clear(Kflags::FAX_RECEIVING);
|
|
||||||
|
|
||||||
/* make audio come back.. */
|
|
||||||
_pvt->startStream(false);
|
|
||||||
_pvt->startListen();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Fax::addFaxFile(const char * filename, bool last)
|
|
||||||
{
|
|
||||||
/* Events: EV_FAX_FILE_SENT , EV_FAX_FILE_FAIL , EV_FAX_TX_TIMEOUT */
|
|
||||||
if(!filename)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::string params = STG(FMT("filename=\"%s\" last=\"%s\"") % filename
|
|
||||||
% (last ? "true": "false"));
|
|
||||||
|
|
||||||
if (!_pvt->command(KHOMP_LOG, CM_ADD_FAX_FILE, params.c_str()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
SMS::_SMSEvent SMS::SMSEvent;
|
|
||||||
|
|
||||||
bool SMS::justAlloc(unsigned int count)
|
|
||||||
{
|
|
||||||
/* incoming contexts */
|
|
||||||
MatchExtension::ContextListType contexts;
|
|
||||||
|
|
||||||
contexts.push_back(Opt::_options._context_gsm_sms());
|
|
||||||
|
|
||||||
/* temporary variables */
|
|
||||||
std::string context;
|
|
||||||
std::string exten("s");
|
|
||||||
|
|
||||||
const K3L_DEVICE_CONFIG & dev_cfg = Globals::k3lapi.device_config(_pvt->_target);
|
|
||||||
|
|
||||||
for (MatchExtension::ContextListType::iterator i = contexts.begin(); i != contexts.end(); i++)
|
|
||||||
{
|
|
||||||
replaceTemplate((*i), "DD", _pvt->_target.device);
|
|
||||||
replaceTemplate((*i), "CC", _pvt->_target.object);
|
|
||||||
replaceTemplate((*i), "SSSS", atoi(dev_cfg.SerialNumber));
|
|
||||||
}
|
|
||||||
|
|
||||||
//switch(_pvt->findExtension(exten, context, contexts, _got_sms._type, _got_sms._from, false, true))
|
|
||||||
switch(MatchExtension::findExtension(exten, context, contexts, exten, _got_sms._from, false, true))
|
|
||||||
{
|
|
||||||
case MatchExtension::MATCH_NONE:
|
|
||||||
if( _got_sms._type != "broadcast")
|
|
||||||
{
|
|
||||||
LOG(WARNING, PVT_FMT(_pvt->target(), "unable to find context/exten for incoming SMS (s/%s), processing disabled for this channel.")
|
|
||||||
% (contexts.size() >= 1 ? contexts[0] : "default"));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
default:
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "our: context '%s', exten '%s'") % context % exten);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(unsigned int c = 0; c < count; c++)
|
|
||||||
{
|
|
||||||
|
|
||||||
#if SWITCH_LESS_THAN(1,0,6)
|
|
||||||
switch_core_session_t *session = switch_core_session_request(Globals::khomp_sms_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, NULL);
|
|
||||||
#else
|
|
||||||
switch_core_session_t *session = switch_core_session_request(Globals::khomp_sms_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!session)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "Initilization Error, session not created!"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_core_session_add_stream(session, NULL);
|
|
||||||
|
|
||||||
switch_core_session_set_private(session, _pvt);
|
|
||||||
|
|
||||||
switch_caller_profile_t *caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
|
|
||||||
"Khomp_SMS", //username
|
|
||||||
Opt::_options._dialplan().c_str(), //dialplan
|
|
||||||
NULL, //caller_id_name
|
|
||||||
_got_sms._from.c_str(), //caller_id_number
|
|
||||||
NULL, //network_addr
|
|
||||||
_got_sms._from.c_str(), //ani
|
|
||||||
NULL, //aniii
|
|
||||||
NULL, //rdnis
|
|
||||||
(char *) "mod_khomp", //source
|
|
||||||
context.c_str(), //context
|
|
||||||
exten.c_str()); //destination_number
|
|
||||||
|
|
||||||
if(!caller_profile)
|
|
||||||
{
|
|
||||||
_pvt->destroy(session);
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "r (Cannot create caller profile)"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
|
||||||
|
|
||||||
if(!channel)
|
|
||||||
{
|
|
||||||
_pvt->destroy(session);
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "r (Cannot get channel)"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name = STG(FMT("Khomp_SMS/%d/%d")
|
|
||||||
% _pvt->target().device
|
|
||||||
% _pvt->target().object);
|
|
||||||
|
|
||||||
switch_channel_set_name(channel, name.c_str());
|
|
||||||
switch_channel_set_caller_profile(channel, caller_profile);
|
|
||||||
|
|
||||||
//DBG(FUNC, PVT_FMT(_pvt->target(), "Connect inbound SMS channel %s") % name.c_str());
|
|
||||||
|
|
||||||
switch_channel_set_state(channel, CS_INIT);
|
|
||||||
|
|
||||||
|
|
||||||
_owners.push_front(session);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SMS::justStart()
|
|
||||||
{
|
|
||||||
OwnersList::iterator i = _owners.begin();
|
|
||||||
|
|
||||||
if(i == _owners.end())
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "Cannot get session"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_core_session_t *session = (*i);
|
|
||||||
|
|
||||||
_owners.pop_front();
|
|
||||||
|
|
||||||
if(!session)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "Cannot get session"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
|
||||||
|
|
||||||
if(!channel)
|
|
||||||
{
|
|
||||||
_pvt->destroy(session);
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "r (Cannot get channel)"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_channel_set_variable(channel, "KSmsType", _got_sms._type.c_str());
|
|
||||||
|
|
||||||
if (_got_sms._type == "message" || _got_sms._type == "confirm")
|
|
||||||
{
|
|
||||||
switch_channel_set_variable(channel, "KSmsFrom", _got_sms._from.c_str());
|
|
||||||
switch_channel_set_variable(channel, "KSmsDate", _got_sms._date.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_got_sms._type == "confirm")
|
|
||||||
{
|
|
||||||
switch_channel_set_variable(channel, "KSmsDelivery", _got_sms._sc_date.c_str());
|
|
||||||
switch_channel_set_variable(channel, "KSmsStatus", _got_sms._status.c_str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(_got_sms._type == "broadcast")
|
|
||||||
{
|
|
||||||
switch_channel_set_variable(channel, "KSmsSerial", _got_sms._serial.c_str());
|
|
||||||
switch_channel_set_variable(channel, "KSmsPage", _got_sms._page.c_str());
|
|
||||||
switch_channel_set_variable(channel, "KSmsPages", _got_sms._pages.c_str());
|
|
||||||
}
|
|
||||||
switch_channel_set_variable(channel, "KSmsSize", _got_sms._size.c_str());
|
|
||||||
switch_channel_set_variable(channel, "KSmsMode", _got_sms._coding.c_str());
|
|
||||||
switch_channel_set_variable(channel, "KSmsBody", _got_sms._body.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
_pvt->destroy(session);
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "Error spawning thread"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SMS::sendSMS(switch_core_session_t * session, const char *data)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "(SMS) c"));
|
|
||||||
|
|
||||||
volatile bool finished = false;
|
|
||||||
volatile KGsmCallCause result = kgccNone;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//ScopedAllocLock alloc_lock;
|
|
||||||
|
|
||||||
if(!_can_send)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "(SMS) r (cannot send SMS messages, modem NOT initialized!)"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string sms_string((const char *)data);
|
|
||||||
Strings::vector_type sms_args;
|
|
||||||
|
|
||||||
Strings::tokenize(sms_string, sms_args, "/|,", 3);
|
|
||||||
|
|
||||||
if (sms_args.size() != 3)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "(SMS) r (invalid dial string '%s': wrong number of separators.)") % sms_string);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string dest(sms_args[1]);
|
|
||||||
|
|
||||||
bool conf = false;
|
|
||||||
|
|
||||||
if (dest[0] == '!')
|
|
||||||
{
|
|
||||||
dest.erase(0,1);
|
|
||||||
conf = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dest[dest.size()-1] == '!')
|
|
||||||
{
|
|
||||||
dest.erase(dest.size()-1,1);
|
|
||||||
conf = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get options/values
|
|
||||||
|
|
||||||
_send_sms._dest = dest;
|
|
||||||
_send_sms._conf = conf;
|
|
||||||
_send_sms._body = sms_args[2];
|
|
||||||
|
|
||||||
Request request_sms(_send_sms, &finished, &result);
|
|
||||||
|
|
||||||
_mutex.lock();
|
|
||||||
bool status = _buffer.provide(request_sms);
|
|
||||||
_mutex.unlock();
|
|
||||||
|
|
||||||
_pvt->_mutex.unlock();
|
|
||||||
|
|
||||||
if(status)
|
|
||||||
_cond.signal();
|
|
||||||
|
|
||||||
while (!finished)
|
|
||||||
{
|
|
||||||
usleep(200000);
|
|
||||||
}
|
|
||||||
|
|
||||||
_pvt->_mutex.lock();
|
|
||||||
|
|
||||||
switch_channel_t *channel = _pvt->getFSChannel(session);
|
|
||||||
|
|
||||||
switch_channel_set_variable(channel, "KSmsDelivered", ((KGsmSmsCause)result == ((KGsmSmsCause)0) ? "yes" : "no"));
|
|
||||||
switch_channel_set_variable(channel, "KSmsErrorCode", STG(FMT("%d") % result).c_str());
|
|
||||||
switch_channel_set_variable(channel, "KSmsErrorName", ((KGsmSmsCause)result == ((KGsmSmsCause)0) ? "None" : Verbose::gsmSmsCause((KGsmSmsCause)result).c_str()));
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "(SMS) r (unable to global alloc lock)"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch(Board::KhompPvt::InvalidSwitchChannel & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "(SMS) %s") % err._msg.c_str());
|
|
||||||
//return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ret = ((KGsmSmsCause)result == ((KGsmSmsCause)0));
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "(SMS) r (%s)") % (ret ? "true" : "false"));
|
|
||||||
|
|
||||||
//return (KGsmSmsCause)result;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SMS::onNewSMS(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "(SMS) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(_pvt);
|
|
||||||
|
|
||||||
if(!_can_receive)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "(SMS) received new SMS message(s), but receiving is disabled. keeping the message(s) at the SIM card."));
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
else if(!justAlloc(e->AddInfo))
|
|
||||||
{
|
|
||||||
LOG(WARNING, PVT_FMT(_pvt->target(), "(SMS) unable to allocate channel for new SMS message(s). disabling processing to prevent messages from being lost."));
|
|
||||||
_can_receive = false;
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "downloading %d SMS message(s) on the SIM card.") % e->AddInfo);
|
|
||||||
|
|
||||||
_pvt->command(KHOMP_LOG, CM_GET_SMS);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "(SMS) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "(SMS) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SMS::onSMSInfo(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "(SMS) c"));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(_pvt);
|
|
||||||
|
|
||||||
Globals::k3lapi.get_param(e, "sms_type", _got_sms._type);
|
|
||||||
Globals::k3lapi.get_param(e, "sms_from", _got_sms._from);
|
|
||||||
Globals::k3lapi.get_param(e, "sms_date", _got_sms._date);
|
|
||||||
Globals::k3lapi.get_param(e, "sms_size", _got_sms._size);
|
|
||||||
Globals::k3lapi.get_param(e, "sms_coding", _got_sms._coding);
|
|
||||||
Globals::k3lapi.get_param(e, "sms_serial", _got_sms._serial);
|
|
||||||
Globals::k3lapi.get_param(e, "sms_id", _got_sms._id);
|
|
||||||
Globals::k3lapi.get_param(e, "sms_page", _got_sms._page);
|
|
||||||
Globals::k3lapi.get_param(e, "sms_pages", _got_sms._pages);
|
|
||||||
Globals::k3lapi.get_param(e, "sms_sc_date", _got_sms._sc_date);
|
|
||||||
Globals::k3lapi.get_param(e, "sms_status", _got_sms._status);
|
|
||||||
|
|
||||||
//DBG(FUNC, PVT_FMT(_pvt->target(), "(SMS) type=%s from=%s date=%s size=%s coding=%s serial=%s id=%s page=%s pages=%s sc_date=%s status=%s") % _got_sms._type % _got_sms._from % _got_sms._date % _got_sms._size % _got_sms._coding % _got_sms._serial % _got_sms._id % _got_sms._page % _got_sms._pages % _got_sms._sc_date % _got_sms._status);
|
|
||||||
|
|
||||||
if (_owners.empty() && !justAlloc(1) && (_got_sms._type.compare("broadcast") != 0))
|
|
||||||
{
|
|
||||||
// this error is fatal
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "unable to allocate channel, new SMS message from %s will not be sent to dialplan!") % _got_sms._from);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "(SMS) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "(SMS) r"));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SMS::onSMSData(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "(SMS) c"));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(_pvt);
|
|
||||||
|
|
||||||
if (_owners.empty())
|
|
||||||
{
|
|
||||||
if(_got_sms._type != "broadcast")
|
|
||||||
{
|
|
||||||
LOG(WARNING, PVT_FMT(_pvt->target(), "unable to allocate channel for new SMS message(s). disabling processing to prevent messages from being lost."));
|
|
||||||
_can_receive = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_got_sms._body = (const char *)(e->Params ? e->Params : "");
|
|
||||||
|
|
||||||
SMSEvent(_pvt, _got_sms);
|
|
||||||
|
|
||||||
if(!justStart())
|
|
||||||
{
|
|
||||||
if(_got_sms._type != "broadcast")
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "unable to receive SMS from '%s', something wrong!") % _got_sms._from);
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "disabling SMS processing to prevent messages from being lost."));
|
|
||||||
|
|
||||||
_can_receive = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_can_receive)
|
|
||||||
{
|
|
||||||
/* stats update! */
|
|
||||||
if(_got_sms._type == "message")
|
|
||||||
{
|
|
||||||
statistics<SMSStatistics>()->incrementIncoming();
|
|
||||||
}
|
|
||||||
else if(_got_sms._type == "confirm")
|
|
||||||
{
|
|
||||||
statistics<SMSStatistics>()->incrementConfirm();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
statistics<SMSStatistics>()->incrementBroadcast();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reset data stuff */
|
|
||||||
_got_sms.clear();
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "(SMS) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "(SMS) r"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SMS::onSMSSendResult(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "(SMS) c"));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(_pvt);
|
|
||||||
|
|
||||||
_result = (KGsmCallCause)e->AddInfo;
|
|
||||||
_pvt->call()->_flags.clear(Kflags::SMS_DOING_UPLOAD);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_pvt->target(), "(SMS) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_pvt->target(), "(SMS) r"));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SMS::smsThread(void * sms_ptr)
|
|
||||||
{
|
|
||||||
SMS * sms = static_cast < SMS * > (sms_ptr);
|
|
||||||
|
|
||||||
Board::KhompPvt * pvt = static_cast < Board::KhompPvt * > (sms->_pvt);
|
|
||||||
|
|
||||||
DBG(THRD, PVT_FMT(pvt->target(), "c"));
|
|
||||||
|
|
||||||
bool loop = true;
|
|
||||||
|
|
||||||
while(loop)
|
|
||||||
{
|
|
||||||
if(sms->_cond.wait(1000))
|
|
||||||
{
|
|
||||||
if(sms->_shutdown)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(pvt);
|
|
||||||
|
|
||||||
K3L_CHANNEL_STATUS status;
|
|
||||||
|
|
||||||
KLibraryStatus ret = (KLibraryStatus) k3lGetDeviceStatus(
|
|
||||||
pvt->_target.device,
|
|
||||||
pvt->_target.object + ksoChannel,
|
|
||||||
&status,
|
|
||||||
sizeof(status));
|
|
||||||
|
|
||||||
if (ret == ksSuccess)
|
|
||||||
{
|
|
||||||
switch (status.AddInfo)
|
|
||||||
{
|
|
||||||
case kgsmModemError:
|
|
||||||
case kgsmSIMCardError:
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case kgsmIdle:
|
|
||||||
{
|
|
||||||
/* pede registro do canal.. */
|
|
||||||
pvt->command(KHOMP_LOG, CM_SEND_TO_MODEM, "AT+COPS?");
|
|
||||||
|
|
||||||
/* pede estado da antena.. */
|
|
||||||
pvt->command(KHOMP_LOG, CM_SEND_TO_MODEM, "AT+CSQ?");
|
|
||||||
|
|
||||||
/* forca tipo padrao a ser message... */
|
|
||||||
sms->_got_sms._type = "message";
|
|
||||||
|
|
||||||
/* pre-aloca canal para receber mensagens SMS. */
|
|
||||||
if (sms->justAlloc())
|
|
||||||
{
|
|
||||||
/* habilita processamento de SMSs entrantes */
|
|
||||||
sms->_can_receive = true;
|
|
||||||
|
|
||||||
/* envia comando para "limpar" SMSs do SIM card */
|
|
||||||
pvt->command(KHOMP_LOG, CM_CHECK_NEW_SMS);
|
|
||||||
}
|
|
||||||
|
|
||||||
sms->_got_sms.clear();
|
|
||||||
|
|
||||||
/* sai fora do loop! */
|
|
||||||
loop = false;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(pvt->_target, "unable to obtain lock: %s") % err._msg.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
sms->_can_send = true;
|
|
||||||
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
Request request_sms;
|
|
||||||
|
|
||||||
DBG(THRD, PVT_FMT(pvt->_target, "begin"));
|
|
||||||
|
|
||||||
while(!sms->_buffer.consume(request_sms))
|
|
||||||
{
|
|
||||||
DBG(THRD, PVT_FMT(pvt->_target, "buffer empty"));
|
|
||||||
|
|
||||||
sms->_cond.wait();
|
|
||||||
|
|
||||||
DBG(THRD, PVT_FMT(pvt->_target, "waked up!"));
|
|
||||||
|
|
||||||
if(sms->_shutdown)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(THRD, PVT_FMT(pvt->_target, "processing buffer..."));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int timeout = 30;
|
|
||||||
|
|
||||||
ScopedPvtLock lock(pvt);
|
|
||||||
|
|
||||||
pvt->call()->_flags.set(Kflags::SMS_DOING_UPLOAD);
|
|
||||||
|
|
||||||
if (pvt->command(KHOMP_LOG, CM_PREPARE_SMS, request_sms._send_sms._body.c_str()))
|
|
||||||
{
|
|
||||||
std::string extra = (request_sms._send_sms._conf ? " sms_confirm=\"TRUE\"" : "");
|
|
||||||
|
|
||||||
if (pvt->command(KHOMP_LOG, CM_SEND_SMS,
|
|
||||||
STG(FMT("sms_to=\"%s\"%s") % request_sms._send_sms._dest % extra).c_str()))
|
|
||||||
{
|
|
||||||
if (!pvt->loopWhileFlagTimed(Kflags::SMS_DOING_UPLOAD, timeout))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sms->_result = kgccResourceUnavailable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sms->_result = kgccInvalidMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
pvt->call()->_flags.clear(Kflags::SMS_DOING_UPLOAD);
|
|
||||||
|
|
||||||
if (request_sms._cause)
|
|
||||||
*(request_sms._cause) = (KGsmCallCause)sms->_result;
|
|
||||||
|
|
||||||
if (request_sms._finished)
|
|
||||||
*(request_sms._finished) = true;
|
|
||||||
|
|
||||||
if (sms->_result == kgccNone)
|
|
||||||
{
|
|
||||||
sms->SMSEvent(pvt, sms->_send_sms);
|
|
||||||
|
|
||||||
/* stats update if sent! */
|
|
||||||
sms->statistics<SMSStatistics>()->incrementOutgoing();
|
|
||||||
}
|
|
||||||
|
|
||||||
sms->_send_sms.clear();
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(pvt->_target, "unable to obtain lock: %s") % err._msg.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(pvt->target(), "ok, going to loop..."));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(pvt->target(), "r"));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,124 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#include "frame.h"
|
|
||||||
|
|
||||||
#define ALLOC(T,s) ((T*)calloc(1,s))
|
|
||||||
|
|
||||||
/* Internal frame manager structure. */
|
|
||||||
FrameStorage::FrameStorage(switch_codec_t * codec, int packet_size)
|
|
||||||
: _frames(ALLOC(switch_frame_t, frame_count * sizeof(switch_frame_t))),
|
|
||||||
_buffer(ALLOC( char, audio_count * packet_size)),
|
|
||||||
_index(0)
|
|
||||||
{
|
|
||||||
for (unsigned int i = 0; i < frame_count; i++)
|
|
||||||
{
|
|
||||||
_frames[i].codec = codec;
|
|
||||||
_frames[i].source = "mod_khomp";
|
|
||||||
|
|
||||||
_frames[i].packet = 0;
|
|
||||||
_frames[i].packetlen = 0;
|
|
||||||
_frames[i].extra_data = 0;
|
|
||||||
|
|
||||||
_frames[i].data = (char *)0;
|
|
||||||
_frames[i].datalen = packet_size;
|
|
||||||
_frames[i].buflen = packet_size;
|
|
||||||
|
|
||||||
_frames[i].samples = packet_size; // packet_duration * 8
|
|
||||||
_frames[i].rate = 8000;
|
|
||||||
_frames[i].payload = 0;
|
|
||||||
|
|
||||||
_frames[i].timestamp = 0u;
|
|
||||||
|
|
||||||
_frames[i].seq = 0u;
|
|
||||||
_frames[i].ssrc = 0u;
|
|
||||||
_frames[i].m = SWITCH_FALSE;
|
|
||||||
_frames[i].flags = SFF_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cng_frame.codec = codec;
|
|
||||||
_cng_frame.source = "mod_khomp";
|
|
||||||
_cng_frame.packet = 0;
|
|
||||||
_cng_frame.packetlen = 0;
|
|
||||||
_cng_frame.extra_data = 0;
|
|
||||||
|
|
||||||
_cng_frame.data = (void*)"A";
|
|
||||||
_cng_frame.datalen = 2;
|
|
||||||
_cng_frame.buflen = 2;
|
|
||||||
|
|
||||||
_cng_frame.samples = packet_size;
|
|
||||||
_cng_frame.rate = 8000;
|
|
||||||
_cng_frame.payload = 0;
|
|
||||||
|
|
||||||
_cng_frame.timestamp = 0u;
|
|
||||||
|
|
||||||
_cng_frame.seq = 0u;
|
|
||||||
_cng_frame.ssrc = 0u;
|
|
||||||
_cng_frame.m = SWITCH_FALSE;
|
|
||||||
_cng_frame.flags = SFF_CNG;
|
|
||||||
|
|
||||||
// if (mlock(&_frames, frames_size) < 0)
|
|
||||||
// {
|
|
||||||
// DBG(CONF, F("Unable to lock ast_frame buffer memory in RAM: %s") % strerror(errno));
|
|
||||||
// std::cerr << "chan_khomp: Unable to lock ast_frame buffer memory in RAM: "
|
|
||||||
// << strerror(errno) << ". "
|
|
||||||
// << "This is not a catastrophic failure, but may cause unpredictable "
|
|
||||||
// << "audio delay under extreme load conditions." << std::endl;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (mlock(&_buffer, buffer_size) < 0)
|
|
||||||
// {
|
|
||||||
// DBG(CONF, F("Unable to lock audio buffer memory in RAM: %s") % strerror(errno));
|
|
||||||
// std::cerr << "chan_khomp: Unable to lock temporary audio buffer memory in RAM: "
|
|
||||||
// << strerror(errno) << ". "
|
|
||||||
// << "This is not a catastrophic failure, but may cause unpredictable "
|
|
||||||
// << "audio delay under extreme load conditions." << std::endl;
|
|
||||||
// }
|
|
||||||
};
|
|
||||||
|
|
||||||
FrameStorage::~FrameStorage()
|
|
||||||
{
|
|
||||||
free(_frames);
|
|
||||||
free(_buffer);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#include "globals.h"
|
|
||||||
|
|
||||||
K3LAPI Globals::k3lapi;
|
|
||||||
K3LUtil Globals::k3lutil(Globals::k3lapi);
|
|
||||||
Verbose Globals::verbose(Globals::k3lapi);
|
|
||||||
|
|
||||||
/* Global Timer */
|
|
||||||
Globals::GlobalTimer * Globals::global_timer = NULL;
|
|
||||||
|
|
||||||
Globals::Mutex Globals::khomp_alloc_mutex;
|
|
||||||
|
|
||||||
Config::Options Globals::options;
|
|
||||||
|
|
||||||
const Regex::Expression Globals::regex_allocation("(((([bB])[ ]*([0-9]+))|(([sS])[ ]*([0-9]+)))[ ]*(([cClL])[ ]*([0-9]+)[ ]*([-][ ]*([0-9]+))?)?)|(([rR])[ ]*([0-9]+)[ ]*([-][ ]*([0-9]+))?)", Regex::E_EXTENDED);
|
|
||||||
|
|
||||||
switch_endpoint_interface_t * Globals::khomp_endpoint_interface = NULL;
|
|
||||||
switch_endpoint_interface_t * Globals::khomp_sms_endpoint_interface = NULL;
|
|
||||||
switch_endpoint_interface_t * Globals::khomp_pr_endpoint_interface = NULL;
|
|
||||||
switch_application_interface_t * Globals::khomp_app_inteface = NULL;
|
|
||||||
switch_api_interface_t * Globals::api_interface = NULL;
|
|
||||||
switch_memory_pool_t * Globals::module_pool = NULL;
|
|
||||||
|
|
||||||
volatile bool Globals::logs_being_rotated = false;
|
|
||||||
|
|
||||||
bool Globals::flag_trace_rdsi = false;
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,821 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#include "khomp_pvt_fxo.h"
|
|
||||||
#include "lock.h"
|
|
||||||
#include "logger.h"
|
|
||||||
|
|
||||||
int BoardFXO::KhompPvtFXO::makeCall(std::string params)
|
|
||||||
{
|
|
||||||
DBG(FUNC,PVT_FMT(_target, "(FXO) c"));
|
|
||||||
|
|
||||||
int ret = ksSuccess;
|
|
||||||
|
|
||||||
/* we always have audio */
|
|
||||||
call()->_flags.set(Kflags::HAS_PRE_AUDIO);
|
|
||||||
|
|
||||||
if(callFXO()->_call_info_drop == 0 && !callFXO()->_call_info_report)
|
|
||||||
{
|
|
||||||
command(KHOMP_LOG, CM_DISABLE_CALL_ANSWER_INFO);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!callFXO()->_pre_digits.empty())
|
|
||||||
{
|
|
||||||
/* Seize the line at local PABX. */
|
|
||||||
|
|
||||||
callFXO()->_flags.set(Kflags::CALL_WAIT_SEIZE);
|
|
||||||
|
|
||||||
if (!command(KHOMP_LOG, CM_SEIZE, call()->_orig_addr.c_str()))
|
|
||||||
return ksFail;
|
|
||||||
|
|
||||||
int timeout = 150;
|
|
||||||
|
|
||||||
if(!loopWhileFlagTimed(Kflags::CALL_WAIT_SEIZE, timeout))
|
|
||||||
return ksFail;
|
|
||||||
|
|
||||||
if (callFXO()->_flags.check(Kflags::CALL_WAIT_SEIZE) || (timeout <= 0))
|
|
||||||
return ksFail;
|
|
||||||
|
|
||||||
/* Grab line from local PABX. */
|
|
||||||
|
|
||||||
callFXO()->_flags.set(Kflags::WAIT_SEND_DTMF);
|
|
||||||
|
|
||||||
if (!command(KHOMP_LOG, CM_DIAL_DTMF, callFXO()->_pre_digits.c_str()))
|
|
||||||
return ksFail;
|
|
||||||
|
|
||||||
if(!loopWhileFlagTimed(Kflags::WAIT_SEND_DTMF, timeout))
|
|
||||||
return ksFail;
|
|
||||||
|
|
||||||
if (callFXO()->_flags.check(Kflags::WAIT_SEND_DTMF) || (timeout <= 0))
|
|
||||||
return ksFail;
|
|
||||||
|
|
||||||
/* Seize line from public central (works because the *
|
|
||||||
* continuous cadence is always detected by the k3l api. */
|
|
||||||
|
|
||||||
callFXO()->_flags.set(Kflags::CALL_WAIT_SEIZE);
|
|
||||||
|
|
||||||
if (!command(KHOMP_LOG, CM_SEIZE, call()->_orig_addr.c_str()))
|
|
||||||
return ksFail;
|
|
||||||
|
|
||||||
if(!loopWhileFlagTimed(Kflags::CALL_WAIT_SEIZE, timeout))
|
|
||||||
return ksFail;
|
|
||||||
|
|
||||||
if (callFXO()->_flags.check(Kflags::CALL_WAIT_SEIZE) || (timeout <= 0))
|
|
||||||
return ksFail;
|
|
||||||
|
|
||||||
/* we want the audio as soon as dialing ends */
|
|
||||||
callFXO()->_flags.set(Kflags::EARLY_RINGBACK);
|
|
||||||
|
|
||||||
if (!command(KHOMP_LOG, CM_DIAL_DTMF, call()->_dest_addr.c_str()))
|
|
||||||
return ksFail;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* we want the audio as soon as dialing ends */
|
|
||||||
callFXO()->_flags.set(Kflags::EARLY_RINGBACK);
|
|
||||||
|
|
||||||
|
|
||||||
if(!call()->_orig_addr.empty())
|
|
||||||
params += STG(FMT(" orig_addr=\"%s\"") % _call->_orig_addr);
|
|
||||||
|
|
||||||
|
|
||||||
ret = KhompPvt::makeCall(params);
|
|
||||||
|
|
||||||
if(ret != ksSuccess)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "Fail on make call"));
|
|
||||||
}
|
|
||||||
|
|
||||||
call()->_cleanup_upon_hangup = (ret == ksInvalidParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC,PVT_FMT(_target, "(FXO) r"));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::doChannelAnswer(CommandRequest &cmd)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
// is this a collect call?
|
|
||||||
bool has_recv_collect_call = _call->_collect_call;
|
|
||||||
|
|
||||||
if(has_recv_collect_call)
|
|
||||||
DBG(FUNC, PVT_FMT(target(), "receive a collect call"));
|
|
||||||
|
|
||||||
if(call()->_flags.check(Kflags::DROP_COLLECT))
|
|
||||||
DBG(FUNC, PVT_FMT(target(), "flag DROP_COLLECT == true"));
|
|
||||||
|
|
||||||
// do we have to drop collect calls?
|
|
||||||
bool has_drop_collect_call = call()->_flags.check(Kflags::DROP_COLLECT);
|
|
||||||
|
|
||||||
// do we have to drop THIS call?
|
|
||||||
bool do_drop_call = has_drop_collect_call && has_recv_collect_call;
|
|
||||||
|
|
||||||
if(!do_drop_call)
|
|
||||||
{
|
|
||||||
command(KHOMP_LOG, CM_CONNECT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(has_drop_collect_call)
|
|
||||||
{
|
|
||||||
if(has_recv_collect_call)
|
|
||||||
{
|
|
||||||
usleep(75000);
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(target(), "disconnecting collect call doChannelAnswer FXO"));
|
|
||||||
command(KHOMP_LOG,CM_DISCONNECT);
|
|
||||||
|
|
||||||
// thou shalt not talk anymore!
|
|
||||||
stopListen();
|
|
||||||
stopStream();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(target(), "dropping collect call at doChannelAnswer FXO"));
|
|
||||||
command(KHOMP_LOG, CM_DROP_COLLECT_CALL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = KhompPvt::doChannelAnswer(cmd);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_target,"(FXO) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::onNewCall(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC,PVT_FMT(_target,"(FXO) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
/* we always have audio */
|
|
||||||
call()->_flags.set(Kflags::HAS_PRE_AUDIO);
|
|
||||||
|
|
||||||
ret = KhompPvt::onNewCall(e);
|
|
||||||
|
|
||||||
if(!ret)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
startListen();
|
|
||||||
startStream();
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "(FXO) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::onDisconnect(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
command(KHOMP_LOG, CM_DISCONNECT);
|
|
||||||
|
|
||||||
ret = KhompPvt::onDisconnect(e);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "(FXO) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::onChannelRelease(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
if (call()->_flags.check(Kflags::FAX_SENDING))
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "stopping fax tx"));
|
|
||||||
_fax->stopFaxTX();
|
|
||||||
}
|
|
||||||
else if (call()->_flags.check(Kflags::FAX_RECEIVING))
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "stopping fax rx"));
|
|
||||||
_fax->stopFaxRX();
|
|
||||||
}
|
|
||||||
|
|
||||||
command(KHOMP_LOG, CM_ENABLE_CALL_ANSWER_INFO);
|
|
||||||
|
|
||||||
ret = KhompPvt::onChannelRelease(e);
|
|
||||||
}
|
|
||||||
catch(ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "(FXO) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) r"));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::onCallSuccess(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
ret = KhompPvt::onCallSuccess(e);
|
|
||||||
|
|
||||||
if (call()->_pre_answer)
|
|
||||||
{
|
|
||||||
dtmfSuppression(Opt::_options._out_of_band_dtmfs() && !call()->_flags.check(Kflags::FAX_DETECTED));
|
|
||||||
|
|
||||||
startListen();
|
|
||||||
startStream();
|
|
||||||
switch_channel_mark_pre_answered(getFSChannel());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_target, "(FXO) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch (Board::KhompPvt::InvalidSwitchChannel & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "(FXO) r (%s)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::onCallFail(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
bool ret = true;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
command(KHOMP_LOG, CM_DISCONNECT);
|
|
||||||
|
|
||||||
setHangupCause(causeFromCallFail(e->AddInfo), true);
|
|
||||||
|
|
||||||
ret = KhompPvt::onCallFail(e);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "unable to lock %s!") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::onAudioStatus(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(STRM, PVT_FMT(_target, "(FXO) c"));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
if(e->AddInfo == kmtFax)
|
|
||||||
{
|
|
||||||
DBG(STRM, PVT_FMT(_target, "Fax detected"));
|
|
||||||
|
|
||||||
/* hadn't we did this already? */
|
|
||||||
bool already_detected = call()->_flags.check(Kflags::FAX_DETECTED);
|
|
||||||
|
|
||||||
time_t time_was = call()->_call_statistics->_base_time;
|
|
||||||
time_t time_now = time(NULL);
|
|
||||||
|
|
||||||
bool detection_timeout = (time_now > (time_was + (time_t) (Opt::_options._fax_adjustment_timeout())));
|
|
||||||
|
|
||||||
BEGIN_CONTEXT
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
/* already adjusted? do not adjust again. */
|
|
||||||
if (already_detected || detection_timeout)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (callFXO()->_call_info_drop != 0 || callFXO()->_call_info_report)
|
|
||||||
{
|
|
||||||
/* we did not detected fax yet, send answer info! */
|
|
||||||
setAnswerInfo(Board::KhompPvt::CI_FAX);
|
|
||||||
|
|
||||||
if (callFXO()->_call_info_drop & Board::KhompPvt::CI_FAX)
|
|
||||||
{
|
|
||||||
/* fastest way to force a disconnection */
|
|
||||||
command(KHOMP_LOG,CM_DISCONNECT);//,SCE_HIDE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Opt::_options._auto_fax_adjustment())
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "communication will be adjusted for fax!"));
|
|
||||||
_fax->adjustForFax();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END_CONTEXT
|
|
||||||
|
|
||||||
if (!already_detected)
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
/* adjust the flag */
|
|
||||||
call()->_flags.set(Kflags::FAX_DETECTED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_target, "(FXO) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ret = KhompPvt::onAudioStatus(e);
|
|
||||||
|
|
||||||
DBG(STRM, PVT_FMT(_target, "(FXO) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::onSeizeSuccess(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) c"));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
callFXO()->_flags.clear(Kflags::CALL_WAIT_SEIZE);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_target, "(FXO) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) r"));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::onDtmfDetected(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
if (callFXO()->_flags.check(Kflags::WAIT_SEND_DTMF) ||
|
|
||||||
callFXO()->_flags.check(Kflags::CALL_WAIT_SEIZE))
|
|
||||||
{
|
|
||||||
/* waiting digit or seize means DEADLOCK if we try to
|
|
||||||
* queue something below. */
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "not queueing dtmf, waiting stuff!"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = KhompPvt::onDtmfDetected(e);
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_target, "(FXO) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::onDtmfSendFinish(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
ret = KhompPvt::onDtmfSendFinish(e);
|
|
||||||
|
|
||||||
if (callFXO()->_flags.check(Kflags::EARLY_RINGBACK))
|
|
||||||
{
|
|
||||||
callFXO()->_flags.clear(Kflags::EARLY_RINGBACK);
|
|
||||||
|
|
||||||
/* start grabbing */
|
|
||||||
startListen();
|
|
||||||
|
|
||||||
/* activate resources early... */
|
|
||||||
bool fax_detected = callFXO()->_flags.check(Kflags::FAX_DETECTED);
|
|
||||||
|
|
||||||
bool res_out_of_band_dtmf = Opt::_options._suppression_delay() && Opt::_options._out_of_band_dtmfs() && !fax_detected;
|
|
||||||
bool res_echo_cancellator = Opt::_options._echo_canceller() && !fax_detected;
|
|
||||||
bool res_auto_gain_cntrol = Opt::_options._auto_gain_control() && !fax_detected;
|
|
||||||
|
|
||||||
if (!call()->_flags.check(Kflags::KEEP_DTMF_SUPPRESSION))
|
|
||||||
dtmfSuppression(res_out_of_band_dtmf);
|
|
||||||
|
|
||||||
if (!call()->_flags.check(Kflags::KEEP_ECHO_CANCELLATION))
|
|
||||||
echoCancellation(res_echo_cancellator);
|
|
||||||
|
|
||||||
if (!call()->_flags.check(Kflags::KEEP_AUTO_GAIN_CONTROL))
|
|
||||||
autoGainControl(res_auto_gain_cntrol);
|
|
||||||
|
|
||||||
/* start sending audio if wanted so */
|
|
||||||
if (Opt::_options._fxo_send_pre_audio())
|
|
||||||
startStream();
|
|
||||||
|
|
||||||
//TODO: Verificar isso aqui
|
|
||||||
if (call()->_pre_answer)
|
|
||||||
{
|
|
||||||
/* tell the user we are answered! */
|
|
||||||
switch_channel_mark_answered(getFSChannel());
|
|
||||||
//pvt->signal_state(AST_CONTROL_ANSWER);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* are we ringing, now? lets try this way! */
|
|
||||||
switch_channel_mark_ring_ready(getFSChannel());
|
|
||||||
//pvt->signal_state(AST_CONTROL_RINGING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_target, "(FXO) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch(Board::KhompPvt::InvalidSwitchChannel & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_target, "(FXO) r (no valid channel: %s)") % err._msg.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::onCallAnswerInfo(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) c"));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
int info_code = -1;
|
|
||||||
|
|
||||||
switch (e->AddInfo)
|
|
||||||
{
|
|
||||||
case kcsiCellPhoneMessageBox:
|
|
||||||
info_code = CI_MESSAGE_BOX;
|
|
||||||
break;
|
|
||||||
case kcsiHumanAnswer:
|
|
||||||
info_code = CI_HUMAN_ANSWER;
|
|
||||||
break;
|
|
||||||
case kcsiAnsweringMachine:
|
|
||||||
info_code = CI_ANSWERING_MACHINE;
|
|
||||||
break;
|
|
||||||
case kcsiCarrierMessage:
|
|
||||||
info_code = CI_CARRIER_MESSAGE;
|
|
||||||
break;
|
|
||||||
case kcsiUnknown:
|
|
||||||
info_code = CI_UNKNOWN;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "got an unknown call answer info '%d', ignoring...") % e->AddInfo);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info_code != -1)
|
|
||||||
{
|
|
||||||
if (callFXO()->_call_info_report)
|
|
||||||
{
|
|
||||||
//TODO: HOW WE TREAT THAT
|
|
||||||
// make the channel export this
|
|
||||||
setAnswerInfo(info_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callFXO()->_call_info_drop & info_code)
|
|
||||||
{
|
|
||||||
command(KHOMP_LOG,CM_DISCONNECT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_target,"(FXO) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) r"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::application(ApplicationType type, switch_core_session_t * session, const char *data)
|
|
||||||
{
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case FAX_ADJUST:
|
|
||||||
return _fax->adjustForFax();
|
|
||||||
case FAX_SEND:
|
|
||||||
return _fax->sendFax(session, data);
|
|
||||||
case FAX_RECEIVE:
|
|
||||||
return _fax->receiveFax(session, data);
|
|
||||||
case USER_TRANSFER:
|
|
||||||
return _transfer->userTransfer(session, data);
|
|
||||||
default:
|
|
||||||
return KhompPvt::application(type, session, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::setupConnection()
|
|
||||||
{
|
|
||||||
if(!call()->_flags.check(Kflags::IS_INCOMING) && !call()->_flags.check(Kflags::IS_OUTGOING))
|
|
||||||
{
|
|
||||||
DBG(FUNC,PVT_FMT(_target, "Channel already disconnected"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
callFXO()->_flags.clear(Kflags::CALL_WAIT_SEIZE);
|
|
||||||
callFXO()->_flags.clear(Kflags::WAIT_SEND_DTMF);
|
|
||||||
|
|
||||||
/* if received some disconnect from 'drop collect call'
|
|
||||||
feature of some pbx, then leave the call rock and rolling */
|
|
||||||
//Board::board(_target.device)->_timers.del(callFXO()->_idx_disconnect);
|
|
||||||
|
|
||||||
bool fax_detected = callFXO()->_flags.check(Kflags::FAX_DETECTED) || (callFXO()->_var_fax_adjust == T_TRUE);
|
|
||||||
|
|
||||||
bool res_out_of_band_dtmf = (call()->_var_dtmf_state == T_UNKNOWN || fax_detected ?
|
|
||||||
Opt::_options._suppression_delay() && Opt::_options._out_of_band_dtmfs() && !fax_detected : (call()->_var_dtmf_state == T_TRUE));
|
|
||||||
|
|
||||||
bool res_echo_cancellator = (call()->_var_echo_state == T_UNKNOWN || fax_detected ?
|
|
||||||
Opt::_options._echo_canceller() && !fax_detected : (call()->_var_echo_state == T_TRUE));
|
|
||||||
|
|
||||||
bool res_auto_gain_cntrol = (call()->_var_gain_state == T_UNKNOWN || fax_detected ?
|
|
||||||
Opt::_options._auto_gain_control() && !fax_detected : (call()->_var_gain_state == T_TRUE));
|
|
||||||
|
|
||||||
if (!call()->_flags.check(Kflags::REALLY_CONNECTED))
|
|
||||||
{
|
|
||||||
obtainRX(res_out_of_band_dtmf);
|
|
||||||
|
|
||||||
/* esvazia buffers de leitura/escrita */
|
|
||||||
cleanupBuffers();
|
|
||||||
|
|
||||||
if (!call()->_flags.check(Kflags::KEEP_DTMF_SUPPRESSION))
|
|
||||||
dtmfSuppression(res_out_of_band_dtmf);
|
|
||||||
|
|
||||||
if (!call()->_flags.check(Kflags::KEEP_ECHO_CANCELLATION))
|
|
||||||
echoCancellation(res_echo_cancellator);
|
|
||||||
|
|
||||||
if (!call()->_flags.check(Kflags::KEEP_AUTO_GAIN_CONTROL))
|
|
||||||
autoGainControl(res_auto_gain_cntrol);
|
|
||||||
|
|
||||||
startListen(false);
|
|
||||||
|
|
||||||
startStream();
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) Audio callbacks initialized successfully"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return KhompPvt::setupConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::autoGainControl(bool enable)
|
|
||||||
{
|
|
||||||
bool ret = KhompPvt::autoGainControl(enable);
|
|
||||||
|
|
||||||
/* enable this AGC also, can be very useful */
|
|
||||||
ret &= command(KHOMP_LOG, (enable ? CM_ENABLE_PLAYER_AGC : CM_DISABLE_PLAYER_AGC));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BoardFXO::KhompPvtFXO::setAnswerInfo(int answer_info)
|
|
||||||
{
|
|
||||||
const char * value = answerInfoToString(answer_info);
|
|
||||||
|
|
||||||
if (value == NULL)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target,"signaled unknown call answer info '%d', using 'Unknown'...") % answer_info);
|
|
||||||
value = "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC,PVT_FMT(_target,"KCallAnswerInfo: %s") % value);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
setFSChannelVar("KCallAnswerInfo", value);
|
|
||||||
}
|
|
||||||
catch(Board::KhompPvt::InvalidSwitchChannel & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR,PVT_FMT(_target,"Cannot obtain the channel variable: %s") % err._msg.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::indicateBusyUnlocked(int cause, bool sent_signaling)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) c"));
|
|
||||||
|
|
||||||
if(!KhompPvt::indicateBusyUnlocked(cause, sent_signaling))
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(FXO) r (false)"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(call()->_flags.check(Kflags::IS_INCOMING))
|
|
||||||
{
|
|
||||||
/* already connected or sent signaling... */
|
|
||||||
mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
|
|
||||||
|
|
||||||
if(!call()->_flags.check(Kflags::CONNECTED) && !sent_signaling)
|
|
||||||
{
|
|
||||||
/* we are talking about branches, not trunks */
|
|
||||||
command(KHOMP_LOG, CM_CONNECT);
|
|
||||||
callFXO()->_busy_disconnect = Board::board(_target.device)->_timers.add(Opt::_options._fxo_busy_disconnection(), &BoardFXO::KhompPvtFXO::busyDisconnect, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(call()->_flags.check(Kflags::IS_OUTGOING))
|
|
||||||
{
|
|
||||||
/* already connected or sent signaling... */
|
|
||||||
mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC,PVT_FMT(_target, "(FXO) r"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BoardFXO::KhompPvtFXO::busyDisconnect(Board::KhompPvt * pvt)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(pvt->target(), "Disconnecting FXO"));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(pvt);
|
|
||||||
pvt->command(KHOMP_LOG, CM_DISCONNECT);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(pvt->target(), "unable to lock the pvt !"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BoardFXO::KhompPvtFXO::reportFailToReceive(int fail_code)
|
|
||||||
{
|
|
||||||
KhompPvt::reportFailToReceive(fail_code);
|
|
||||||
|
|
||||||
command(KHOMP_LOG, CM_CONNECT);
|
|
||||||
command(KHOMP_LOG, CM_DISCONNECT);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::validContexts(
|
|
||||||
MatchExtension::ContextListType & contexts, std::string extra_context)
|
|
||||||
{
|
|
||||||
DBG(FUNC,PVT_FMT(_target,"(FXO) c"));
|
|
||||||
|
|
||||||
if(!_group_context.empty())
|
|
||||||
{
|
|
||||||
contexts.push_back(_group_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
contexts.push_back(Opt::_options._context_fxo());
|
|
||||||
contexts.push_back(Opt::_options._context2_fxo());
|
|
||||||
|
|
||||||
for (MatchExtension::ContextListType::iterator i = contexts.begin(); i != contexts.end(); i++)
|
|
||||||
{
|
|
||||||
replaceTemplate((*i), "CC", _target.object);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ret = Board::KhompPvt::validContexts(contexts,extra_context);
|
|
||||||
|
|
||||||
DBG(FUNC,PVT_FMT(_target,"(FXO) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::isOK()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
K3L_CHANNEL_STATUS status;
|
|
||||||
|
|
||||||
if (k3lGetDeviceStatus (_target.device, _target.object + ksoChannel, &status, sizeof (status)) != ksSuccess)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return (status.AddInfo == kfcsEnabled);
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "unable to lock %s!") % err._msg.c_str() );
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardFXO::KhompPvtFXO::sendDtmf(std::string digit)
|
|
||||||
{
|
|
||||||
if(_transfer->checkUserXferUnlocked(digit))
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(target(), "started (or waiting for) an user xfer"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ret = KhompPvt::sendDtmf(callFXO()->_digits_buffer);
|
|
||||||
|
|
||||||
callFXO()->_digits_buffer.clear();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,572 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#include "khomp_pvt_gsm.h"
|
|
||||||
#include "lock.h"
|
|
||||||
#include "logger.h"
|
|
||||||
|
|
||||||
bool BoardGSM::KhompPvtGSM::isOK()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
K3L_CHANNEL_STATUS status;
|
|
||||||
|
|
||||||
if (k3lGetDeviceStatus (_target.device, _target.object + ksoChannel, &status, sizeof (status)) != ksSuccess)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (status.AddInfo)
|
|
||||||
{
|
|
||||||
case kgsmModemError:
|
|
||||||
case kgsmSIMCardError:
|
|
||||||
case kgsmNetworkError:
|
|
||||||
case kgsmNotReady:
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "unable to lock %s!") % err._msg.c_str() );
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardGSM::KhompPvtGSM::onChannelRelease(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(GSM) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
call()->_flags.clear(Kflags::HAS_PRE_AUDIO);
|
|
||||||
command(KHOMP_LOG, CM_ENABLE_CALL_ANSWER_INFO);
|
|
||||||
|
|
||||||
ret = KhompPvt::onChannelRelease(e);
|
|
||||||
}
|
|
||||||
catch(ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "(GSM) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(GSM) r"));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardGSM::KhompPvtGSM::onCallSuccess(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(GSM) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
ret = KhompPvt::onCallSuccess(e);
|
|
||||||
|
|
||||||
if (call()->_pre_answer)
|
|
||||||
{
|
|
||||||
dtmfSuppression(Opt::_options._out_of_band_dtmfs());
|
|
||||||
|
|
||||||
startListen();
|
|
||||||
startStream();
|
|
||||||
switch_channel_mark_pre_answered(getFSChannel());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_target, "(GSM) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch (Board::KhompPvt::InvalidSwitchChannel & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "(GSM) r (%s)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(GSM) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BoardGSM::KhompPvtGSM::setAnswerInfo(int answer_info)
|
|
||||||
{
|
|
||||||
const char * value = answerInfoToString(answer_info);
|
|
||||||
|
|
||||||
if (value == NULL)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target,"signaled unknown call answer info '%d', using 'Unknown'...") % answer_info);
|
|
||||||
value = "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC,PVT_FMT(_target,"KCallAnswerInfo: %s") % value);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
setFSChannelVar("KCallAnswerInfo",value);
|
|
||||||
}
|
|
||||||
catch(Board::KhompPvt::InvalidSwitchChannel & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR,PVT_FMT(_target,"Cannot obtain the channel variable: %s") % err._msg.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardGSM::KhompPvtGSM::onCallAnswerInfo(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(GSM) c"));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
int info_code = -1;
|
|
||||||
|
|
||||||
switch (e->AddInfo)
|
|
||||||
{
|
|
||||||
case kcsiCellPhoneMessageBox:
|
|
||||||
info_code = CI_MESSAGE_BOX;
|
|
||||||
break;
|
|
||||||
case kcsiHumanAnswer:
|
|
||||||
info_code = CI_HUMAN_ANSWER;
|
|
||||||
break;
|
|
||||||
case kcsiAnsweringMachine:
|
|
||||||
info_code = CI_ANSWERING_MACHINE;
|
|
||||||
break;
|
|
||||||
case kcsiCarrierMessage:
|
|
||||||
info_code = CI_CARRIER_MESSAGE;
|
|
||||||
break;
|
|
||||||
case kcsiUnknown:
|
|
||||||
info_code = CI_UNKNOWN;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "got an unknown call answer info '%d', ignoring...") % e->AddInfo);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info_code != -1)
|
|
||||||
{
|
|
||||||
if (callGSM()->_call_info_report)
|
|
||||||
{
|
|
||||||
//TODO: HOW WE TREAT THAT
|
|
||||||
// make the channel export this
|
|
||||||
setAnswerInfo(info_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callGSM()->_call_info_drop & info_code)
|
|
||||||
{
|
|
||||||
command(KHOMP_LOG, CM_SEND_TO_MODEM, "ATH");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_target,"(GSM) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(GSM) r"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
bool BoardGSM::KhompPvtGSM::onDtmfDetected(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
bool ret = KhompPvt::onDtmfDetected(e);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_target, "(GSM) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardGSM::KhompPvtGSM::onNewCall(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC,PVT_FMT(_target,"(GSM) c"));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
bool ret = KhompPvtGSM::onNewCall(e);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "(GSM) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(GSM) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool BoardGSM::KhompPvtGSM::onCallFail(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
bool ret = true;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
//K::internal::gsm_cleanup_and_restart(pvt, owner_nr, true);
|
|
||||||
setHangupCause(causeFromCallFail(e->AddInfo), true);
|
|
||||||
|
|
||||||
ret = KhompPvt::onCallFail(e);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "unable to lock %s!") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardGSM::KhompPvtGSM::onDisconnect(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
bool ret = true;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
//gsm_cleanup_and_restart(pvt, (int)evt.gsm_call_ref);
|
|
||||||
|
|
||||||
ret = KhompPvt::onDisconnect(e);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "(GSM) unable to lock %s!") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int BoardGSM::KhompPvtGSM::makeCall(std::string params)
|
|
||||||
{
|
|
||||||
DBG(FUNC,PVT_FMT(_target, "(GSM) c"));
|
|
||||||
|
|
||||||
if(callGSM()->_call_info_drop == 0 && !callGSM()->_call_info_report)
|
|
||||||
{
|
|
||||||
command(KHOMP_LOG, CM_DISABLE_CALL_ANSWER_INFO);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!_call->_orig_addr.compare("restricted"))
|
|
||||||
params += " orig_addr=\"restricted\"";
|
|
||||||
|
|
||||||
int ret = KhompPvt::makeCall(params);
|
|
||||||
|
|
||||||
if(ret != ksSuccess)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "Fail on make call"));
|
|
||||||
}
|
|
||||||
|
|
||||||
call()->_cleanup_upon_hangup = (ret == ksInvalidParams || ret == ksInvalidState);
|
|
||||||
|
|
||||||
DBG(FUNC,PVT_FMT(_target, "(GSM) r"));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardGSM::KhompPvtGSM::doChannelAnswer(CommandRequest &cmd)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(GSM) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
command(KHOMP_LOG, CM_CONNECT);
|
|
||||||
|
|
||||||
ret = KhompPvt::doChannelAnswer(cmd);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_target,"(GSM) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(GSM) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardGSM::KhompPvtGSM::doChannelHangup(CommandRequest &cmd)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(GSM) c"));
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
int owner_nr = 0;
|
|
||||||
|
|
||||||
command(KHOMP_LOG, CM_DISCONNECT,
|
|
||||||
STG(FMT("gsm_call_ref=%d") % (int)owner_nr).c_str());
|
|
||||||
|
|
||||||
|
|
||||||
//ret = KhompPvt::doChannelHangup(cmd);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(_target,"(GSM) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(GSM) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardGSM::KhompPvtGSM::application(ApplicationType type, switch_core_session_t * session, const char *data)
|
|
||||||
{
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case SMS_CHECK:
|
|
||||||
return true;
|
|
||||||
case SMS_SEND:
|
|
||||||
return _sms->sendSMS(session, data);
|
|
||||||
case SELECT_SIM_CARD:
|
|
||||||
return selectSimCard(data);
|
|
||||||
default:
|
|
||||||
return KhompPvt::application(type, session, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardGSM::KhompPvtGSM::setupConnection()
|
|
||||||
{
|
|
||||||
if(!call()->_flags.check(Kflags::IS_INCOMING) && !call()->_flags.check(Kflags::IS_OUTGOING))
|
|
||||||
{
|
|
||||||
DBG(FUNC,PVT_FMT(_target, "Channel already disconnected"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool res_out_of_band_dtmf = (call()->_var_dtmf_state == T_UNKNOWN ?
|
|
||||||
Opt::_options._suppression_delay() && Opt::_options._out_of_band_dtmfs() : (call()->_var_dtmf_state == T_TRUE));
|
|
||||||
|
|
||||||
bool res_echo_cancellator = (call()->_var_echo_state == T_UNKNOWN ?
|
|
||||||
Opt::_options._echo_canceller() : (call()->_var_echo_state == T_TRUE));
|
|
||||||
|
|
||||||
|
|
||||||
bool res_auto_gain_cntrol = (call()->_var_gain_state == T_UNKNOWN ?
|
|
||||||
Opt::_options._auto_gain_control() : (call()->_var_gain_state == T_TRUE));
|
|
||||||
|
|
||||||
|
|
||||||
if (!call()->_flags.check(Kflags::REALLY_CONNECTED))
|
|
||||||
{
|
|
||||||
obtainRX(res_out_of_band_dtmf);
|
|
||||||
|
|
||||||
/* esvazia buffers de leitura/escrita */
|
|
||||||
cleanupBuffers();
|
|
||||||
|
|
||||||
if (!call()->_flags.check(Kflags::KEEP_DTMF_SUPPRESSION))
|
|
||||||
dtmfSuppression(res_out_of_band_dtmf);
|
|
||||||
|
|
||||||
if (!call()->_flags.check(Kflags::KEEP_ECHO_CANCELLATION))
|
|
||||||
echoCancellation(res_echo_cancellator);
|
|
||||||
|
|
||||||
if (!call()->_flags.check(Kflags::KEEP_AUTO_GAIN_CONTROL))
|
|
||||||
autoGainControl(res_auto_gain_cntrol);
|
|
||||||
|
|
||||||
startListen(false);
|
|
||||||
|
|
||||||
startStream();
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(GSM) Audio callbacks initialized successfully"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Board::KhompPvt::setupConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardGSM::KhompPvtGSM::indicateBusyUnlocked(int cause, bool sent_signaling)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(GSM) c"));
|
|
||||||
|
|
||||||
if(!KhompPvt::indicateBusyUnlocked(cause, sent_signaling))
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(GSM) r (false)"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(call()->_flags.check(Kflags::IS_INCOMING))
|
|
||||||
{
|
|
||||||
if(!call()->_flags.check(Kflags::CONNECTED) && !sent_signaling)
|
|
||||||
{
|
|
||||||
/* we are talking about branches, not trunks */
|
|
||||||
command(KHOMP_LOG, CM_DISCONNECT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* already connected or sent signaling... */
|
|
||||||
mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(call()->_flags.check(Kflags::IS_OUTGOING))
|
|
||||||
{
|
|
||||||
/* already connected or sent signaling... */
|
|
||||||
mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC,PVT_FMT(_target, "(GSM) r"));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BoardGSM::KhompPvtGSM::reportFailToReceive(int fail_code)
|
|
||||||
{
|
|
||||||
KhompPvt::reportFailToReceive(fail_code);
|
|
||||||
|
|
||||||
command(KHOMP_LOG, CM_CONNECT);
|
|
||||||
|
|
||||||
/* K3L may fail depending on its configuration (GsmModem) */
|
|
||||||
if (!command(KHOMP_LOG, CM_DISCONNECT))
|
|
||||||
{
|
|
||||||
int owner_nr = 0;
|
|
||||||
command(KHOMP_LOG, CM_DISCONNECT,
|
|
||||||
STG(FMT("gsm_call_ref=\"%d\"") % owner_nr).c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int BoardGSM::KhompPvtGSM::causeFromCallFail(int fail)
|
|
||||||
{
|
|
||||||
int switch_cause = SWITCH_CAUSE_USER_BUSY;
|
|
||||||
|
|
||||||
if (fail <= 127)
|
|
||||||
switch_cause = fail;
|
|
||||||
else
|
|
||||||
switch_cause = SWITCH_CAUSE_INTERWORKING;
|
|
||||||
|
|
||||||
return switch_cause;
|
|
||||||
}
|
|
||||||
|
|
||||||
int BoardGSM::KhompPvtGSM::callFailFromCause(int cause)
|
|
||||||
{
|
|
||||||
int k3l_fail = -1; // default
|
|
||||||
|
|
||||||
if (cause <= 127)
|
|
||||||
k3l_fail = cause;
|
|
||||||
else
|
|
||||||
k3l_fail = kgccInterworking;
|
|
||||||
|
|
||||||
return k3l_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardGSM::KhompPvtGSM::validContexts(
|
|
||||||
MatchExtension::ContextListType & contexts, std::string extra_context)
|
|
||||||
{
|
|
||||||
DBG(FUNC,PVT_FMT(_target,"(GSM) c"));
|
|
||||||
|
|
||||||
if(!_group_context.empty())
|
|
||||||
{
|
|
||||||
contexts.push_back(_group_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!extra_context.empty())
|
|
||||||
{
|
|
||||||
if (!_group_context.empty())
|
|
||||||
{
|
|
||||||
std::string pvt_context(_group_context);
|
|
||||||
pvt_context += "-";
|
|
||||||
pvt_context += extra_context;
|
|
||||||
contexts.push_back(pvt_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Opt::_options._context_gsm_call().empty())
|
|
||||||
{
|
|
||||||
std::string context(Opt::_options._context_gsm_call());
|
|
||||||
context += "-";
|
|
||||||
context += extra_context;
|
|
||||||
contexts.push_back(_group_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Opt::_options._context2_gsm_call().empty())
|
|
||||||
{
|
|
||||||
std::string context(Opt::_options._context2_gsm_call());
|
|
||||||
context += "-";
|
|
||||||
context += extra_context;
|
|
||||||
contexts.push_back(_group_context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
contexts.push_back(Opt::_options._context_gsm_call());
|
|
||||||
contexts.push_back(Opt::_options._context2_gsm_call());
|
|
||||||
|
|
||||||
for (MatchExtension::ContextListType::iterator i = contexts.begin(); i != contexts.end(); i++)
|
|
||||||
replaceTemplate((*i), "CC", _target.object);
|
|
||||||
|
|
||||||
bool ret = Board::KhompPvt::validContexts(contexts,extra_context);
|
|
||||||
|
|
||||||
DBG(FUNC,PVT_FMT(_target,"(GSM) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,295 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#include "khomp_pvt_passive.h"
|
|
||||||
#include "lock.h"
|
|
||||||
#include "logger.h"
|
|
||||||
|
|
||||||
bool BoardPassive::KhompPvtPassive::validContexts(
|
|
||||||
MatchExtension::ContextListType & contexts, std::string extra_context)
|
|
||||||
{
|
|
||||||
DBG(FUNC,PVT_FMT(_target,"(Passive) c"));
|
|
||||||
|
|
||||||
if(!_group_context.empty())
|
|
||||||
{
|
|
||||||
contexts.push_back(_group_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
contexts.push_back(Opt::_options._context_pr());
|
|
||||||
|
|
||||||
for (MatchExtension::ContextListType::iterator i = contexts.begin(); i != contexts.end(); i++)
|
|
||||||
{
|
|
||||||
replaceTemplate((*i), "CC", _target.object);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ret = Board::KhompPvt::validContexts(contexts,extra_context);
|
|
||||||
|
|
||||||
DBG(FUNC,PVT_FMT(_target,"(Passive) r"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardPassive::KhompPvtHI::onSeizureStart(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC,PVT_FMT(_target,"(HI) c"));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
_call->_orig_addr.clear();
|
|
||||||
_call->_dest_addr = "s";
|
|
||||||
|
|
||||||
#if SWITCH_LESS_THAN(1,0,6)
|
|
||||||
session(switch_core_session_request(Globals::khomp_pr_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, NULL));
|
|
||||||
#else
|
|
||||||
session(switch_core_session_request(Globals::khomp_pr_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (justAlloc(true) != SWITCH_STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
setHangupCause(SWITCH_CAUSE_UNALLOCATED_NUMBER);
|
|
||||||
cleanup(CLN_FAIL);
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "(HI) r (Initilization Error on alloc!)"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* begin context adjusting + processing */
|
|
||||||
MatchExtension::ContextListType contexts;
|
|
||||||
|
|
||||||
validContexts(contexts);
|
|
||||||
|
|
||||||
std::string tmp_exten;
|
|
||||||
std::string tmp_context;
|
|
||||||
|
|
||||||
switch (MatchExtension::findExtension(tmp_exten, tmp_context, contexts, call()->_dest_addr, call()->_orig_addr, false))
|
|
||||||
{
|
|
||||||
case MatchExtension::MATCH_NONE:
|
|
||||||
destroy();
|
|
||||||
owner(NULL);
|
|
||||||
LOG(WARNING, PVT_FMT(_target, "(HI) r (unable to find exten/context on incoming call %s/%s)")
|
|
||||||
% _call->_dest_addr % (contexts.size() >= 1 ? contexts[0] : "default"));
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(HI) our: context '%s', exten '%s'") % tmp_context % tmp_exten);
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
call()->_incoming_context = tmp_context;
|
|
||||||
_call->_dest_addr = tmp_exten;
|
|
||||||
|
|
||||||
startListen();
|
|
||||||
|
|
||||||
if (justStart() != SWITCH_STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
setHangupCause(SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL);
|
|
||||||
cleanup(CLN_FAIL);
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "(HI) r (Initilization Error on start!)"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
call()->_flags.set(Kflags::REALLY_CONNECTED);
|
|
||||||
call()->statistics()->incrementNewCall();
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "(HI) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(HI) r"));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardPassive::KhompPvtKPR::onNewCall(K3L_EVENT *e)
|
|
||||||
{
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(KPR) c"));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::string orig_addr, dest_addr;
|
|
||||||
|
|
||||||
Globals::k3lapi.get_param(e, "orig_addr", orig_addr);
|
|
||||||
Globals::k3lapi.get_param(e, "dest_addr", dest_addr);
|
|
||||||
|
|
||||||
if(dest_addr.empty())
|
|
||||||
{
|
|
||||||
dest_addr="s";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isdn_reverse_charge = false;
|
|
||||||
std::string isdn_reverse_charge_str;
|
|
||||||
int isdn_status = Globals::k3lapi.get_param(e, "isdn_reverse_charge", isdn_reverse_charge_str);
|
|
||||||
|
|
||||||
if (isdn_status == ksSuccess && !isdn_reverse_charge_str.empty())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
isdn_reverse_charge = Strings::toboolean(isdn_reverse_charge_str);
|
|
||||||
}
|
|
||||||
catch (Strings::invalid_value & err)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
long int r2_category = -1;
|
|
||||||
std::string r2_categ_a;
|
|
||||||
int r2_status = Globals::k3lapi.get_param(e, "r2_categ_a", r2_categ_a);
|
|
||||||
|
|
||||||
if (r2_status == ksSuccess && !r2_categ_a.empty())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
r2_category = Strings::toulong(r2_categ_a);
|
|
||||||
}
|
|
||||||
catch (Strings::invalid_value e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedPvtLock lock(this);
|
|
||||||
|
|
||||||
_call->_orig_addr = orig_addr;
|
|
||||||
_call->_dest_addr = dest_addr;
|
|
||||||
|
|
||||||
if(isdn_reverse_charge || r2_category == kg2CollectCall)
|
|
||||||
{
|
|
||||||
call()->_collect_call = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if SWITCH_LESS_THAN(1,0,6)
|
|
||||||
session(switch_core_session_request(Globals::khomp_pr_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, NULL));
|
|
||||||
#else
|
|
||||||
session(switch_core_session_request(Globals::khomp_pr_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (justAlloc(true) != SWITCH_STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
setHangupCause(SWITCH_CAUSE_UNALLOCATED_NUMBER);
|
|
||||||
cleanup(CLN_FAIL);
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "(KPR) r (Initilization Error on alloc!)"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* begin context adjusting + processing */
|
|
||||||
MatchExtension::ContextListType contexts;
|
|
||||||
|
|
||||||
validContexts(contexts);
|
|
||||||
|
|
||||||
std::string tmp_exten;
|
|
||||||
std::string tmp_context;
|
|
||||||
|
|
||||||
switch (MatchExtension::findExtension(tmp_exten, tmp_context, contexts, call()->_dest_addr, call()->_orig_addr, false))
|
|
||||||
{
|
|
||||||
case MatchExtension::MATCH_NONE:
|
|
||||||
destroy();
|
|
||||||
owner(NULL);
|
|
||||||
LOG(WARNING, PVT_FMT(_target, "(KPR) r (unable to find exten/context on incoming call %s/%s)")
|
|
||||||
% _call->_dest_addr % (contexts.size() >= 1 ? contexts[0] : "default"));
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(KPR) our: context '%s', exten '%s'") % tmp_context % tmp_exten);
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
call()->_incoming_context = tmp_context;
|
|
||||||
_call->_dest_addr = tmp_exten;
|
|
||||||
|
|
||||||
obtainBoth();
|
|
||||||
|
|
||||||
startListen(false);
|
|
||||||
|
|
||||||
if (justStart() != SWITCH_STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
setHangupCause(SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL);
|
|
||||||
cleanup(CLN_FAIL);
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "(KPR) r (Initilization Error on start!)"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
call()->_flags.set(Kflags::REALLY_CONNECTED);
|
|
||||||
call()->statistics()->incrementNewCall();
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(ScopedLockFailed & err)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "(KPR) r (unable to lock %s!)") % err._msg.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG(FUNC, PVT_FMT(_target, "(KPR) r"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BoardPassive::KhompPvtKPR::obtainBoth()
|
|
||||||
{
|
|
||||||
/* estes buffers *NAO PODEM SER ESTATICOS*! */
|
|
||||||
char cmd1[] = { 0x3f, 0x03, 0xff, 0x00, 0x05, 0xff };
|
|
||||||
char cmd2[] = { 0x3f, 0x03, 0xff, 0x01, 0x05, 0xff };
|
|
||||||
|
|
||||||
cmd1[2] = cmd1[5] = cmd2[2] = _target.object;
|
|
||||||
cmd2[5] = _target.object + 30;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int dsp = Globals::k3lapi.get_dsp(_target.device, K3LAPI::DSP_AUDIO);
|
|
||||||
|
|
||||||
Globals::k3lapi.raw_command(_target.device, dsp, cmd1, sizeof(cmd1));
|
|
||||||
|
|
||||||
Globals::k3lapi.raw_command(_target.device, dsp, cmd2, sizeof(cmd2));
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(K3LAPI::failed_raw_command & e)
|
|
||||||
{
|
|
||||||
LOG(ERROR, PVT_FMT(target(), "ERROR sending mixer command!"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,138 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#include "lock.h"
|
|
||||||
|
|
||||||
/* ScopedPvtLock */
|
|
||||||
|
|
||||||
ScopedPvtLock::ScopedPvtLock(KhompPvt * pvt)
|
|
||||||
: ScopedLockBasic(false), _pvt(pvt)
|
|
||||||
{
|
|
||||||
//DBG(LOCK, DP(_pvt, "c"));
|
|
||||||
|
|
||||||
if (! _pvt)
|
|
||||||
throw ScopedLockFailed(ScopedLockFailed::NULL_PVT, "null KhompPvt");
|
|
||||||
|
|
||||||
switch(_pvt->_mutex.lock())
|
|
||||||
{
|
|
||||||
case SimpleLock::FAILURE:
|
|
||||||
throw ScopedLockFailed(ScopedLockFailed::FAILED, "Failure");
|
|
||||||
break;
|
|
||||||
case SimpleLock::ISINUSE:
|
|
||||||
throw ScopedLockFailed(ScopedLockFailed::FAILED, "In use");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_locked = true;
|
|
||||||
|
|
||||||
//DBG(LOCK, DP(_pvt, "r"));
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedPvtLock::~ScopedPvtLock()
|
|
||||||
{
|
|
||||||
//DBG(LOCK, DP(_pvt, "c"));
|
|
||||||
unlock();
|
|
||||||
//DBG(LOCK, DP(_pvt, "r"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScopedPvtLock::unlock()
|
|
||||||
{
|
|
||||||
//DBG(LOCK, DP(_pvt, "c"));
|
|
||||||
|
|
||||||
if (_locked)
|
|
||||||
{
|
|
||||||
//DBG(LOCK, DP(_pvt, "unlocking!"));
|
|
||||||
|
|
||||||
_locked = false;
|
|
||||||
_pvt->_mutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
//DBG(LOCK, DP(_pvt, "r"));
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedAllocLock::ScopedAllocLock()
|
|
||||||
: ScopedLockBasic(false)
|
|
||||||
{
|
|
||||||
//DBG(LOCK, DP(_pvt, "c"));
|
|
||||||
|
|
||||||
switch(Globals::khomp_alloc_mutex.lock())
|
|
||||||
{
|
|
||||||
case SimpleLock::FAILURE:
|
|
||||||
throw ScopedLockFailed(ScopedLockFailed::ALLOC_FAILED, "Failure");
|
|
||||||
break;
|
|
||||||
case SimpleLock::ISINUSE:
|
|
||||||
throw ScopedLockFailed(ScopedLockFailed::ALLOC_FAILED, "In use");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_locked = true;
|
|
||||||
|
|
||||||
//DBG(LOCK, DP(_pvt, "r"));
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedAllocLock::~ScopedAllocLock()
|
|
||||||
{
|
|
||||||
//DBG(LOCK, DP(_pvt, "c"));
|
|
||||||
unlock();
|
|
||||||
//DBG(LOCK, DP(_pvt, "r"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScopedAllocLock::unlock()
|
|
||||||
{
|
|
||||||
//DBG(LOCK, DP(_pvt, "c"));
|
|
||||||
|
|
||||||
if (_locked)
|
|
||||||
{
|
|
||||||
//DBG(LOCK, DP(_pvt, "unlocking!"));
|
|
||||||
|
|
||||||
_locked = false;
|
|
||||||
Globals::khomp_alloc_mutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
//DBG(LOCK, DP(_pvt, "r"));
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,437 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#include "logger.h"
|
|
||||||
#include "globals.h"
|
|
||||||
|
|
||||||
namespace K
|
|
||||||
{
|
|
||||||
LogManager Logger::Logg;
|
|
||||||
LogInternalManager Logger::Logg2;
|
|
||||||
|
|
||||||
std::string Logger::base_path;
|
|
||||||
std::ofstream Logger::generic_file;
|
|
||||||
|
|
||||||
bool LogConfig::set(Logfile & file, const char * section, const char * option, bool value)
|
|
||||||
{
|
|
||||||
Section * sec = file.root().section_find(section);
|
|
||||||
|
|
||||||
if (!sec)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Option * opt = sec->option_find(option);
|
|
||||||
|
|
||||||
if (!opt)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
opt->set( value ? "Ativado" : "Desativado" );
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LogConfig::commit(Logfile & file)
|
|
||||||
{
|
|
||||||
return file.provide();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Logger::start()
|
|
||||||
{
|
|
||||||
/* we love shortcuts! */
|
|
||||||
typedef LogManager::Option LogOpt;
|
|
||||||
|
|
||||||
typedef LogOpt::Flags Flags;
|
|
||||||
typedef LogOpt::InitFlags FL;
|
|
||||||
|
|
||||||
/* configures default log levels */
|
|
||||||
Logger::Logg.classe(C_ERROR)
|
|
||||||
& LogOpt(O_CONSOLE, "ERROR: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::ENABLED)))
|
|
||||||
& LogOpt(O_GENERIC, "E: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::THREADID) & FL(LogOpt::ENABLED)));
|
|
||||||
|
|
||||||
Logger::Logg.classe(C_WARNING)
|
|
||||||
& LogOpt(O_CONSOLE, "WARNING: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::ENABLED)))
|
|
||||||
& LogOpt(O_GENERIC, "W: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::THREADID) & FL(LogOpt::ENABLED)));
|
|
||||||
|
|
||||||
Logger::Logg.classe(C_MESSAGE)
|
|
||||||
& LogOpt(O_CONSOLE, Flags(FL(LogOpt::ENABLED)))
|
|
||||||
& LogOpt(O_GENERIC, "M: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::THREADID) & FL(LogOpt::ENABLED)));
|
|
||||||
|
|
||||||
/* k3l messages */
|
|
||||||
Logger::Logg.classe(C_COMMAND)
|
|
||||||
& LogOpt(O_CONSOLE, Flags(FL(LogOpt::DATETIME)))
|
|
||||||
& LogOpt(O_GENERIC, "c: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::THREADID)));
|
|
||||||
|
|
||||||
Logger::Logg.classe(C_EVENT)
|
|
||||||
& LogOpt(O_CONSOLE, Flags(FL(LogOpt::DATETIME)))
|
|
||||||
& LogOpt(O_GENERIC, "e: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::THREADID)));
|
|
||||||
|
|
||||||
Logger::Logg.classe(C_AUDIO_EV)
|
|
||||||
& LogOpt(O_CONSOLE, Flags(FL(LogOpt::DATETIME)))
|
|
||||||
& LogOpt(O_GENERIC, "a: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::THREADID)));
|
|
||||||
|
|
||||||
Logger::Logg.classe(C_MODEM_EV)
|
|
||||||
& LogOpt(O_CONSOLE, Flags(FL(LogOpt::DATETIME)))
|
|
||||||
& LogOpt(O_GENERIC, "m: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::THREADID) & FL(LogOpt::ENABLED)));
|
|
||||||
|
|
||||||
Logger::Logg.classe(C_LINK_STT)
|
|
||||||
& LogOpt(O_CONSOLE, Flags(FL(LogOpt::DATETIME) & FL(LogOpt::ENABLED)))
|
|
||||||
& LogOpt(O_GENERIC, "s: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::THREADID) & FL(LogOpt::ENABLED)));
|
|
||||||
|
|
||||||
Logger::Logg.classe(C_CAS_MSGS)
|
|
||||||
& LogOpt(O_CONSOLE, Flags(FL(LogOpt::DATETIME) & FL(LogOpt::ENABLED)))
|
|
||||||
& LogOpt(O_GENERIC, "p: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::THREADID) & FL(LogOpt::ENABLED)));
|
|
||||||
|
|
||||||
/* channel debug */
|
|
||||||
Logger::Logg.classe(C_DBG_FUNC)
|
|
||||||
& LogOpt(O_GENERIC, "F: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::THREADID) & FL(LogOpt::ENABLED)));
|
|
||||||
|
|
||||||
Logger::Logg.classe(C_DBG_LOCK)
|
|
||||||
& LogOpt(O_GENERIC, "L: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::THREADID) & FL(LogOpt::ENABLED)));
|
|
||||||
|
|
||||||
Logger::Logg.classe(C_DBG_THRD)
|
|
||||||
& LogOpt(O_GENERIC, "T: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::THREADID) & FL(LogOpt::ENABLED)));
|
|
||||||
|
|
||||||
Logger::Logg.classe(C_DBG_STRM)
|
|
||||||
& LogOpt(O_GENERIC, "S: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::THREADID) & FL(LogOpt::ENABLED)));
|
|
||||||
|
|
||||||
Logger::Logg.classe(C_DBG_CONF)
|
|
||||||
& LogOpt(O_GENERIC, "C: ", Flags(FL(LogOpt::DATETIME) & FL(LogOpt::THREADID) & FL(LogOpt::ENABLED)));
|
|
||||||
|
|
||||||
Logger::Logg.classe(C_DBG_FUNC).enabled(false);
|
|
||||||
Logger::Logg.classe(C_DBG_LOCK).enabled(false);
|
|
||||||
Logger::Logg.classe(C_DBG_THRD).enabled(false);
|
|
||||||
Logger::Logg.classe(C_DBG_STRM).enabled(false);
|
|
||||||
|
|
||||||
/* we debug config file loading, by default */
|
|
||||||
Logger::Logg.classe(C_DBG_CONF).enabled(true);
|
|
||||||
|
|
||||||
/* adds a prefix to the cli messages */
|
|
||||||
Logger::Logg.classe(C_CLI).prefix("<K> ");
|
|
||||||
|
|
||||||
/* inserts default console log before opening files */
|
|
||||||
Logger::Logg.add(O_CONSOLE,SwitchConsoleLog(), "mod_khomp: ");
|
|
||||||
|
|
||||||
time_t tv;
|
|
||||||
struct tm lt;
|
|
||||||
|
|
||||||
/* get local time! */
|
|
||||||
time (&tv);
|
|
||||||
localtime_r (&tv, <);
|
|
||||||
|
|
||||||
base_path = STG(FMT("/var/log/khomp%d.%d/mod_khomp-%04d%02d%02d_%02d%02d%02d/")
|
|
||||||
% k3lApiMajorVersion % k3lApiMinorVersion % (lt.tm_year + 1900) % (lt.tm_mon + 1)
|
|
||||||
% lt.tm_mday % lt.tm_hour % lt.tm_min % lt.tm_sec );
|
|
||||||
|
|
||||||
// NOTE: ALWAYS unlink, as we may have a dangling symlink lying around...
|
|
||||||
std::string link_path = STG(FMT("/var/log/khomp%d.%d/current") % k3lApiMajorVersion % k3lApiMinorVersion );
|
|
||||||
unlink(link_path.c_str());
|
|
||||||
|
|
||||||
if (mkdir(base_path.c_str(), 493 /*755*/) < 0 && errno != EEXIST)
|
|
||||||
{
|
|
||||||
Logger::Logg(C_ERROR, D("unable to create log directory '%s': %s!") % base_path % strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (symlink(base_path.c_str(), link_path.c_str()))
|
|
||||||
{
|
|
||||||
Logger::Logg(C_ERROR, D("unable to create symlink to latest log directory '%s': %s!") % base_path % strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string gen_tmp = base_path + std::string("generic.log");
|
|
||||||
generic_file.open(gen_tmp.c_str());
|
|
||||||
|
|
||||||
if (!generic_file.good())
|
|
||||||
{
|
|
||||||
Logger::Logg(C_ERROR, D("could not open file '%s': %s") % gen_tmp % strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* inserts other file descriptors (TODO: delete this when stopping logs) */
|
|
||||||
Logger::Logg.add(O_GENERIC, &generic_file);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::stop()
|
|
||||||
{
|
|
||||||
if(generic_file.is_open())
|
|
||||||
{
|
|
||||||
generic_file.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Logger::rotate()
|
|
||||||
{
|
|
||||||
std::string new_gen;
|
|
||||||
|
|
||||||
for (unsigned int i = 0;; i++)
|
|
||||||
{
|
|
||||||
std::string tmp = base_path + STG(FMT("generic.%d.log") % i);
|
|
||||||
|
|
||||||
if (access(tmp.c_str(), R_OK|W_OK) != 0 && errno == ENOENT)
|
|
||||||
{
|
|
||||||
new_gen = tmp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string old_gen = base_path + "generic.log";
|
|
||||||
|
|
||||||
if (rename(old_gen.c_str(), new_gen.c_str()) != 0)
|
|
||||||
{
|
|
||||||
Logger::Logg(C_ERROR, FMT("unable to move generic log file: %s.") % strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Globals::logs_being_rotated = true;
|
|
||||||
|
|
||||||
generic_file.close();
|
|
||||||
generic_file.open(old_gen.c_str());
|
|
||||||
|
|
||||||
Globals::logs_being_rotated = false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::processLogConsole(switch_stream_handle_t *s, const std::string options, bool invert, bool unique)
|
|
||||||
{
|
|
||||||
class_type classe = ( !s ? C_MESSAGE : C_CLI );
|
|
||||||
|
|
||||||
Strings::vector_type tokens;
|
|
||||||
Strings::tokenize(options, tokens, ",");
|
|
||||||
|
|
||||||
bool flag_errors = false;
|
|
||||||
bool flag_warnings = false;
|
|
||||||
bool flag_messages = false;
|
|
||||||
bool flag_events = false;
|
|
||||||
bool flag_commands = false;
|
|
||||||
bool flag_audio = false;
|
|
||||||
bool flag_modem = false;
|
|
||||||
bool flag_link = false;
|
|
||||||
bool flag_cas = false;
|
|
||||||
|
|
||||||
Strings::Merger strs;
|
|
||||||
|
|
||||||
for (Strings::vector_type::iterator i = tokens.begin(); i != tokens.end(); i++)
|
|
||||||
{
|
|
||||||
std::string tok = Strings::trim(*i);
|
|
||||||
|
|
||||||
/**/ if ((tok) == "errors") flag_errors = true;
|
|
||||||
else if ((tok) == "warnings") flag_warnings = true;
|
|
||||||
else if ((tok) == "messages") flag_messages = true;
|
|
||||||
else if ((tok) == "events") flag_events = true;
|
|
||||||
else if ((tok) == "commands") flag_commands = true;
|
|
||||||
else if ((tok) == "audio") flag_audio = true;
|
|
||||||
else if ((tok) == "modem") flag_modem = true;
|
|
||||||
else if ((tok) == "link") flag_link = true;
|
|
||||||
else if ((tok) == "cas") flag_cas = true;
|
|
||||||
else if ((tok) == "standard")
|
|
||||||
{
|
|
||||||
flag_errors = true;
|
|
||||||
flag_warnings = true;
|
|
||||||
flag_messages = true;
|
|
||||||
flag_link = true;
|
|
||||||
}
|
|
||||||
else if ((tok) == "all")
|
|
||||||
{
|
|
||||||
flag_errors = true;
|
|
||||||
flag_warnings = true;
|
|
||||||
flag_messages = true;
|
|
||||||
flag_events = true;
|
|
||||||
flag_commands = true;
|
|
||||||
flag_audio = true;
|
|
||||||
flag_modem = true;
|
|
||||||
flag_link = true;
|
|
||||||
flag_cas = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
K::Logger::Logg2(classe, s, FMT("WARNING: The following console message option is not valid and will be ignored: %s.") % (tok) );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
strs.add(tok);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((unique && !flag_errors) || flag_errors) K::Logger::Logg.classe(C_ERROR) .set(O_CONSOLE, LogManager::Option::ENABLED, (!invert && flag_errors));
|
|
||||||
if ((unique && !flag_warnings) || flag_warnings) K::Logger::Logg.classe(C_WARNING) .set(O_CONSOLE, LogManager::Option::ENABLED, (!invert && flag_warnings));
|
|
||||||
if ((unique && !flag_messages) || flag_messages) K::Logger::Logg.classe(C_MESSAGE) .set(O_CONSOLE, LogManager::Option::ENABLED, (!invert && flag_messages));
|
|
||||||
if ((unique && !flag_events) || flag_events) K::Logger::Logg.classe(C_EVENT) .set(O_CONSOLE, LogManager::Option::ENABLED, (!invert && flag_events));
|
|
||||||
if ((unique && !flag_commands) || flag_commands) K::Logger::Logg.classe(C_COMMAND) .set(O_CONSOLE, LogManager::Option::ENABLED, (!invert && flag_commands));
|
|
||||||
if ((unique && !flag_audio) || flag_audio) K::Logger::Logg.classe(C_AUDIO_EV).set(O_CONSOLE, LogManager::Option::ENABLED, (!invert && flag_audio));
|
|
||||||
if ((unique && !flag_modem) || flag_modem) K::Logger::Logg.classe(C_MODEM_EV).set(O_CONSOLE, LogManager::Option::ENABLED, (!invert && flag_modem));
|
|
||||||
if ((unique && !flag_link) || flag_link) K::Logger::Logg.classe(C_LINK_STT).set(O_CONSOLE, LogManager::Option::ENABLED, (!invert && flag_link));
|
|
||||||
if ((unique && !flag_cas) || flag_cas) K::Logger::Logg.classe(C_CAS_MSGS).set(O_CONSOLE, LogManager::Option::ENABLED, (!invert && flag_cas));
|
|
||||||
|
|
||||||
if (!strs.empty())
|
|
||||||
{
|
|
||||||
K::Logger::Logg2(classe, s, FMT("NOTICE: %s %sthe following console messages: %s.")
|
|
||||||
% (invert ? "Disabling" : "Enabling")
|
|
||||||
% (unique ? "just " : "") % strs.merge(", "));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
K::Logger::Logg2(classe, s, "WARNING: No valid console messages have been specified, doing nothing.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::processLogDisk(switch_stream_handle_t *s, const std::string options, bool invert, bool unique)
|
|
||||||
{
|
|
||||||
class_type classe = ( !s ? C_MESSAGE : C_CLI );
|
|
||||||
|
|
||||||
Strings::vector_type tokens;
|
|
||||||
Strings::tokenize(options, tokens, ",");
|
|
||||||
|
|
||||||
bool flag_errors = false;
|
|
||||||
bool flag_warnings = false;
|
|
||||||
bool flag_messages = false;
|
|
||||||
bool flag_events = false;
|
|
||||||
bool flag_commands = false;
|
|
||||||
bool flag_audio = false;
|
|
||||||
bool flag_modem = false;
|
|
||||||
bool flag_link = false;
|
|
||||||
bool flag_cas = false;
|
|
||||||
bool flag_functions = false;
|
|
||||||
bool flag_threads = false;
|
|
||||||
bool flag_locks = false;
|
|
||||||
bool flag_streams = false;
|
|
||||||
|
|
||||||
Strings::Merger strs;
|
|
||||||
|
|
||||||
for (Strings::vector_type::iterator i = tokens.begin(); i != tokens.end(); i++)
|
|
||||||
{
|
|
||||||
std::string tok = Strings::trim(*i);
|
|
||||||
|
|
||||||
/**/ if ((tok) == "errors") flag_errors = true;
|
|
||||||
else if ((tok) == "warnings") flag_warnings = true;
|
|
||||||
else if ((tok) == "messages") flag_messages = true;
|
|
||||||
else if ((tok) == "events") flag_events = true;
|
|
||||||
else if ((tok) == "commands") flag_commands = true;
|
|
||||||
else if ((tok) == "audio") flag_audio = true;
|
|
||||||
else if ((tok) == "modem") flag_modem = true;
|
|
||||||
else if ((tok) == "link") flag_link = true;
|
|
||||||
else if ((tok) == "cas") flag_cas = true;
|
|
||||||
else if ((tok) == "functions") flag_functions = true;
|
|
||||||
else if ((tok) == "threads") flag_threads = true;
|
|
||||||
else if ((tok) == "locks") flag_locks = true;
|
|
||||||
else if ((tok) == "streams") flag_streams = true;
|
|
||||||
else if ((tok) == "standard")
|
|
||||||
{
|
|
||||||
flag_errors = true;
|
|
||||||
flag_warnings = true;
|
|
||||||
flag_messages = true;
|
|
||||||
flag_link = true;
|
|
||||||
}
|
|
||||||
else if ((tok) == "debugging")
|
|
||||||
{
|
|
||||||
flag_errors = true;
|
|
||||||
flag_warnings = true;
|
|
||||||
flag_messages = true;
|
|
||||||
flag_commands = true;
|
|
||||||
flag_events = true;
|
|
||||||
flag_audio = true;
|
|
||||||
flag_modem = true;
|
|
||||||
flag_link = true;
|
|
||||||
flag_cas = true;
|
|
||||||
flag_functions = true;
|
|
||||||
}
|
|
||||||
else if ((tok) == "all")
|
|
||||||
{
|
|
||||||
flag_errors = true;
|
|
||||||
flag_warnings = true;
|
|
||||||
flag_messages = true;
|
|
||||||
flag_events = true;
|
|
||||||
flag_commands = true;
|
|
||||||
flag_audio = true;
|
|
||||||
flag_modem = true;
|
|
||||||
flag_link = true;
|
|
||||||
flag_cas = true;
|
|
||||||
flag_functions = true;
|
|
||||||
flag_threads = true;
|
|
||||||
flag_locks = true;
|
|
||||||
flag_streams = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* do not show! */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
strs.add(tok);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((unique && !flag_errors) || flag_errors) K::Logger::Logg.classe(C_ERROR) .set(O_GENERIC, LogManager::Option::ENABLED, (!invert && flag_errors));
|
|
||||||
if ((unique && !flag_warnings) || flag_warnings) K::Logger::Logg.classe(C_WARNING) .set(O_GENERIC, LogManager::Option::ENABLED, (!invert && flag_warnings));
|
|
||||||
if ((unique && !flag_messages) || flag_messages) K::Logger::Logg.classe(C_MESSAGE) .set(O_GENERIC, LogManager::Option::ENABLED, (!invert && flag_messages));
|
|
||||||
if ((unique && !flag_events) || flag_events) K::Logger::Logg.classe(C_EVENT) .set(O_GENERIC, LogManager::Option::ENABLED, (!invert && flag_events));
|
|
||||||
if ((unique && !flag_commands) || flag_commands) K::Logger::Logg.classe(C_COMMAND) .set(O_GENERIC, LogManager::Option::ENABLED, (!invert && flag_commands));
|
|
||||||
if ((unique && !flag_audio) || flag_audio) K::Logger::Logg.classe(C_AUDIO_EV).set(O_GENERIC, LogManager::Option::ENABLED, (!invert && flag_audio));
|
|
||||||
if ((unique && !flag_modem) || flag_modem) K::Logger::Logg.classe(C_MODEM_EV).set(O_GENERIC, LogManager::Option::ENABLED, (!invert && flag_modem));
|
|
||||||
if ((unique && !flag_link) || flag_link) K::Logger::Logg.classe(C_LINK_STT).set(O_GENERIC, LogManager::Option::ENABLED, (!invert && flag_link));
|
|
||||||
if ((unique && !flag_cas) || flag_cas) K::Logger::Logg.classe(C_CAS_MSGS).set(O_GENERIC, LogManager::Option::ENABLED, (!invert && flag_cas));
|
|
||||||
if ((unique && !flag_functions) || flag_functions) K::Logger::Logg.classe(C_DBG_FUNC).enabled(!invert && flag_functions);
|
|
||||||
if ((unique && !flag_threads) || flag_threads) K::Logger::Logg.classe(C_DBG_THRD).enabled(!invert && flag_threads);
|
|
||||||
if ((unique && !flag_locks) || flag_locks) K::Logger::Logg.classe(C_DBG_LOCK).enabled(!invert && flag_locks);
|
|
||||||
if ((unique && !flag_streams) || flag_streams) K::Logger::Logg.classe(C_DBG_STRM).enabled(!invert && flag_streams);
|
|
||||||
|
|
||||||
if (!strs.empty())
|
|
||||||
{
|
|
||||||
K::Logger::Logg2(classe, s, FMT("NOTICE: %s %sthe logging of the following messages: %s.")
|
|
||||||
% (invert ? "Disabling" : "Enabling")
|
|
||||||
% (unique ? "just " : "") % strs.merge(", "));
|
|
||||||
|
|
||||||
if ((flag_streams || flag_locks) && !invert)
|
|
||||||
{
|
|
||||||
K::Logger::Logg2(classe, s, "WARNING: You have enabled *INTENSIVE* debug messages for the Khomp channel!");
|
|
||||||
K::Logger::Logg2(classe, s, "WARNING: Don't *EVER* use these options on production systems, unless you *REALLY* know what you are doing!");
|
|
||||||
}
|
|
||||||
else if ((flag_functions || flag_threads) && !invert)
|
|
||||||
{
|
|
||||||
K::Logger::Logg2(classe, s, "WARNING: You have enabled some debug messages for the Khomp channel.");
|
|
||||||
K::Logger::Logg2(classe, s, "WARNING: Do not use these options on production systems unless you really know what you are doing!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
K::Logger::Logg2(classe, s, "WARNING: No valid log messages have been specified, doing nothing.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,694 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
KHOMP generic endpoint/channel library.
|
|
||||||
Copyright (C) 2007-2010 Khomp Ind. & Com.
|
|
||||||
|
|
||||||
The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
||||||
the specific language governing rights and limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of the
|
|
||||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
|
||||||
case the provisions of "LGPL License" are applicable instead of those above.
|
|
||||||
|
|
||||||
If you wish to allow use of your version of this file only under the terms of
|
|
||||||
the LGPL License and not to allow others to use your version of this file
|
|
||||||
under the MPL, indicate your decision by deleting the provisions above and
|
|
||||||
replace them with the notice and other provisions required by the LGPL
|
|
||||||
License. If you do not delete the provisions above, a recipient may use your
|
|
||||||
version of this file under either the MPL or the LGPL License.
|
|
||||||
|
|
||||||
The LGPL header follows below:
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this library; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#include "opt.h"
|
|
||||||
#include "globals.h"
|
|
||||||
#include "defs.h"
|
|
||||||
#include "logger.h"
|
|
||||||
#include "spec.h"
|
|
||||||
|
|
||||||
#include <function.hpp>
|
|
||||||
|
|
||||||
Options Opt::_options;
|
|
||||||
CadencesMapType Opt::_cadences;
|
|
||||||
GroupToDestMapType Opt::_groups;
|
|
||||||
OrigToDestMapType Opt::_fxs_hotline;
|
|
||||||
BoardToOrigMapType Opt::_fxs_orig_base;
|
|
||||||
BranchToOptMapType Opt::_branch_options;
|
|
||||||
BranchToObjectMapType Opt::_fxs_branch_map;
|
|
||||||
|
|
||||||
/* not beautiful, should think of something! */
|
|
||||||
#define FUNCTION_VALUE(x) reinterpret_cast< Config::FunctionValue Options::* >( x )
|
|
||||||
|
|
||||||
void Opt::initialize(void)
|
|
||||||
{
|
|
||||||
Globals::options.add(Config::Option("debug", &Options::_debug, false));
|
|
||||||
Globals::options.add(Config::Option("dialplan", &Options::_dialplan, "XML"));
|
|
||||||
Globals::options.add(Config::Option("context", &Options::_context, "default"));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("echo-canceller", &Options::_echo_canceller, true));
|
|
||||||
Globals::options.add(Config::Option("auto-gain-control", &Options::_auto_gain_control, true));
|
|
||||||
Globals::options.add(Config::Option("out-of-band-dtmfs", &Options::_out_of_band_dtmfs, true));
|
|
||||||
Globals::options.add(Config::Option("suppression-delay", &Options::_suppression_delay, true));
|
|
||||||
Globals::options.add(Config::Option("pulse-forwarding", &Options::_pulse_forwarding, false));
|
|
||||||
Globals::options.add(Config::Option("native-bridge", &Options::_native_bridge, true));
|
|
||||||
Globals::options.add(Config::Option("recording", &Options::_recording, true));
|
|
||||||
Globals::options.add(Config::Option("has-ctbus", &Options::_has_ctbus, false));
|
|
||||||
Globals::options.add(Config::Option("fxs-bina", &Options::_fxs_bina, true));
|
|
||||||
Globals::options.add(Config::Option("fxs-sharp-dial", &Options::_fxs_sharp_dial, true));
|
|
||||||
Globals::options.add(Config::Option("drop-collect-call", &Options::_drop_collect_call, false));
|
|
||||||
Globals::options.add(Config::Option("ignore-letter-dtmfs", &Options::_ignore_letter_dtmfs, true));
|
|
||||||
Globals::options.add(Config::Option("optimize-audio-path", &Options::_optimize_audio_path, false));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("fxo-send-pre-audio", &Options::_fxo_send_pre_audio, true));
|
|
||||||
Globals::options.add(Config::Option("fxo-busy-disconnection", &Options::_fxo_busy_disconnection, 1250u, 50u, 90000u));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("auto-fax-adjustment", &Options::_auto_fax_adjustment, true));
|
|
||||||
Globals::options.add(Config::Option("fax-adjustment-timeout", &Options::_fax_adjustment_timeout, 30u, 3u, 9999u));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("r2-strict-behaviour", &Options::_r2_strict_behaviour, false));
|
|
||||||
Globals::options.add(Config::Option("r2-preconnect-wait", &Options::_r2_preconnect_wait, 250u, 25u, 500u));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("fxs-digit-timeout", &Options::_fxs_digit_timeout, 7u, 1u, 30u));
|
|
||||||
Globals::options.add(Config::Option("transferdigittimeout", &Options::_transferdigittimeout, 3000u, 0u, 90000u));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("atxfer", &Options::_atxfer, ""));
|
|
||||||
Globals::options.add(Config::Option("blindxfer", &Options::_blindxfer, ""));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("flash-to-digits", &Options::_flash, "*1"));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("delay-ringback-co", &Options::_ringback_co_delay, 1500u, 0u, 999000u));
|
|
||||||
Globals::options.add(Config::Option("delay-ringback-pbx", &Options::_ringback_pbx_delay, 2500u, 0u, 999000u));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("disconnect-delay", &Options::_disconnect_delay, 0u, 0u, 100000u));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("input-volume", &Options::_input_volume, 0, -10, 10));
|
|
||||||
Globals::options.add(Config::Option("output-volume", &Options::_output_volume, 0, -10, 10));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("fxs-co-dialtone",
|
|
||||||
FUNCTION_VALUE(&Options::_fxs_co_dialtone), ""));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("log-to-disk",
|
|
||||||
FUNCTION_VALUE(&Options::_log_disk_option), "standard", false));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("callgroup", &Options::_callgroup, "0"));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("pickupgroup", &Options::_pickupgroup, "0"));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("log-to-console",
|
|
||||||
FUNCTION_VALUE(&Options::_log_console_option), "standard", false));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("trace",
|
|
||||||
FUNCTION_VALUE(&Options::_log_trace_option), "", false));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("record-prefix",
|
|
||||||
FUNCTION_VALUE(&Options::_record_prefix), "/var/spool/freeswitch/monitor/"));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("fxs-global-orig", &Options::_fxs_global_orig_base, "0"));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("language", &Options::_global_language, ""));
|
|
||||||
Globals::options.add(Config::Option("mohclass", &Options::_global_mohclass, ""));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("context-fxo", &Options::_context_fxo, "khomp-DD-CC"));
|
|
||||||
Globals::options.add(Config::Option("context-fxo-alt", &Options::_context2_fxo, "khomp-DD"));
|
|
||||||
Globals::options.add(Config::Option("context-fxs", &Options::_context_fxs, "khomp-DD-CC"));
|
|
||||||
Globals::options.add(Config::Option("context-fxs-alt", &Options::_context2_fxs, "khomp-DD"));
|
|
||||||
Globals::options.add(Config::Option("context-gsm-call", &Options::_context_gsm_call, "khomp-DD-CC"));
|
|
||||||
Globals::options.add(Config::Option("context-gsm-call-alt", &Options::_context2_gsm_call, "khomp-DD"));
|
|
||||||
Globals::options.add(Config::Option("context-gsm-sms", &Options::_context_gsm_sms, "khomp-sms-DD-CC"));
|
|
||||||
Globals::options.add(Config::Option("context-digital", &Options::_context_digital, "khomp-DD-LL"));
|
|
||||||
Globals::options.add(Config::Option("context-pr", &Options::_context_pr, "khomp-DD-CC"));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("accountcode", &Options::_accountcode, ""));
|
|
||||||
|
|
||||||
Config::StringSet activation_strings;
|
|
||||||
activation_strings.insert("auto");
|
|
||||||
activation_strings.insert("manual");
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("kommuter-activation", &Options::_kommuter_activation , "auto", activation_strings));
|
|
||||||
Globals::options.add(Config::Option("kommuter-timeout", &Options::_kommuter_timeout ,(unsigned int) 10 , (unsigned int) 0 , (unsigned int) 255));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("audio-packet-length", &Options::_audio_packet_size,
|
|
||||||
(unsigned int)KHOMP_READ_PACKET_SIZE, (unsigned int)KHOMP_MIN_READ_PACKET_SIZE, (unsigned int)KHOMP_MAX_READ_PACKET_SIZE, 8u));
|
|
||||||
|
|
||||||
Globals::options.add(Config::Option("user-transfer-digits", &Options::_user_xfer_digits, ""));
|
|
||||||
|
|
||||||
/* aliases */
|
|
||||||
Globals::options.synonym("context-gsm", "context-gsm-call");
|
|
||||||
Globals::options.synonym("context-gsm-alt", "context-gsm-call-alt");
|
|
||||||
Globals::options.synonym("echocanceller", "echo-canceller");
|
|
||||||
Globals::options.synonym("dtmfsuppression", "out-of-band-dtmfs");
|
|
||||||
Globals::options.synonym("dtmfsupression", "out-of-band-dtmfs");
|
|
||||||
Globals::options.synonym("pulsedetection", "pulse-forwarding");
|
|
||||||
Globals::options.synonym("r2preconnectwait", "r2-preconnect-wait");
|
|
||||||
Globals::options.synonym("bridge", "native-bridge");
|
|
||||||
Globals::options.synonym("suppressiondelay", "suppression-delay");
|
|
||||||
Globals::options.synonym("log", "log-to-disk");
|
|
||||||
Globals::options.synonym("volume", "output-volume");
|
|
||||||
Globals::options.synonym("disconnectdelay", "disconnect-delay");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Opt::obtain(void)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
/* everything should start clean! */
|
|
||||||
cleanConfiguration();
|
|
||||||
|
|
||||||
/* reset loaded options */
|
|
||||||
Globals::options.reset(&Opt::_options);
|
|
||||||
|
|
||||||
/* should be loaded *BEFORE* start_k3l */
|
|
||||||
loadConfiguration("khomp.conf", NULL);
|
|
||||||
|
|
||||||
/* commit, loading defaults where needed */
|
|
||||||
Config::Options::Messages msgs = Globals::options.commit(&Opt::_options);
|
|
||||||
|
|
||||||
/* config already full loaded at this point, so we can use our own log system... */
|
|
||||||
for (Config::Options::Messages::iterator i = msgs.begin(); i != msgs.end(); i++)
|
|
||||||
{
|
|
||||||
DBG(FUNC,FMT("%s") % (*i).c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::runtime_error & e)
|
|
||||||
{
|
|
||||||
LOG(ERROR, FMT("unable to obtain general options: %s: procedure aborted!") % e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Opt::commit(void)
|
|
||||||
{
|
|
||||||
processGroupString();
|
|
||||||
|
|
||||||
/* Check FXS hotlines correcteness */
|
|
||||||
OrigToDestMapType::const_iterator endOfHotlines = _fxs_hotline.end();
|
|
||||||
|
|
||||||
for (OrigToDestMapType::const_iterator i = _fxs_hotline.begin(); i != endOfHotlines; i++)
|
|
||||||
{
|
|
||||||
BranchToObjectMapType::const_iterator j = _fxs_branch_map.find(i->first);
|
|
||||||
|
|
||||||
if (j == _fxs_branch_map.end())
|
|
||||||
{
|
|
||||||
LOG(ERROR, FMT("unable to find branch '%s': hotline '%s' to '%s' is invalid!")
|
|
||||||
% i->first % i->first % i->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check FXS options correcteness */
|
|
||||||
BranchToOptMapType::const_iterator endOfOptions = _branch_options.end();
|
|
||||||
|
|
||||||
for (BranchToOptMapType::const_iterator i = _branch_options.begin(); i != endOfOptions; i++)
|
|
||||||
{
|
|
||||||
BranchToObjectMapType::const_iterator j = _fxs_branch_map.find(i->first);
|
|
||||||
if (j == _fxs_branch_map.end())
|
|
||||||
{
|
|
||||||
LOG(ERROR, FMT("unable to find branch '%s' for options '%s'")
|
|
||||||
% i->first % i->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Opt::loadConfiguration(const char *file_name, const char **section, bool show_errors)
|
|
||||||
{
|
|
||||||
switch_xml_t cfg, xml, settings;
|
|
||||||
|
|
||||||
if (!(xml = switch_xml_open_cfg(file_name, &cfg, NULL)))
|
|
||||||
{
|
|
||||||
if (show_errors)
|
|
||||||
{
|
|
||||||
LOG(ERROR,FMT("Open of %s failed") % file_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load all the global settings pertinent to all boards */
|
|
||||||
settings = processSimpleXML(cfg,"settings");
|
|
||||||
|
|
||||||
/* Process channel settings */
|
|
||||||
processSimpleXML(settings,"channels");
|
|
||||||
|
|
||||||
/* Process groups settings */
|
|
||||||
processGroupXML(settings);
|
|
||||||
|
|
||||||
/* Process cadence settings */
|
|
||||||
processCadenceXML(settings);
|
|
||||||
|
|
||||||
/* Process fxs branches settings */
|
|
||||||
processFXSBranchesXML(settings);
|
|
||||||
|
|
||||||
/* Process hotlines settings */
|
|
||||||
processFXSHotlines(settings);
|
|
||||||
|
|
||||||
/* Process fxs options settings */
|
|
||||||
processFXSOptions(settings);
|
|
||||||
|
|
||||||
switch_xml_free(xml);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Opt::cleanConfiguration(void)
|
|
||||||
{
|
|
||||||
_fxs_orig_base.clear();
|
|
||||||
_fxs_hotline.clear();
|
|
||||||
_fxs_branch_map.clear();
|
|
||||||
_branch_options.clear();
|
|
||||||
|
|
||||||
_groups.clear();
|
|
||||||
_cadences.clear();
|
|
||||||
|
|
||||||
_cadences.insert(CadencesPairType("fast-busy", CadenceType(100,100)));
|
|
||||||
_cadences.insert(CadencesPairType("ringback", CadenceType(1000,4000)));
|
|
||||||
_cadences.insert(CadencesPairType("pbx-dialtone", CadenceType(1000,100)));
|
|
||||||
_cadences.insert(CadencesPairType("co-dialtone", CadenceType(0,0)));
|
|
||||||
_cadences.insert(CadencesPairType("vm-dialtone", CadenceType(1000,100,100,100)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void Options::AmaflagOption::operator()(const Config::StringType & str)
|
|
||||||
{
|
|
||||||
//_value = Strings::tolong(str);
|
|
||||||
//if(_value < 0)
|
|
||||||
// throw Config::Failure(STG(FMT("invalid AMA flags: %s") % str));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Options::CallGroupOption::operator()(const Config::StringType & str)
|
|
||||||
{
|
|
||||||
_groups = str;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Options::PickupGroupOption::operator()(const Config::StringType & str)
|
|
||||||
{
|
|
||||||
_groups = str;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Options::RecordPrefixOption::operator()(const Config::StringType & str)
|
|
||||||
{
|
|
||||||
if (mkdir(str.c_str(), 493 /* 0755 */) < 0 && errno != EEXIST)
|
|
||||||
throw Config::Failure("the default recording directory could not be created.");
|
|
||||||
|
|
||||||
_value = str;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Options::CentralOfficeDialtone::operator()(const Config::StringType & str)
|
|
||||||
{
|
|
||||||
Strings::vector_type tokens;
|
|
||||||
Strings::tokenize(str, tokens, ",");
|
|
||||||
|
|
||||||
for (Strings::vector_type::iterator i = tokens.begin(); i != tokens.end(); i++)
|
|
||||||
_value.push_back(*i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Options::LogDiskOption::operator()(const Config::StringType & str)
|
|
||||||
{
|
|
||||||
K::Logger::processLogDisk(NULL, str, false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Options::LogConsoleOption::operator()(const Config::StringType & str)
|
|
||||||
{
|
|
||||||
K::Logger::processLogConsole(NULL, str, false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Options::LogTraceOption::operator()(const Config::StringType & str)
|
|
||||||
{
|
|
||||||
Strings::vector_type tokens;
|
|
||||||
Strings::tokenize(str, tokens, ",");
|
|
||||||
|
|
||||||
bool enable_k3l_tracing = false;
|
|
||||||
bool enable_r2_tracing = false;
|
|
||||||
bool enable_rdsi_tracing = false;
|
|
||||||
|
|
||||||
for (Strings::vector_type::iterator i = tokens.begin(); i != tokens.end(); i++)
|
|
||||||
{
|
|
||||||
std::string tok = Strings::trim(*i);
|
|
||||||
|
|
||||||
/**/ if (tok == "k3l") enable_k3l_tracing = true;
|
|
||||||
else if (tok == "r2") enable_r2_tracing = true;
|
|
||||||
else if (tok == "rdsi") enable_rdsi_tracing = true;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG(ERROR, FMT("invalid string '%s' for option 'trace', ignoring...") % tok)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Logfile logfile;
|
|
||||||
|
|
||||||
/* k3l tracing */
|
|
||||||
if (enable_k3l_tracing)
|
|
||||||
{
|
|
||||||
K::LogConfig::set(logfile, "K3L", "Value", enable_k3l_tracing);
|
|
||||||
K::LogConfig::set(logfile, "K3L", "CallProgress", enable_k3l_tracing);
|
|
||||||
K::LogConfig::set(logfile, "K3L", "CallAnalyzer", enable_k3l_tracing);
|
|
||||||
K::LogConfig::set(logfile, "K3L", "CadenceRecog", enable_k3l_tracing);
|
|
||||||
K::LogConfig::set(logfile, "K3L", "CallControl", enable_k3l_tracing);
|
|
||||||
K::LogConfig::set(logfile, "K3L", "Fax", enable_k3l_tracing);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* r2 tracing */
|
|
||||||
K::LogConfig::set(logfile, "R2", "Value", enable_r2_tracing);
|
|
||||||
K::LogConfig::set(logfile, "R2", "Signaling", enable_r2_tracing);
|
|
||||||
K::LogConfig::set(logfile, "R2", "States", enable_r2_tracing);
|
|
||||||
|
|
||||||
/* ISDN tracing */
|
|
||||||
if (enable_rdsi_tracing ^ Globals::flag_trace_rdsi)
|
|
||||||
{
|
|
||||||
K::LogConfig::set(logfile, "ISDN", "Value", enable_rdsi_tracing);
|
|
||||||
K::LogConfig::set(logfile, "ISDN", "Lapd", enable_rdsi_tracing);
|
|
||||||
K::LogConfig::set(logfile, "ISDN", "Q931", enable_rdsi_tracing);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Globals::k3lapi.command(-1, -1, CM_LOG_UPDATE);
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
LOG(ERROR,"Error while send command CM_LOG_UPDATE");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_xml_t Opt::processSimpleXML(switch_xml_t &xml, const std::string& child_name)
|
|
||||||
{
|
|
||||||
switch_xml_t param, child;
|
|
||||||
|
|
||||||
if ((child = switch_xml_child(xml, child_name.c_str())))
|
|
||||||
{
|
|
||||||
for (param = switch_xml_child(child, "param"); param; param = param->next)
|
|
||||||
{
|
|
||||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
|
||||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
DBG(FUNC,FMT("loading '%s' options: '%s'...")
|
|
||||||
% var
|
|
||||||
% val);
|
|
||||||
|
|
||||||
Globals::options.process(&Opt::_options, var, val);
|
|
||||||
}
|
|
||||||
catch (Config::Failure e)
|
|
||||||
{
|
|
||||||
LOG(ERROR,FMT("config processing error: %s. [%s=%s]")
|
|
||||||
% e.what()
|
|
||||||
% var
|
|
||||||
% val);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Opt::processGroupXML(switch_xml_t &xml)
|
|
||||||
{
|
|
||||||
switch_xml_t param, child;
|
|
||||||
|
|
||||||
if ((child = switch_xml_child(xml,"groups")))
|
|
||||||
{
|
|
||||||
for (param = switch_xml_child(child, "param"); param; param = param->next)
|
|
||||||
{
|
|
||||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
|
||||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
DBG(FUNC,FMT("loading group '%s' options: '%s'...")
|
|
||||||
% var
|
|
||||||
% val);
|
|
||||||
|
|
||||||
_groups.insert(GroupToDestPairType(var,val));
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Config::Failure e)
|
|
||||||
{
|
|
||||||
LOG(ERROR,FMT("config processing error: %s. [%s=%s]")
|
|
||||||
% e.what()
|
|
||||||
% var
|
|
||||||
% val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Opt::processCadenceXML(switch_xml_t &xml)
|
|
||||||
{
|
|
||||||
switch_xml_t param, child;
|
|
||||||
|
|
||||||
if ((child = switch_xml_child(xml,"cadences")))
|
|
||||||
{
|
|
||||||
for (param = switch_xml_child(child, "param"); param; param = param->next)
|
|
||||||
{
|
|
||||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
|
||||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
DBG(FUNC,FMT("loading cadences '%s' options: '%s'...")
|
|
||||||
% var
|
|
||||||
% val);
|
|
||||||
|
|
||||||
Strings::vector_type values;
|
|
||||||
Strings::tokenize(val, values, " :,.");
|
|
||||||
|
|
||||||
if (values.size() != 2 && values.size() != 4)
|
|
||||||
{
|
|
||||||
LOG(WARNING, FMT("file '%s': wrong number of arguments at cadence '%s'!")
|
|
||||||
% "khomp.conf.xml"
|
|
||||||
% var);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CadenceType cadence;
|
|
||||||
|
|
||||||
cadence.ring = Strings::toulong(Strings::trim(values[0]));
|
|
||||||
cadence.ring_s = Strings::toulong(Strings::trim(values[1]));
|
|
||||||
|
|
||||||
if (values.size() == 4)
|
|
||||||
{
|
|
||||||
cadence.ring_ext = Strings::toulong(Strings::trim(values[2]));
|
|
||||||
cadence.ring_ext_s = Strings::toulong(Strings::trim(values[3]));
|
|
||||||
}
|
|
||||||
|
|
||||||
_cadences.erase(var); /* erases previous (possibly predefined) cadence */
|
|
||||||
_cadences.insert(CadencesPairType(var, cadence));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Config::Failure e)
|
|
||||||
{
|
|
||||||
LOG(ERROR,FMT("config processing error: %s. [%s=%s]")
|
|
||||||
% e.what()
|
|
||||||
% var
|
|
||||||
% val);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Strings::invalid_value e)
|
|
||||||
{
|
|
||||||
LOG(ERROR,FMT("file '%s': number expected at cadence '%s', got '%s'.")
|
|
||||||
% "khomp.conf.xml"
|
|
||||||
% var
|
|
||||||
% e.value().c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Opt::processFXSBranchesXML(switch_xml_t &xml)
|
|
||||||
{
|
|
||||||
switch_xml_t param, child;
|
|
||||||
|
|
||||||
if ((child = switch_xml_child(xml,"fxs-branches")))
|
|
||||||
{
|
|
||||||
for (param = switch_xml_child(child, "param"); param; param = param->next)
|
|
||||||
{
|
|
||||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
|
||||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
|
||||||
|
|
||||||
|
|
||||||
DBG(FUNC,FMT("loading fxs-branches '%s' options: '%s'...")
|
|
||||||
% var
|
|
||||||
% val);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
unsigned long orig_number = Strings::toulong(var);
|
|
||||||
|
|
||||||
/* gcc! stop complaining! */
|
|
||||||
(void)orig_number;
|
|
||||||
|
|
||||||
Strings::vector_type boards;
|
|
||||||
Strings::tokenize(val, boards, " :,");
|
|
||||||
|
|
||||||
if (boards.size() < 1)
|
|
||||||
{
|
|
||||||
DBG(FUNC,FMT("file '%s': orig number '%s' without any board!")
|
|
||||||
% "khomp.conf.xml"
|
|
||||||
% var);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Strings::vector_type::iterator iter = boards.begin(); iter != boards.end(); iter++)
|
|
||||||
{
|
|
||||||
/* quebrar em strings por vírgula/espaço */
|
|
||||||
unsigned long serial_number = Strings::toulong(Strings::trim(*iter));
|
|
||||||
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
for (unsigned int device = 0; device < Globals::k3lapi.device_count(); device++)
|
|
||||||
{
|
|
||||||
const K3L_DEVICE_CONFIG & conf = Globals::k3lapi.device_config(device);
|
|
||||||
|
|
||||||
std::string str_serial(conf.SerialNumber);
|
|
||||||
|
|
||||||
if (Strings::toulong(str_serial) == serial_number)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
|
|
||||||
_fxs_orig_base.insert(BoardToOrigPairType(device, var));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
LOG(WARNING, FMT("file 'khomp.conf.xml': board with serial number '%u' not found!")
|
|
||||||
% serial_number);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Config::Failure e)
|
|
||||||
{
|
|
||||||
LOG(ERROR,FMT("config processing error: %s. [%s=%s]")
|
|
||||||
% e.what()
|
|
||||||
% var
|
|
||||||
% val);
|
|
||||||
}
|
|
||||||
catch (Strings::invalid_value & e)
|
|
||||||
{
|
|
||||||
LOG(ERROR, D("invalid numeric value: %s") % e.value());
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
LOG(ERROR, D("config processing error..."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Opt::processFXSHotlines(switch_xml_t &xml)
|
|
||||||
{
|
|
||||||
switch_xml_t param, child;
|
|
||||||
|
|
||||||
if ((child = switch_xml_child(xml,"fxs-hotlines")))
|
|
||||||
{
|
|
||||||
for (param = switch_xml_child(child, "param"); param; param = param->next)
|
|
||||||
{
|
|
||||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
|
||||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
DBG(FUNC,FMT("loading fxs-hotlines '%s' options: '%s'...")
|
|
||||||
% var
|
|
||||||
% val);
|
|
||||||
|
|
||||||
unsigned long orig_number = Strings::toulong(var);
|
|
||||||
|
|
||||||
(void)orig_number; /* stop complaining! */
|
|
||||||
|
|
||||||
_fxs_hotline.insert(OrigToDestPairType(var, val));
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Config::Failure e)
|
|
||||||
{
|
|
||||||
LOG(ERROR,FMT("config processing error: %s. [%s=%s]")
|
|
||||||
% e.what()
|
|
||||||
% var
|
|
||||||
% val);
|
|
||||||
}
|
|
||||||
catch (Strings::invalid_value e)
|
|
||||||
{
|
|
||||||
LOG(WARNING, FMT("file '%s': number expected, got '%s'!")
|
|
||||||
% "khomp.conf.xml" % e.value().c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Opt::processFXSOptions(switch_xml_t &xml)
|
|
||||||
{
|
|
||||||
switch_xml_t param, child;
|
|
||||||
|
|
||||||
if ((child = switch_xml_child(xml,"fxs-options")))
|
|
||||||
{
|
|
||||||
for (param = switch_xml_child(child, "param"); param; param = param->next)
|
|
||||||
{
|
|
||||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
|
||||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
DBG(FUNC,FMT("loading fxs-options '%s' options: '%s'...")
|
|
||||||
% var
|
|
||||||
% val);
|
|
||||||
|
|
||||||
Strings::vector_type branches;
|
|
||||||
Strings::tokenize(var, branches, " ,");
|
|
||||||
|
|
||||||
if (branches.size() < 1)
|
|
||||||
{
|
|
||||||
//TODO: Get linenumber
|
|
||||||
LOG(WARNING, FMT("file '%s': no branches specified in line %d!")
|
|
||||||
% "khomp.conf.xml" % 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (Strings::vector_type::iterator iter = branches.begin();
|
|
||||||
iter != branches.end(); iter++)
|
|
||||||
{
|
|
||||||
std::string tmp_branch = Strings::trim(*iter);
|
|
||||||
|
|
||||||
unsigned long branch_number = Strings::toulong(tmp_branch);
|
|
||||||
(void) branch_number;
|
|
||||||
|
|
||||||
_branch_options.insert(BranchToOptPairType(tmp_branch, val));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Config::Failure e)
|
|
||||||
{
|
|
||||||
LOG(ERROR,FMT("config processing error: %s. [%s=%s]")
|
|
||||||
% e.what()
|
|
||||||
% var
|
|
||||||
% val);
|
|
||||||
}
|
|
||||||
catch (Strings::invalid_value e)
|
|
||||||
{
|
|
||||||
LOG(WARNING, FMT("file '%s': number expected, got '%s'!")
|
|
||||||
% "khomp.conf.xml" % e.value().c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue