Merge branch 'master' of git.sangoma.com:smg_freeswitch
This commit is contained in:
commit
96e4a6b7d6
|
@ -964,9 +964,7 @@ Global
|
|||
{692F6330-4D87-4C82-81DF-40DB5892636E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{692F6330-4D87-4C82-81DF-40DB5892636E}.Release|x64.ActiveCfg = Release|x64
|
||||
{692F6330-4D87-4C82-81DF-40DB5892636E}.Release|x64 Setup.ActiveCfg = Release|x64
|
||||
{692F6330-4D87-4C82-81DF-40DB5892636E}.Release|x64 Setup.Build.0 = Release|x64
|
||||
{692F6330-4D87-4C82-81DF-40DB5892636E}.Release|x86 Setup.ActiveCfg = Release|Win32
|
||||
{692F6330-4D87-4C82-81DF-40DB5892636E}.Release|x86 Setup.Build.0 = Release|Win32
|
||||
{D3EC0AFF-76FC-4210-A825-9A17410660A3}.All|Win32.ActiveCfg = Release|x64
|
||||
{D3EC0AFF-76FC-4210-A825-9A17410660A3}.All|x64.ActiveCfg = Release|x64
|
||||
{D3EC0AFF-76FC-4210-A825-9A17410660A3}.All|x64.Build.0 = Release|x64
|
||||
|
|
|
@ -6,8 +6,13 @@ all:
|
|||
@echo " + Install by running: +"
|
||||
@echo " + +"
|
||||
@echo " + $(MK) install +"
|
||||
@echo " + +"
|
||||
@echo " + While you're waiting, register for ClueCon! +"
|
||||
@echo " + http://www.cluecon.com +"
|
||||
@echo " + +"
|
||||
@echo " +-----------------------------------------------+"
|
||||
|
||||
|
||||
install:
|
||||
@echo " +---------- FreeSWITCH install Complete ----------+"
|
||||
@echo " + FreeSWITCH has been successfully installed. +"
|
||||
|
|
|
@ -62,6 +62,7 @@ endpoints/mod_loopback
|
|||
#endpoints/mod_skinny
|
||||
#endpoints/mod_skypopen
|
||||
#endpoints/mod_h323
|
||||
#endpoints/mod_khomp
|
||||
#../../libs/openzap/mod_openzap
|
||||
#../../libs/freetdm/mod_freetdm
|
||||
#asr_tts/mod_unimrcp
|
||||
|
@ -105,5 +106,4 @@ say/mod_say_ru
|
|||
#say/mod_say_th
|
||||
|
||||
## Experimental Modules (don't cry if they're broken)
|
||||
#endpoints/mod_khomp
|
||||
#../../contrib/mod/xml_int/mod_xml_odbc
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
<!-- <load module="mod_openzap"/> -->
|
||||
<!-- <load module="mod_unicall"/> -->
|
||||
<!-- <load module="mod_skinny"/> -->
|
||||
<!-- <load module="mod_khomp"/> -->
|
||||
|
||||
<!-- Applications -->
|
||||
<load module="mod_commands"/>
|
||||
|
|
|
@ -1005,7 +1005,7 @@ int main(int argc, char *argv[])
|
|||
int temp_log = -1;
|
||||
int argv_error = 0;
|
||||
int argv_exec = 0;
|
||||
char argv_command[256] = "";
|
||||
char argv_command[1024] = "";
|
||||
char argv_loglevel[128] = "";
|
||||
int argv_quiet = 0;
|
||||
int loops = 2, reconnect = 0;
|
||||
|
|
|
@ -55,10 +55,6 @@ COMPILE = $(CC) $(FTDM_CFLAGS)
|
|||
LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(COMPILE)
|
||||
LINK = $(LIBTOOL) --mode=link --tag=CC $(CC) $(FTDM_CFLAGS) $(LDFLAGS) -o $@
|
||||
|
||||
if WANT_DEBUGDTMF
|
||||
FTDM_CFLAGS += -DFTDM_DEBUG_DTMF
|
||||
endif
|
||||
|
||||
|
||||
#
|
||||
# GNU pkgconfig file
|
||||
|
|
|
@ -45,3 +45,29 @@ fxs-channel => 1
|
|||
number => 2
|
||||
fxo-channel => 3
|
||||
|
||||
; MFC-R2 typical span configuration
|
||||
|
||||
; MFC-R2 with wanpipe (Sangoma)
|
||||
[span wanpipe myWanpipeSpan]
|
||||
trunk_type => E1
|
||||
cas-channel => 1-15:1101
|
||||
cas-channel => 17-31:1101
|
||||
|
||||
; MFC-R2 with Zaptel/DAHDI
|
||||
[span zt myWanpipeSpan]
|
||||
trunk_type => E1
|
||||
cas-channel => 1-15:1101
|
||||
cas-channel => 17-31:1101
|
||||
|
||||
; generic channel parameters
|
||||
; this parameters are accepted by any type of span/channel
|
||||
; remember that for generic channel parameters only channels
|
||||
; below the parameter within the span will be affected
|
||||
|
||||
; Channel audio gain
|
||||
; rxgain => 0.0
|
||||
; txgain => 0.0
|
||||
|
||||
; Whether to perform media dumps for DTMF debugging
|
||||
; debugdtmf => yes
|
||||
|
||||
|
|
|
@ -1,52 +1,220 @@
|
|||
<!-- Please refer to http://wiki.freeswitch.org/wiki/FreeTDM for further documentation -->
|
||||
|
||||
<!--
|
||||
This is a sample FreeSWITCH XML configuration for FreeTDM
|
||||
Remember you still need to configure freetdm.conf (no XML extension) in $prefix/conf/
|
||||
directory of FreeSWITCH. The freetdm.conf (no XML extension) is a simple text file
|
||||
definining the I/O interfaces (Sangoma, DAHDI etc). This file (freetdm.conf.xml) deals
|
||||
with the signaling protocols that you can run on top of your I/O interfaces.
|
||||
-->
|
||||
<configuration name="freetdm.conf" description="FreeTDM Configuration">
|
||||
<settings>
|
||||
<param name="debug" value="0"/>
|
||||
<!--<param name="hold-music" value="$${moh_uri}"/>-->
|
||||
<!--<param name="enable-analog-option" value="call-swap"/>-->
|
||||
<!--<param name="enable-analog-option" value="3-way"/>-->
|
||||
</settings>
|
||||
|
||||
<settings>
|
||||
<param name="debug" value="0"/>
|
||||
<!--<param name="hold-music" value="$${moh_uri}"/>-->
|
||||
<!--<param name="enable-analog-option" value="call-swap"/>-->
|
||||
<!--<param name="enable-analog-option" value="3-way"/>-->
|
||||
</settings>
|
||||
|
||||
<!-- use the <pri_spans> tag for native ISDN support (most likely broken at this point, check sangoma_pri_spans or libpri_spans for alternatives) -->
|
||||
<pri_spans>
|
||||
<span name="PRI_1">
|
||||
<!-- Log Levels: none, alert, crit, err, warning, notice, info, debug -->
|
||||
<param name="q921loglevel" value="alert"/>
|
||||
<param name="q931loglevel" value="alert"/>
|
||||
<param name="mode" value="user"/>
|
||||
<param name="dialect" value="5ess"/>
|
||||
<param name="dialplan" value="XML"/>
|
||||
<param name="context" value="default"/>
|
||||
</span>
|
||||
<span name="PRI_2">
|
||||
<param name="q921loglevel" value="alert"/>
|
||||
<param name="q931loglevel" value="alert"/>
|
||||
<param name="mode" value="user"/>
|
||||
<param name="dialect" value="5ess"/>
|
||||
<param name="dialplan" value="XML"/>
|
||||
<param name="context" value="default"/>
|
||||
</span>
|
||||
</pri_spans>
|
||||
<!-- Sample analog configuration -->
|
||||
<analog_spans>
|
||||
<!-- The span name must match the name in your freetdm.conf -->
|
||||
<span name="myAnalog">
|
||||
<!--<param name="hold-music" value="$${moh_uri}"/>-->
|
||||
<!--<param name="enable-analog-option" value="call-swap"/>-->
|
||||
<!--<param name="enable-analog-option" value="3-way"/>-->
|
||||
<param name="tonegroup" value="us"/>
|
||||
<param name="digit-timeout" value="2000"/>
|
||||
<param name="max-digits" value="11"/>
|
||||
<param name="dialplan" value="XML"/>
|
||||
<param name="context" value="default"/>
|
||||
<param name="enable-callerid" value="true"/>
|
||||
<!-- regex to stop dialing when it matches -->
|
||||
<!--<param name="dial-regex" value="5555"/>-->
|
||||
<!-- regex to stop dialing when it does not match -->
|
||||
<!--<param name="fail-dial-regex" value="^5"/>-->
|
||||
</span>
|
||||
</analog_spans>
|
||||
|
||||
<!-- openr2 (MFC-R2 signaling) spans
|
||||
MFC-R2 signaling has lots of variants from country to country and even sometimes
|
||||
minor variants inside the same country. The only mandatory parameters here are:
|
||||
variant, but typically you also want to set max_ani and max_dnis.
|
||||
IT IS RECOMMENDED that you leave the default values (leaving them commented) for the
|
||||
other parameters unless you have problems or you have been instructed to change some
|
||||
parameter. OpenR2 library uses the 'variant' parameter to try to determine the
|
||||
best defaults for your country. If you want to contribute your configs for a particular
|
||||
country send them to the e-mail of the primary OpenR2 developer that you can find in the
|
||||
AUTHORS file of the OpenR2 package, they will be added to the samples directory of openr2.
|
||||
-->
|
||||
<r2_spans>
|
||||
<span name="wp1" cfgprofile="testr2">
|
||||
|
||||
<!--
|
||||
MFC/R2 variant. This depends on the OpenR2 supported variants
|
||||
A list of values can be found by executing the openr2 command r2test -l
|
||||
some valid values are:
|
||||
mx (Mexico)
|
||||
ar (Argentina)
|
||||
br (Brazil)
|
||||
ph (Philippines)
|
||||
itu (per ITU spec)
|
||||
-->
|
||||
<param name="variant" value="mx"/>
|
||||
|
||||
<!-- Analog spans go here -->
|
||||
<analog_spans>
|
||||
<span name="myAnalog">
|
||||
<!--<param name="hold-music" value="$${moh_uri}"/>-->
|
||||
<!--<param name="enable-analog-option" value="call-swap"/>-->
|
||||
<!--<param name="enable-analog-option" value="3-way"/>-->
|
||||
<param name="tonegroup" value="us"/>
|
||||
<param name="digit-timeout" value="2000"/>
|
||||
<param name="max-digits" value="11"/>
|
||||
<param name="dialplan" value="XML"/>
|
||||
<param name="context" value="default"/>
|
||||
<param name="enable-callerid" value="true"/>
|
||||
<!-- regex to stop dialing when it matches -->
|
||||
<!--<param name="dial-regex" value="5555"/>-->
|
||||
<!-- regex to stop dialing when it does not match -->
|
||||
<!--<param name="fail-dial-regex" value="^5"/>-->
|
||||
</span>
|
||||
</analog_spans>
|
||||
<!-- switch parameters (required), where to send calls to -->
|
||||
<param name="dialplan" value="XML"/>
|
||||
<param name="context" value="default"/>
|
||||
|
||||
<!--
|
||||
Max amount of ANI (caller id digits) to ask for
|
||||
<param name="max_ani" value="4"/>
|
||||
-->
|
||||
<!--
|
||||
Max amount of DNIS to ask for
|
||||
<param name="max_dnis" value="4"/>
|
||||
-->
|
||||
|
||||
<!-- Do not set parameters below this line unless you desire to tweak it because is not working -->
|
||||
|
||||
<!--
|
||||
Whether or not to get the ANI before getting DNIS (only affects incoming calls)
|
||||
Some telcos require ANI first some others do not care, if default go wrong on
|
||||
incoming calls, change this value
|
||||
<param name="get_ani_first" value="yes"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Caller Category to send. Accepted values:
|
||||
- national_subscriber
|
||||
- national_priority_subscriber
|
||||
- international_subscriber
|
||||
- international_priority_subscriber
|
||||
- collect_call
|
||||
Usually national_subscriber (the default) works just fine
|
||||
<param name="category" value="national_subscriber"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Brazil uses a special calling party category for collect calls (llamadas por cobrar)
|
||||
instead of using the operator (as in Mexico). The R2 spec in Brazil says a special GB tone
|
||||
should be used to reject collect calls. If you want to ALLOW collect calls specify 'yes',
|
||||
if you want to BLOCK collect calls then say 'no'. Default is to block collect calls.
|
||||
(see also 'double_answer')
|
||||
<param name="allow_collect_calls" value="yes"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
This feature is related but independent of allow_collect_calls
|
||||
Some PBX's require a double-answer process to block collect calls, if
|
||||
you ever have problems blocking collect calls using Group B signals (allow_collect_calls=no)
|
||||
then you may want to try with double_answer=yes, this will cause that every answer signal
|
||||
is changed to perform 'answer -> clear back -> answer' (sort of a flash)
|
||||
(see also 'allow_collect_calls')
|
||||
<param name="double_answer" value="yes"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
This feature allows to skip the use of Group B/II signals and go directly
|
||||
to the accepted state for incoming calls
|
||||
<param name="immediate_accept" value="yes"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Skip request of calling party category and ANI
|
||||
<param name="skip_category" value="yes"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Brazil use a special signal to force the release of the line (hangup) from the
|
||||
backward perspective. When forced_release=no, the normal clear back signal
|
||||
will be sent on hangup, which is OK for all mfcr2 variants I know of, except for
|
||||
Brazilian variant, where the central will leave the line up for several seconds (30, 60)
|
||||
which sometimes is not what people really want. When forced_release=yes, a different
|
||||
signal will be sent to hangup the call indicating that the line should be released immediately
|
||||
<param name="forced_release" value="yes"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Whether or not report to the other end 'accept call with charge'
|
||||
This setting has no effect with most telecos, usually is safe
|
||||
leave the default (yes), but once in a while when interconnecting with
|
||||
old PBXs this may be useful.
|
||||
Concretely this affects the Group B signal used to accept calls
|
||||
<param name="charge_calls" value="yes"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
MFC/R2 value in milliseconds for the MF timeout. Any negative value
|
||||
means 'default', smaller values than 500ms are not recommended
|
||||
and can cause malfunctioning. If you experience protocol error
|
||||
due to MF timeout try incrementing this value in 500ms steps
|
||||
<param name="mfback_timeout" value="1500"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
MFC/R2 value in milliseconds for the metering pulse timeout.
|
||||
Metering pulses are sent by some telcos for some R2 variants
|
||||
during a call presumably for billing purposes to indicate costs,
|
||||
however this pulses use the same signal that is used to indicate
|
||||
call hangup, therefore a timeout is sometimes required to distinguish
|
||||
between a *real* hangup and a billing pulse that should not
|
||||
last more than 500ms, If you experience call drops after some
|
||||
minutes of being stablished try setting a value of some ms here,
|
||||
values greater than 500ms are not recommended.
|
||||
BE AWARE that choosing the proper protocol variant parameter
|
||||
implicitly sets a good recommended value for this timer, use this
|
||||
parameter only when you *really* want to override the default, otherwise
|
||||
just comment out this value.
|
||||
<param name="metering_pulse_timeout" value="1000"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
WARNING: advanced users only! I really mean it
|
||||
this parameter is commented by default because
|
||||
YOU DON'T NEED IT UNLESS YOU REALLY GROK MFC/R2
|
||||
READ COMMENTS on doc/r2proto.conf in openr2 package
|
||||
for more info
|
||||
<param name="advanced_protocol_file" value="/usr/local/freeswitch/conf/r2proto.conf"/>
|
||||
-->
|
||||
|
||||
<!-- USE THIS FOR DEBUGGING MFC-R2 PROTOCOL -->
|
||||
<!--
|
||||
Where to dump advanced call file protocol logs
|
||||
<param name="logdir" value="$${base_dir}/log/mfcr2"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
MFC/R2 valid logging values are: all,error,warning,debug,notice,cas,mf,nothing
|
||||
error,warning,debug and notice are self-descriptive
|
||||
'cas' is for logging ABCD CAS tx and rx
|
||||
'mf' is for logging of the Multi Frequency tones
|
||||
You can mix up values, like: loglevel=error,debug,mf to log just error, debug and
|
||||
multi frequency messages
|
||||
'all' is a special value to log all the activity
|
||||
'nothing' is a clean-up value, in case you want to not log any activity for
|
||||
a channel or group of channels
|
||||
BE AWARE that the level of output logged will ALSO depend on
|
||||
the value you have in FreeSWITCH logging configurations, if you disable output FreeSWITCH
|
||||
then it does not matter if you specify 'all' here, nothing will be logged
|
||||
so FreeSWITCH has the last word on what is going to be logged
|
||||
<param name="logging" value="debug,notice,warning,error,mf,cas"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
whether or not to drop protocol call files into 'logdir'
|
||||
<param name="call_files" value="yes"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Use only for very technical debugging
|
||||
This is the size (if 0, dumps are disabled) of MF dump files. MF dump files
|
||||
are audio files that are dumped when a protocol error occurs.
|
||||
The files are dumped in whatever you set in the logdir parameter.
|
||||
Value -1 uses a default recommended size (which stores 5 seconds of audio)
|
||||
<param name="mf_dump_size" value="-1"/>
|
||||
-->
|
||||
</span>
|
||||
</r2_spans>
|
||||
</configuration>
|
||||
|
||||
|
|
|
@ -167,17 +167,6 @@ AC_ARG_WITH([pritap],
|
|||
HAVE_PRITAP="${enable_pritap}"
|
||||
AM_CONDITIONAL([HAVE_PRITAP],[test "${enable_pritap}" = "yes"])
|
||||
|
||||
# debug dtmf?
|
||||
AC_ARG_WITH([debugdtmf],
|
||||
[AS_HELP_STRING([--with-debugdtmf], [Debug DTMF])],
|
||||
[case "${withval}" in
|
||||
no) enable_debugdtmf="no" ;;
|
||||
*) enable_debugdtmf="yes" ;;
|
||||
esac],
|
||||
[enable_debugdtmf="no"]
|
||||
)
|
||||
AM_CONDITIONAL([WANT_DEBUGDTMF], [test "${enable_debugdtmf}" = "yes"])
|
||||
|
||||
##
|
||||
# OpenR2 stack
|
||||
#
|
||||
|
|
|
@ -64,6 +64,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_sangoma_isdn", "src\f
|
|||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_r2", "src\ftmod\ftmod_r2\ftmod_r2.2008.vcproj", "{08C3EA27-A51D-47F8-B47D-B189C649CF30}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -131,7 +134,6 @@ Global
|
|||
{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|x64.ActiveCfg = Release|x64
|
||||
{D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|x64.Build.0 = Debug|x64
|
||||
{D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|Win32.ActiveCfg = Release|Win32
|
||||
|
@ -139,7 +141,6 @@ Global
|
|||
{D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|x64.ActiveCfg = Release|x64
|
||||
{D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|x64.Build.0 = Release|x64
|
||||
{2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|x64.Build.0 = Debug|x64
|
||||
{2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
|
@ -147,7 +148,6 @@ Global
|
|||
{2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|x64.ActiveCfg = Release|x64
|
||||
{2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|x64.Build.0 = Release|x64
|
||||
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|x64.Build.0 = Debug|x64
|
||||
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|Win32.ActiveCfg = Release|Win32
|
||||
|
@ -155,16 +155,13 @@ Global
|
|||
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.ActiveCfg = Release|x64
|
||||
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.Build.0 = Release|x64
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.Build.0 = Release|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|Win32
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|Win32.Build.0 = Release|Win32
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|x64.ActiveCfg = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
|
|
|
@ -120,16 +120,14 @@ Global
|
|||
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.Build.0 = Release|x64
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.Build.0 = Release|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|Win32
|
||||
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|x64
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|Win32.Build.0 = Release|Win32
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|x64.ActiveCfg = Release|Win32
|
||||
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|x64.ActiveCfg = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -1417,6 +1417,24 @@ fail:
|
|||
|
||||
}
|
||||
|
||||
static void ftdm_enable_channel_dtmf(ftdm_channel_t *fchan, switch_channel_t *channel)
|
||||
{
|
||||
if (channel) {
|
||||
const char *var;
|
||||
if ((var = switch_channel_get_variable(channel, "freetdm_disable_dtmf"))) {
|
||||
if (switch_true(var)) {
|
||||
ftdm_channel_command(fchan, FTDM_COMMAND_DISABLE_DTMF_DETECT, NULL);
|
||||
ftdm_log(FTDM_LOG_INFO, "DTMF detection disabled in channel %d:%d\n", ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan));
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* the variable is not present or has a negative value then proceed to enable DTMF ... */
|
||||
}
|
||||
if (ftdm_channel_command(fchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, NULL) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to enable DTMF detection in channel %d:%d\n", ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan));
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session_t **sp)
|
||||
{
|
||||
switch_core_session_t *session = NULL;
|
||||
|
@ -1440,6 +1458,9 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
|
|||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* I guess we always want DTMF detection */
|
||||
ftdm_enable_channel_dtmf(sigmsg->channel, NULL);
|
||||
|
||||
switch_core_session_add_stream(session, NULL);
|
||||
|
||||
tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t));
|
||||
|
@ -1633,24 +1654,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
|
|||
return FTDM_BREAK;
|
||||
}
|
||||
|
||||
static void ftdm_enable_channel_dtmf(ftdm_channel_t *fchan, switch_channel_t *channel)
|
||||
{
|
||||
if (channel) {
|
||||
const char *var;
|
||||
if ((var = switch_channel_get_variable(channel, "freetdm_disable_dtmf"))) {
|
||||
if (switch_true(var)) {
|
||||
ftdm_channel_command(fchan, FTDM_COMMAND_DISABLE_DTMF_DETECT, NULL);
|
||||
ftdm_log(FTDM_LOG_INFO, "DTMF detection disabled in channel %d:%d\n", ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan));
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* the variable is not present or has a negative value then proceed to enable DTMF ... */
|
||||
}
|
||||
if (ftdm_channel_command(fchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, NULL) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to enable DTMF detection in channel %d:%d\n", ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan));
|
||||
}
|
||||
}
|
||||
|
||||
static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
|
||||
{
|
||||
switch_core_session_t *session = NULL;
|
||||
|
@ -2059,6 +2062,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
|
|||
}
|
||||
break;
|
||||
|
||||
case FTDM_SIGEVENT_PROCEED:{} break;
|
||||
|
||||
default:
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled event %d from R2 for channel %d:%d\n",
|
||||
|
@ -2092,8 +2097,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
|||
{
|
||||
ftdm_channel_add_var(sigmsg->channel, "screening_ind", ftdm_screening2str(caller_data->screen));
|
||||
ftdm_channel_add_var(sigmsg->channel, "presentation_ind", ftdm_presentation2str(caller_data->pres));
|
||||
|
||||
ftdm_enable_channel_dtmf(sigmsg->channel, NULL);
|
||||
return ftdm_channel_from_event(sigmsg, &session);
|
||||
}
|
||||
break;
|
||||
|
@ -3234,33 +3237,10 @@ static switch_status_t load_config(void)
|
|||
|
||||
if ((spans = switch_xml_child(cfg, "r2_spans"))) {
|
||||
for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
|
||||
char *id = (char *) switch_xml_attr(myspan, "id");
|
||||
char *name = (char *) switch_xml_attr(myspan, "name");
|
||||
char *configname = (char *) switch_xml_attr(myspan, "cfgprofile");
|
||||
ftdm_status_t zstatus = FTDM_FAIL;
|
||||
|
||||
/* strings */
|
||||
const char *variant = "itu";
|
||||
const char *category = "national_subscriber";
|
||||
const char *logdir = "/usr/local/freeswitch/log/"; /* FIXME: get PREFIX variable */
|
||||
const char *logging = "notice,warning,error";
|
||||
const char *advanced_protocol_file = "";
|
||||
|
||||
/* booleans */
|
||||
int call_files = 0;
|
||||
int get_ani_first = -1;
|
||||
int immediate_accept = -1;
|
||||
int double_answer = -1;
|
||||
int skip_category = -1;
|
||||
int forced_release = -1;
|
||||
int charge_calls = -1;
|
||||
|
||||
/* integers */
|
||||
int mfback_timeout = -1;
|
||||
int metering_pulse_timeout = -1;
|
||||
int allow_collect_calls = -1;
|
||||
int max_ani = 10;
|
||||
int max_dnis = 4;
|
||||
|
||||
/* common non r2 stuff */
|
||||
const char *context = "default";
|
||||
const char *dialplan = "XML";
|
||||
|
@ -3269,53 +3249,29 @@ static switch_status_t load_config(void)
|
|||
uint32_t span_id = 0;
|
||||
ftdm_span_t *span = NULL;
|
||||
|
||||
ftdm_conf_parameter_t spanparameters[30];
|
||||
unsigned paramindex = 0;
|
||||
|
||||
if (!name) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "'name' attribute required for R2 spans!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(spanparameters, 0, sizeof(spanparameters));
|
||||
|
||||
if (configname) {
|
||||
paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters));
|
||||
if (paramindex) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id);
|
||||
}
|
||||
}
|
||||
|
||||
for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
|
||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
||||
|
||||
/* string parameters */
|
||||
if (!strcasecmp(var, "variant")) {
|
||||
variant = val;
|
||||
} else if (!strcasecmp(var, "category")) {
|
||||
category = val;
|
||||
} else if (!strcasecmp(var, "logdir")) {
|
||||
logdir = val;
|
||||
} else if (!strcasecmp(var, "logging")) {
|
||||
logging = val;
|
||||
} else if (!strcasecmp(var, "advanced_protocol_file")) {
|
||||
advanced_protocol_file = val;
|
||||
|
||||
/* booleans */
|
||||
} else if (!strcasecmp(var, "allow_collect_calls")) {
|
||||
allow_collect_calls = switch_true(val);
|
||||
} else if (!strcasecmp(var, "immediate_accept")) {
|
||||
immediate_accept = switch_true(val);
|
||||
} else if (!strcasecmp(var, "double_answer")) {
|
||||
double_answer = switch_true(val);
|
||||
} else if (!strcasecmp(var, "skip_category")) {
|
||||
skip_category = switch_true(var);
|
||||
} else if (!strcasecmp(var, "forced_release")) {
|
||||
forced_release = switch_true(val);
|
||||
} else if (!strcasecmp(var, "charge_calls")) {
|
||||
charge_calls = switch_true(val);
|
||||
} else if (!strcasecmp(var, "get_ani_first")) {
|
||||
get_ani_first = switch_true(val);
|
||||
} else if (!strcasecmp(var, "call_files")) {
|
||||
call_files = switch_true(val);
|
||||
|
||||
/* integers */
|
||||
} else if (!strcasecmp(var, "mfback_timeout")) {
|
||||
mfback_timeout = atoi(val);
|
||||
} else if (!strcasecmp(var, "metering_pulse_timeout")) {
|
||||
metering_pulse_timeout = atoi(val);
|
||||
} else if (!strcasecmp(var, "max_ani")) {
|
||||
max_ani = atoi(val);
|
||||
} else if (!strcasecmp(var, "max_dnis")) {
|
||||
max_dnis = atoi(val);
|
||||
|
||||
/* common non r2 stuff */
|
||||
} else if (!strcasecmp(var, "context")) {
|
||||
if (!strcasecmp(var, "context")) {
|
||||
context = val;
|
||||
} else if (!strcasecmp(var, "dialplan")) {
|
||||
dialplan = val;
|
||||
|
@ -3323,57 +3279,23 @@ static switch_status_t load_config(void)
|
|||
dial_regex = val;
|
||||
} else if (!strcasecmp(var, "fail-dial-regex")) {
|
||||
fail_dial_regex = val;
|
||||
} else {
|
||||
spanparameters[paramindex].var = var;
|
||||
spanparameters[paramindex].val = val;
|
||||
paramindex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!id && !name) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "span missing required param 'id'\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (name) {
|
||||
zstatus = ftdm_span_find_by_name(name, &span);
|
||||
} else {
|
||||
if (switch_is_number(id)) {
|
||||
span_id = atoi(id);
|
||||
zstatus = ftdm_span_find(span_id, &span);
|
||||
}
|
||||
|
||||
if (zstatus != FTDM_SUCCESS) {
|
||||
zstatus = ftdm_span_find_by_name(id, &span);
|
||||
}
|
||||
}
|
||||
|
||||
zstatus = ftdm_span_find_by_name(name, &span);
|
||||
if (zstatus != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM R2 Span '%s'\n", name);
|
||||
continue;
|
||||
}
|
||||
span_id = ftdm_span_get_id(span);
|
||||
|
||||
if (!span_id) {
|
||||
span_id = ftdm_span_get_id(span);
|
||||
}
|
||||
|
||||
if (ftdm_configure_span(span, "r2", on_r2_signal,
|
||||
"variant", variant,
|
||||
"max_ani", max_ani,
|
||||
"max_dnis", max_dnis,
|
||||
"category", category,
|
||||
"logdir", logdir,
|
||||
"logging", logging,
|
||||
"advanced_protocol_file", advanced_protocol_file,
|
||||
"allow_collect_calls", allow_collect_calls,
|
||||
"immediate_accept", immediate_accept,
|
||||
"double_answer", double_answer,
|
||||
"skip_category", skip_category,
|
||||
"forced_release", forced_release,
|
||||
"charge_calls", charge_calls,
|
||||
"get_ani_first", get_ani_first,
|
||||
"call_files", call_files,
|
||||
"mfback_timeout", mfback_timeout,
|
||||
"metering_pulse_timeout", metering_pulse_timeout,
|
||||
FTDM_TAG_END) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error configuring R2 FreeTDM span %d, error: %s\n",
|
||||
span_id, ftdm_span_get_last_error(span));
|
||||
if (ftdm_configure_span_signaling(span, "r2", on_r2_signal, spanparameters) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM R2 span %s, error: %s\n",
|
||||
name, ftdm_span_get_last_error(span));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -3388,10 +3310,10 @@ static switch_status_t load_config(void)
|
|||
SPAN_CONFIG[span_id].span = span;
|
||||
switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
|
||||
switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
|
||||
switch_copy_string(SPAN_CONFIG[span_id].type, "r2", sizeof(SPAN_CONFIG[span_id].type));
|
||||
switch_copy_string(SPAN_CONFIG[span_id].type, "R2", sizeof(SPAN_CONFIG[span_id].type));
|
||||
|
||||
if (ftdm_span_start(span) == FTDM_FAIL) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error starting R2 FreeTDM span %d, error: %s\n", span_id, ftdm_span_get_last_error(span));
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error starting FreeTDM R2 span %s, error: %s\n", name, ftdm_span_get_last_error(span));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="testboost\$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
BuildLogFile="$(IntDir)\BuildLog-testboost.htm"
|
||||
|
@ -97,87 +97,10 @@
|
|||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
BuildLogFile="$(IntDir)\BuildLog-testboost.htm"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../src/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\testboost\$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
BuildLogFile="$(IntDir)\BuildLog-testboost.htm"
|
||||
|
@ -253,10 +176,87 @@
|
|||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="testboost\$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
BuildLogFile="$(IntDir)\BuildLog-testboost.htm"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../src/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\testboost\$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
|
|
|
@ -97,83 +97,6 @@
|
|||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
BuildLogFile="$(IntDir)\BuildLog-testsangomaboost.htm"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../src/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
|
@ -253,6 +176,83 @@
|
|||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
BuildLogFile="$(IntDir)\BuildLog-testsangomaboost.htm"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../src/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
|
@ -285,7 +285,7 @@
|
|||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
WarnAsError="false"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
|
|
|
@ -186,7 +186,7 @@
|
|||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
|
|
|
@ -48,6 +48,10 @@
|
|||
#endif
|
||||
#include "ftdm_cpu_monitor.h"
|
||||
|
||||
#ifndef localtime_r
|
||||
struct tm *localtime_r(const time_t *clock, struct tm *result);
|
||||
#endif
|
||||
|
||||
#define FORCE_HANGUP_TIMER 3000
|
||||
#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000
|
||||
#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
|
||||
|
@ -86,6 +90,114 @@ FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void write_chan_io_dump(ftdm_io_dump_t *dump, char *dataptr, int dlen)
|
||||
{
|
||||
int windex = dump->windex;
|
||||
int avail = (int)dump->size - windex;
|
||||
|
||||
if (!dump->buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dlen > avail) {
|
||||
int diff = dlen - avail;
|
||||
|
||||
ftdm_assert(diff < dump->size, "Very small buffer or very big IO chunk!\n");
|
||||
|
||||
/* write only what we can and the rest at the beginning of the buffer */
|
||||
memcpy(&dump->buffer[windex], dataptr, avail);
|
||||
memcpy(&dump->buffer[0], &dataptr[avail], diff);
|
||||
windex = diff;
|
||||
|
||||
/*ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "wrapping around dump buffer %p up to index %d\n\n", dump, windex);*/
|
||||
dump->wrapped = 1;
|
||||
} else {
|
||||
memcpy(&dump->buffer[windex], dataptr, dlen);
|
||||
windex += dlen;
|
||||
}
|
||||
|
||||
if (windex == dump->size) {
|
||||
/*ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "wrapping around dump buffer %p\n", dump);*/
|
||||
windex = 0;
|
||||
dump->wrapped = 1;
|
||||
}
|
||||
|
||||
dump->windex = windex;
|
||||
}
|
||||
|
||||
static void dump_chan_io_to_file(ftdm_channel_t *fchan, ftdm_io_dump_t *dump, FILE *file)
|
||||
{
|
||||
/* write the saved audio buffer */
|
||||
size_t rc = 0;
|
||||
size_t towrite = dump->size - dump->windex;
|
||||
if (dump->wrapped) {
|
||||
rc = fwrite(&dump->buffer[dump->windex], 1, towrite, file);
|
||||
if (rc != towrite) {
|
||||
ftdm_log_chan(fchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite);
|
||||
}
|
||||
}
|
||||
if (dump->windex) {
|
||||
towrite = dump->windex;
|
||||
rc = fwrite(&dump->buffer[0], 1, towrite, file);
|
||||
if (rc != towrite) {
|
||||
ftdm_log_chan(fchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite);
|
||||
}
|
||||
}
|
||||
dump->windex = 0;
|
||||
dump->wrapped = 0;
|
||||
}
|
||||
|
||||
static void stop_chan_io_dump(ftdm_io_dump_t *dump)
|
||||
{
|
||||
if (!dump->buffer) {
|
||||
return;
|
||||
}
|
||||
ftdm_safe_free(dump->buffer);
|
||||
memset(dump, 0, sizeof(dump));
|
||||
}
|
||||
|
||||
static ftdm_status_t start_chan_io_dump(ftdm_channel_t *chan, ftdm_io_dump_t *dump, ftdm_size_t size)
|
||||
{
|
||||
if (dump->buffer) {
|
||||
ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "IO dump is already started\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
memset(dump, 0, sizeof(*dump));
|
||||
dump->buffer = ftdm_malloc((uint32_t)size);
|
||||
if (!dump->buffer) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
dump->size = size;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static void close_dtmf_debug_file(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
if (ftdmchan->dtmfdbg.file) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "closing debug dtmf file\n");
|
||||
fclose(ftdmchan->dtmfdbg.file);
|
||||
ftdmchan->dtmfdbg.file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static ftdm_status_t disable_dtmf_debug(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
if (!ftdmchan->dtmfdbg.enabled) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
if (!ftdmchan->rxdump.buffer) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "DTMF debug enabled but no rx dump?\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
close_dtmf_debug_file(ftdmchan);
|
||||
stop_chan_io_dump(&ftdmchan->rxdump);
|
||||
ftdmchan->dtmfdbg.enabled = 0;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint8_t enabled;
|
||||
uint8_t running;
|
||||
|
@ -314,43 +426,43 @@ static ftdm_status_t ftdm_set_caller_data(ftdm_span_t *span, ftdm_caller_data_t
|
|||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (caller_data->dnis.plan == FTDM_NPI_INVALID) {
|
||||
if (caller_data->dnis.plan >= FTDM_NPI_INVALID) {
|
||||
caller_data->dnis.plan = span->default_caller_data.dnis.plan;
|
||||
}
|
||||
|
||||
if (caller_data->dnis.type == FTDM_TON_INVALID) {
|
||||
if (caller_data->dnis.type >= FTDM_TON_INVALID) {
|
||||
caller_data->dnis.type = span->default_caller_data.dnis.type;
|
||||
}
|
||||
|
||||
if (caller_data->cid_num.plan == FTDM_NPI_INVALID) {
|
||||
if (caller_data->cid_num.plan >= FTDM_NPI_INVALID) {
|
||||
caller_data->cid_num.plan = span->default_caller_data.cid_num.plan;
|
||||
}
|
||||
|
||||
if (caller_data->cid_num.type == FTDM_TON_INVALID) {
|
||||
if (caller_data->cid_num.type >= FTDM_TON_INVALID) {
|
||||
caller_data->cid_num.type = span->default_caller_data.cid_num.type;
|
||||
}
|
||||
|
||||
if (caller_data->ani.plan == FTDM_NPI_INVALID) {
|
||||
if (caller_data->ani.plan >= FTDM_NPI_INVALID) {
|
||||
caller_data->ani.plan = span->default_caller_data.ani.plan;
|
||||
}
|
||||
|
||||
if (caller_data->ani.type == FTDM_TON_INVALID) {
|
||||
if (caller_data->ani.type >= FTDM_TON_INVALID) {
|
||||
caller_data->ani.type = span->default_caller_data.ani.type;
|
||||
}
|
||||
|
||||
if (caller_data->rdnis.plan == FTDM_NPI_INVALID) {
|
||||
if (caller_data->rdnis.plan >= FTDM_NPI_INVALID) {
|
||||
caller_data->rdnis.plan = span->default_caller_data.rdnis.plan;
|
||||
}
|
||||
|
||||
if (caller_data->rdnis.type == FTDM_NPI_INVALID) {
|
||||
if (caller_data->rdnis.type >= FTDM_NPI_INVALID) {
|
||||
caller_data->rdnis.type = span->default_caller_data.rdnis.type;
|
||||
}
|
||||
|
||||
if (caller_data->bearer_capability == FTDM_INVALID_INT_PARM) {
|
||||
if (caller_data->bearer_capability >= FTDM_INVALID_INT_PARM) {
|
||||
caller_data->bearer_capability = span->default_caller_data.bearer_capability;
|
||||
}
|
||||
|
||||
if (caller_data->bearer_layer1 == FTDM_INVALID_INT_PARM) {
|
||||
if (caller_data->bearer_layer1 >= FTDM_INVALID_INT_PARM) {
|
||||
caller_data->bearer_layer1 = span->default_caller_data.bearer_layer1;
|
||||
}
|
||||
|
||||
|
@ -448,10 +560,6 @@ static ftdm_status_t ftdm_channel_destroy(ftdm_channel_t *ftdmchan)
|
|||
ftdm_sleep(500);
|
||||
}
|
||||
|
||||
#ifdef FTDM_DEBUG_DTMF
|
||||
ftdm_mutex_destroy(&ftdmchan->dtmfdbg.mutex);
|
||||
#endif
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->pre_buffer_mutex);
|
||||
ftdm_buffer_destroy(&ftdmchan->pre_buffer);
|
||||
ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex);
|
||||
|
@ -870,9 +978,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_add_channel(ftdm_span_t *span, ftdm_socket_t
|
|||
|
||||
ftdm_mutex_create(&new_chan->mutex);
|
||||
ftdm_mutex_create(&new_chan->pre_buffer_mutex);
|
||||
#ifdef FTDM_DEBUG_DTMF
|
||||
ftdm_mutex_create(&new_chan->dtmfdbg.mutex);
|
||||
#endif
|
||||
|
||||
ftdm_buffer_create(&new_chan->digit_buffer, 128, 128, 0);
|
||||
ftdm_buffer_create(&new_chan->gen_dtmf_buffer, 128, 128, 0);
|
||||
|
@ -1004,6 +1109,51 @@ FT_DECLARE(ftdm_status_t) ftdm_span_next_event(ftdm_span_t *span, ftdm_event_t *
|
|||
return status;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_read_event(ftdm_channel_t *ftdmchan, ftdm_event_t **event)
|
||||
{
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
ftdm_sigmsg_t sigmsg;
|
||||
ftdm_span_t *span = ftdmchan->span;
|
||||
ftdm_assert_return(span->fio != NULL, FTDM_FAIL, "No I/O module attached to this span!\n");
|
||||
|
||||
if (!span->fio->channel_next_event) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "channel_next_event method not implemented in module %s!", span->fio->name);
|
||||
return FTDM_NOTIMPL;
|
||||
}
|
||||
|
||||
status = span->fio->channel_next_event(ftdmchan, event);
|
||||
if (status != FTDM_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* before returning the event to the user we do some core operations with certain OOB events */
|
||||
memset(&sigmsg, 0, sizeof(sigmsg));
|
||||
sigmsg.span_id = span->span_id;
|
||||
sigmsg.chan_id = (*event)->channel->chan_id;
|
||||
sigmsg.channel = (*event)->channel;
|
||||
switch ((*event)->enum_id) {
|
||||
case FTDM_OOB_ALARM_CLEAR:
|
||||
{
|
||||
sigmsg.event_id = FTDM_SIGEVENT_ALARM_CLEAR;
|
||||
ftdm_clear_flag_locked((*event)->channel, FTDM_CHANNEL_IN_ALARM);
|
||||
ftdm_span_send_signal(span, &sigmsg);
|
||||
}
|
||||
break;
|
||||
case FTDM_OOB_ALARM_TRAP:
|
||||
{
|
||||
sigmsg.event_id = FTDM_SIGEVENT_ALARM_TRAP;
|
||||
ftdm_set_flag_locked((*event)->channel, FTDM_CHANNEL_IN_ALARM);
|
||||
ftdm_span_send_signal(span, &sigmsg);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* NOOP */
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdmchan_fsk_write_sample(int16_t *buf, ftdm_size_t buflen, void *user_data)
|
||||
{
|
||||
ftdm_channel_t *ftdmchan = (ftdm_channel_t *) user_data;
|
||||
|
@ -2355,23 +2505,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signa
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef FTDM_DEBUG_DTMF
|
||||
static void close_dtmf_debug(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ftdm_mutex_lock(ftdmchan->dtmfdbg.mutex);
|
||||
|
||||
if (ftdmchan->dtmfdbg.file) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "closing debug dtmf file\n");
|
||||
fclose(ftdmchan->dtmfdbg.file);
|
||||
ftdmchan->dtmfdbg.file = NULL;
|
||||
}
|
||||
ftdmchan->dtmfdbg.windex = 0;
|
||||
ftdmchan->dtmfdbg.wrapped = 0;
|
||||
|
||||
ftdm_mutex_unlock(ftdmchan->dtmfdbg.mutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
|
@ -2400,9 +2533,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
|||
ftdm_buffer_destroy(&ftdmchan->pre_buffer);
|
||||
ftdmchan->pre_buffer_size = 0;
|
||||
ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex);
|
||||
#ifdef FTDM_DEBUG_DTMF
|
||||
close_dtmf_debug(ftdmchan);
|
||||
#endif
|
||||
ftdm_channel_clear_vars(ftdmchan);
|
||||
if (ftdmchan->hangup_timer) {
|
||||
ftdm_sched_cancel_timer(globals.timingsched, ftdmchan->hangup_timer);
|
||||
|
@ -2411,7 +2541,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
|||
ftdmchan->init_state = FTDM_CHANNEL_STATE_DOWN;
|
||||
ftdmchan->state = FTDM_CHANNEL_STATE_DOWN;
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "channel done %u:%u\n", ftdmchan->span_id, ftdmchan->chan_id);
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_DEBUG_DTMF, NULL);
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL);
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL);
|
||||
|
||||
if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
|
||||
ftdm_sigmsg_t sigmsg;
|
||||
|
@ -2423,6 +2555,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
|||
ftdm_span_send_signal(ftdmchan->span, &sigmsg);
|
||||
}
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n");
|
||||
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
|
@ -2431,7 +2565,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
|||
FT_DECLARE(ftdm_status_t) ftdm_channel_use(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
|
||||
assert(ftdmchan != NULL);
|
||||
ftdm_assert(ftdmchan != NULL, "Null channel\n");
|
||||
|
||||
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_INUSE);
|
||||
|
||||
|
@ -2505,8 +2639,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||
{
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
|
||||
assert(ftdmchan != NULL);
|
||||
assert(ftdmchan->fio != NULL);
|
||||
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "No channel\n");
|
||||
ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "No IO attached to channel\n");
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
|
@ -2533,7 +2667,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||
break;
|
||||
case FTDM_COMMAND_TRACE_INPUT:
|
||||
{
|
||||
char *path = (char *) obj;
|
||||
char *path = FTDM_COMMAND_OBJ_CHAR_P;
|
||||
if (ftdmchan->fds[FTDM_READ_TRACE_INDEX] > 0) {
|
||||
close(ftdmchan->fds[FTDM_READ_TRACE_INDEX]);
|
||||
ftdmchan->fds[FTDM_READ_TRACE_INDEX] = -1;
|
||||
|
@ -2576,6 +2710,127 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
|
||||
/*!< Enable DTMF debugging */
|
||||
case FTDM_COMMAND_ENABLE_DEBUG_DTMF:
|
||||
{
|
||||
if (ftdmchan->dtmfdbg.enabled) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot enable debug DTMF again\n");
|
||||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
if (ftdmchan->rxdump.buffer) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot debug DTMF if Rx dumping is already enabled\n");
|
||||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, FTDM_IO_DUMP_DEFAULT_BUFF_SIZE) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable rx dump for DTMF debugging\n");
|
||||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
ftdmchan->dtmfdbg.enabled = 1;
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Enabled DTMF debugging\n");
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
|
||||
/*!< Disable DTMF debugging (if not disabled explicitly, it is disabled automatically when calls hangup) */
|
||||
case FTDM_COMMAND_DISABLE_DEBUG_DTMF:
|
||||
{
|
||||
if (!ftdmchan->dtmfdbg.enabled) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "DTMF debug is already disabled\n");
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
if (disable_dtmf_debug(ftdmchan) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to disable DTMF debug\n");
|
||||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
|
||||
/*!< Start dumping all input to a circular buffer. The size of the circular buffer can be specified, default used otherwise */
|
||||
case FTDM_COMMAND_ENABLE_INPUT_DUMP:
|
||||
{
|
||||
ftdm_size_t size = obj ? FTDM_COMMAND_OBJ_SIZE : FTDM_IO_DUMP_DEFAULT_BUFF_SIZE;
|
||||
if (ftdmchan->rxdump.buffer) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Input dump is already enabled\n");
|
||||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, size) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable input dump\n");
|
||||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled input dump with size %zd\n", size);
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
|
||||
/*!< Stop dumping all input to a circular buffer. */
|
||||
case FTDM_COMMAND_DISABLE_INPUT_DUMP:
|
||||
{
|
||||
if (!ftdmchan->rxdump.buffer) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No need to disable input dump\n");
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Disabled input dump of size %zd\n", ftdmchan->rxdump.size);
|
||||
stop_chan_io_dump(&ftdmchan->rxdump);
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
|
||||
/*!< Start dumping all output to a circular buffer. The size of the circular buffer can be specified, default used otherwise */
|
||||
case FTDM_COMMAND_ENABLE_OUTPUT_DUMP:
|
||||
{
|
||||
ftdm_size_t size = obj ? FTDM_COMMAND_OBJ_SIZE : FTDM_IO_DUMP_DEFAULT_BUFF_SIZE;
|
||||
if (ftdmchan->txdump.buffer) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Output dump is already enabled\n");
|
||||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
if (start_chan_io_dump(ftdmchan, &ftdmchan->txdump, size) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable output dump\n");
|
||||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled output dump with size %zd\n", size);
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
|
||||
/*!< Stop dumping all output to a circular buffer. */
|
||||
case FTDM_COMMAND_DISABLE_OUTPUT_DUMP:
|
||||
{
|
||||
if (!ftdmchan->txdump.buffer) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No need to disable output dump\n");
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Disabled output dump of size %zd\n", ftdmchan->rxdump.size);
|
||||
stop_chan_io_dump(&ftdmchan->txdump);
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
|
||||
/*!< Dump the current input circular buffer to the specified FILE* structure */
|
||||
case FTDM_COMMAND_DUMP_INPUT:
|
||||
{
|
||||
if (!obj) {
|
||||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
dump_chan_io_to_file(ftdmchan, &ftdmchan->rxdump, obj);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %d to file %p\n", ftdmchan->rxdump.size, obj);
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
|
||||
/*!< Dump the current output circular buffer to the specified FILE* structure */
|
||||
case FTDM_COMMAND_DUMP_OUTPUT:
|
||||
{
|
||||
if (!obj) {
|
||||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
dump_chan_io_to_file(ftdmchan, &ftdmchan->txdump, obj);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %zd to file %p\n", ftdmchan->txdump.size, obj);
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_COMMAND_SET_INTERVAL:
|
||||
{
|
||||
if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_INTERVAL)) {
|
||||
|
@ -3044,55 +3299,45 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, cons
|
|||
ftdm_size_t wr = 0;
|
||||
const char *p;
|
||||
|
||||
assert(ftdmchan != NULL);
|
||||
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "No channel\n");
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Queuing DTMF %s\n", dtmf);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Queuing DTMF %s (debug = %d)\n", dtmf, ftdmchan->dtmfdbg.enabled);
|
||||
|
||||
if (!ftdmchan->dtmfdbg.enabled) {
|
||||
goto skipdebug;
|
||||
}
|
||||
|
||||
#ifdef FTDM_DEBUG_DTMF
|
||||
ftdm_mutex_lock(ftdmchan->dtmfdbg.mutex);
|
||||
if (!ftdmchan->dtmfdbg.file) {
|
||||
struct tm currtime;
|
||||
time_t currsec;
|
||||
char dfile[512];
|
||||
|
||||
currsec = time(NULL);
|
||||
|
||||
#ifdef WIN32
|
||||
_tzset();
|
||||
_localtime64_s(&currtime, &currsec);
|
||||
#else
|
||||
localtime_r(&currsec, &currtime);
|
||||
#endif
|
||||
|
||||
snprintf(dfile, sizeof(dfile), "dtmf-s%dc%d-20%d-%d-%d-%d:%d:%d.%s",
|
||||
ftdmchan->span_id, ftdmchan->chan_id,
|
||||
currtime.tm_year-100, currtime.tm_mon+1, currtime.tm_mday,
|
||||
currtime.tm_hour, currtime.tm_min, currtime.tm_sec, ftdmchan->native_codec == FTDM_CODEC_ULAW ? "ulaw" : ftdmchan->native_codec == FTDM_CODEC_ALAW ? "alaw" : "sln");
|
||||
ftdmchan->dtmfdbg.file = fopen(dfile, "w");
|
||||
ftdmchan->dtmfdbg.file = fopen(dfile, "w");
|
||||
if (!ftdmchan->dtmfdbg.file) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "failed to open debug dtmf file %s\n", dfile);
|
||||
} else {
|
||||
/* write the saved audio buffer */
|
||||
int rc = 0;
|
||||
int towrite = sizeof(ftdmchan->dtmfdbg.buffer) - ftdmchan->dtmfdbg.windex;
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "created debug DTMF file %s\n", dfile);
|
||||
ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT;
|
||||
if (ftdmchan->dtmfdbg.wrapped) {
|
||||
rc = fwrite(&ftdmchan->dtmfdbg.buffer[ftdmchan->dtmfdbg.windex], 1, towrite, ftdmchan->dtmfdbg.file);
|
||||
if (rc != towrite) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite);
|
||||
}
|
||||
}
|
||||
if (ftdmchan->dtmfdbg.windex) {
|
||||
towrite = ftdmchan->dtmfdbg.windex;
|
||||
rc = fwrite(&ftdmchan->dtmfdbg.buffer[0], 1, towrite, ftdmchan->dtmfdbg.file);
|
||||
if (rc != towrite) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite);
|
||||
}
|
||||
}
|
||||
ftdmchan->dtmfdbg.windex = 0;
|
||||
ftdmchan->dtmfdbg.wrapped = 0;
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_INPUT, ftdmchan->dtmfdbg.file);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped initial DTMF output to %s\n", dfile);
|
||||
}
|
||||
} else {
|
||||
ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT;
|
||||
ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT;
|
||||
}
|
||||
ftdm_mutex_unlock(ftdmchan->dtmfdbg.mutex);
|
||||
#endif
|
||||
|
||||
skipdebug:
|
||||
|
||||
if (ftdmchan->pre_buffer) {
|
||||
ftdm_buffer_zero(ftdmchan->pre_buffer);
|
||||
|
@ -3137,16 +3382,16 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, cons
|
|||
|
||||
static FIO_WRITE_FUNCTION(ftdm_raw_write)
|
||||
{
|
||||
int dlen = (int) *datalen;
|
||||
if (ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] > -1) {
|
||||
int dlen = (int) *datalen;
|
||||
if ((write(ftdmchan->fds[FTDM_WRITE_TRACE_INDEX], data, dlen)) != dlen) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Raw output trace failed to write all of the %zd bytes\n", dlen);
|
||||
}
|
||||
}
|
||||
write_chan_io_dump(&ftdmchan->txdump, data, dlen);
|
||||
return ftdmchan->fio->write(ftdmchan, data, datalen);
|
||||
}
|
||||
|
||||
|
||||
static FIO_READ_FUNCTION(ftdm_raw_read)
|
||||
{
|
||||
ftdm_status_t status = ftdmchan->fio->read(ftdmchan, data, datalen);
|
||||
|
@ -3161,48 +3406,24 @@ static FIO_READ_FUNCTION(ftdm_raw_read)
|
|||
ftdmchan->span->sig_read(ftdmchan, data, *datalen);
|
||||
}
|
||||
|
||||
#ifdef FTDM_DEBUG_DTMF
|
||||
if (status == FTDM_SUCCESS) {
|
||||
int dlen = (int) *datalen;
|
||||
int rc = 0;
|
||||
ftdm_mutex_lock(ftdmchan->dtmfdbg.mutex);
|
||||
if (!ftdmchan->dtmfdbg.file) {
|
||||
/* no file yet, write to our circular buffer */
|
||||
int windex = ftdmchan->dtmfdbg.windex;
|
||||
int avail = sizeof(ftdmchan->dtmfdbg.buffer) - windex;
|
||||
char *dataptr = data;
|
||||
size_t rc = 0;
|
||||
|
||||
if (dlen > avail) {
|
||||
int diff = dlen - avail;
|
||||
/* write only what we can and the rest at the beginning of the buffer */
|
||||
memcpy(&ftdmchan->dtmfdbg.buffer[windex], dataptr, avail);
|
||||
memcpy(&ftdmchan->dtmfdbg.buffer[0], &dataptr[avail], diff);
|
||||
windex = diff;
|
||||
/*ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "wrapping around dtmf read buffer up to index %d\n\n", windex);*/
|
||||
ftdmchan->dtmfdbg.wrapped = 1;
|
||||
} else {
|
||||
memcpy(&ftdmchan->dtmfdbg.buffer[windex], dataptr, dlen);
|
||||
windex += dlen;
|
||||
}
|
||||
if (windex == sizeof(ftdmchan->dtmfdbg.buffer)) {
|
||||
/*ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "wrapping around dtmf read buffer\n");*/
|
||||
windex = 0;
|
||||
ftdmchan->dtmfdbg.wrapped = 1;
|
||||
}
|
||||
ftdmchan->dtmfdbg.windex = windex;
|
||||
} else {
|
||||
write_chan_io_dump(&ftdmchan->rxdump, data, dlen);
|
||||
|
||||
/* if dtmf debug is enabled and initialized, write there too */
|
||||
if (ftdmchan->dtmfdbg.file) {
|
||||
rc = fwrite(data, 1, dlen, ftdmchan->dtmfdbg.file);
|
||||
if (rc != dlen) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "DTMF debugger wrote only %d out of %d bytes: %s\n", rc, datalen, strerror(errno));
|
||||
}
|
||||
ftdmchan->dtmfdbg.closetimeout--;
|
||||
if (!ftdmchan->dtmfdbg.closetimeout) {
|
||||
close_dtmf_debug(ftdmchan);
|
||||
close_dtmf_debug_file(ftdmchan);
|
||||
}
|
||||
}
|
||||
ftdm_mutex_unlock(ftdmchan->dtmfdbg.mutex);
|
||||
}
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -3998,6 +4219,7 @@ static ftdm_status_t ftdm_set_channels_alarms(ftdm_span_t *span, int currindex)
|
|||
FT_DECLARE(ftdm_status_t) ftdm_configure_span_channels(ftdm_span_t *span, const char* str, ftdm_channel_config_t *chan_config, unsigned *configured)
|
||||
{
|
||||
int currindex;
|
||||
unsigned chan_index = 0;
|
||||
|
||||
ftdm_assert_return(span != NULL, FTDM_EINVAL, "span is null\n");
|
||||
ftdm_assert_return(chan_config != NULL, FTDM_EINVAL, "config is null\n");
|
||||
|
@ -4031,6 +4253,14 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_channels(ftdm_span_t *span, const
|
|||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (chan_config->debugdtmf) {
|
||||
for (chan_index = currindex+1; chan_index <= span->chan_count; chan_index++) {
|
||||
if (!FTDM_IS_VOICE_CHANNEL(span->channels[chan_index])) {
|
||||
continue;
|
||||
}
|
||||
span->channels[chan_index]->dtmfdbg.requested = 1;
|
||||
}
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -4049,7 +4279,7 @@ static ftdm_status_t load_config(void)
|
|||
ftdm_channel_config_t chan_config;
|
||||
|
||||
memset(&chan_config, 0, sizeof(chan_config));
|
||||
sprintf(chan_config.group_name,"default");
|
||||
sprintf(chan_config.group_name, "__default");
|
||||
|
||||
if (!ftdm_config_open_file(&cfg, cfg_name)) {
|
||||
return FTDM_FAIL;
|
||||
|
@ -4086,6 +4316,9 @@ static ftdm_status_t load_config(void)
|
|||
if (ftdm_span_create(type, name, &span) == FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "created span %d (%s) of type %s\n", span->span_id, span->name, type);
|
||||
d = 0;
|
||||
/* it is confusing that parameters from one span affect others, so let's clear them */
|
||||
memset(&chan_config, 0, sizeof(chan_config));
|
||||
sprintf(chan_config.group_name, "__default");
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_CRIT, "failure creating span of type %s\n", type);
|
||||
span = NULL;
|
||||
|
@ -4209,6 +4442,9 @@ static ftdm_status_t load_config(void)
|
|||
if (sscanf(val, "%f", &(chan_config.rxgain)) != 1) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "invalid rxgain: '%s'\n", val);
|
||||
}
|
||||
} else if (!strcasecmp(var, "debugdtmf")) {
|
||||
chan_config.debugdtmf = ftdm_true(val);
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Setting debugdtmf to '%s'\n", chan_config.debugdtmf ? "yes" : "no");
|
||||
} else if (!strcasecmp(var, "group")) {
|
||||
len = strlen(val);
|
||||
if (len >= FTDM_MAX_NAME_STR_SZ) {
|
||||
|
@ -4860,6 +5096,9 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
|||
case FTDM_SIGEVENT_START:
|
||||
{
|
||||
ftdm_set_echocancel_call_begin(sigmsg->channel);
|
||||
if (sigmsg->channel->dtmfdbg.requested) {
|
||||
ftdm_channel_command(sigmsg->channel, FTDM_COMMAND_ENABLE_DEBUG_DTMF, NULL);
|
||||
}
|
||||
|
||||
/* when cleaning up the public API I added this because mod_freetdm.c on_fxs_signal was
|
||||
* doing it during SIGEVENT_START, but now that flags are private they can't, wonder if
|
||||
|
|
|
@ -1,353 +1,353 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="ftmod_analog"
|
||||
ProjectGUID="{37C94798-6E33-4B4F-8EE0-C72A7DC91157}"
|
||||
RootNamespace="ftmod_analog"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="4"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="false"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="ftmod_analog.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="ftdm_analog.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="ftmod_analog"
|
||||
ProjectGUID="{37C94798-6E33-4B4F-8EE0-C72A7DC91157}"
|
||||
RootNamespace="ftmod_analog"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="4"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="false"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="false"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="ftmod_analog.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="ftdm_analog.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
|
|
@ -168,7 +168,7 @@
|
|||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
|
|
|
@ -341,8 +341,8 @@ static void send_caller_id(ftdm_channel_t *ftdmchan)
|
|||
static void analog_dial(ftdm_channel_t *ftdmchan, uint32_t *state_counter, uint32_t *dial_timeout)
|
||||
{
|
||||
if (ftdm_strlen_zero(ftdmchan->caller_data.dnis.digits)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "No Digits to send!\n");
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No digits to send, moving to UP!\n");
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
} else {
|
||||
if (ftdm_channel_command(ftdmchan, FTDM_COMMAND_SEND_DTMF, ftdmchan->caller_data.dnis.digits) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Send Digits Failed [%s]\n", ftdmchan->last_error);
|
||||
|
|
|
@ -1,353 +1,353 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="ftmod_analog_em"
|
||||
ProjectGUID="{B3F49375-2834-4937-9D8C-4AC2EC911010}"
|
||||
RootNamespace="ftmod_analog_em"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EM_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="4"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EM_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EM_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="false"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EM_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="ftmod_analog_em.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="ftdm_analog_em.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="ftmod_analog_em"
|
||||
ProjectGUID="{B3F49375-2834-4937-9D8C-4AC2EC911010}"
|
||||
RootNamespace="ftmod_analog_em"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EM_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="4"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EM_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="false"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EM_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="..\..\include;..\..\isdn\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EM_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="false"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="ftmod_analog_em.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="ftdm_analog_em.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
|
|
@ -168,7 +168,7 @@
|
|||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
|
|
|
@ -5,10 +5,18 @@
|
|||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>ftmod_r2</ProjectName>
|
||||
|
@ -19,33 +27,53 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkIncremental>
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
|
@ -68,6 +96,25 @@
|
|||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\include;c:\Program Files\openr2\include\openr2;C:\Program Files\openr2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_R2_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>freetdm.lib;openr2.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\openr2\lib;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\include;C:\Program Files\openr2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
|
@ -86,6 +133,23 @@
|
|||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\include;C:\Program Files\openr2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_R2_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ftmod_r2.c" />
|
||||
</ItemGroup>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -95,83 +95,6 @@
|
|||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="..\..\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
|
@ -249,6 +172,83 @@
|
|||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="..\..\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_SANGOMA_BOOST_EXPORTS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
|
@ -283,7 +283,7 @@
|
|||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarnAsError="true"
|
||||
WarnAsError="false"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
|
|
|
@ -172,7 +172,7 @@
|
|||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
|
|
|
@ -5,10 +5,18 @@
|
|||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>ftmod_sangoma_isdn</ProjectName>
|
||||
|
@ -21,33 +29,58 @@
|
|||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkIncremental>
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
|
@ -74,6 +107,29 @@
|
|||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\libsng_isdn\include;C:\Program Files\libsng_isdn\include\sng_isdn;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>
|
||||
</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);C:\Program Files\libsng_isdn\lib;C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
@ -93,6 +149,23 @@
|
|||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ftmod_sangoma_isdn.h" />
|
||||
<ClInclude Include="ftmod_sangoma_isdn_trace.h" />
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
*/
|
||||
|
||||
#include "ftmod_sangoma_isdn.h"
|
||||
ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn);
|
||||
|
||||
/* Remote side transmit a SETUP */
|
||||
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
||||
|
@ -131,11 +132,13 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
get_called_num(ftdmchan, &conEvnt->cdPtyNmb);
|
||||
get_redir_num(ftdmchan, &conEvnt->redirNmb);
|
||||
get_calling_subaddr(ftdmchan, &conEvnt->cgPtySad);
|
||||
get_prog_ind_ie(ftdmchan, &conEvnt->progInd);
|
||||
get_facility_ie(ftdmchan, &conEvnt->facilityStr);
|
||||
|
||||
if (get_calling_name_from_display(ftdmchan, &conEvnt->display) != FTDM_SUCCESS) {
|
||||
get_calling_name_from_usr_usr(ftdmchan, &conEvnt->usrUsr);
|
||||
}
|
||||
get_prog_ind_ie(ftdmchan, &conEvnt->progInd);
|
||||
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Incoming call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
|
||||
|
||||
|
@ -151,40 +154,34 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
}
|
||||
}
|
||||
|
||||
if (conEvnt->facilityStr.eh.pres) {
|
||||
if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) {
|
||||
get_facility_ie(ftdmchan, &conEvnt->facilityStr);
|
||||
} else if (signal_data->facility == SNGISDN_OPT_TRUE) {
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_NI2) {
|
||||
/* Verify whether the Caller Name will come in a subsequent FACILITY message */
|
||||
uint16_t ret_val;
|
||||
char retrieved_str[255];
|
||||
/* this should be in get_facility_ie function, fix this later */
|
||||
if (signal_data->facility == SNGISDN_OPT_TRUE && conEvnt->facilityStr.eh.pres) {
|
||||
/* Verify whether the Caller Name will come in a subsequent FACILITY message */
|
||||
uint16_t ret_val;
|
||||
char retrieved_str[255];
|
||||
|
||||
ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str);
|
||||
/*
|
||||
return values for "sng_isdn_retrieve_facility_information_following":
|
||||
If there will be no information following, or fails to decode IE, returns -1
|
||||
If there will be no information following, but current FACILITY IE contains a caller name, returns 0
|
||||
If there will be information following, returns 1
|
||||
*/
|
||||
ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str);
|
||||
/*
|
||||
return values for "sng_isdn_retrieve_facility_information_following":
|
||||
If there will be no information following, or fails to decode IE, returns -1
|
||||
If there will be no information following, but current FACILITY IE contains a caller name, returns 0
|
||||
If there will be information following, returns 1
|
||||
*/
|
||||
|
||||
if (ret_val == 1) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n");
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID);
|
||||
/* Launch timer in case we never get a FACILITY msg */
|
||||
if (signal_data->facility_timeout) {
|
||||
ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout,
|
||||
sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
|
||||
}
|
||||
break;
|
||||
} else if (ret_val == 0) {
|
||||
strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
|
||||
}
|
||||
break;
|
||||
if (ret_val == 1) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n");
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID);
|
||||
/* Launch timer in case we never get a FACILITY msg */
|
||||
if (signal_data->facility_timeout) {
|
||||
ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout,
|
||||
sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
|
||||
}
|
||||
break;
|
||||
} else if (ret_val == 0) {
|
||||
strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (signal_data->overlap_dial == SNGISDN_OPT_TRUE && !conEvnt->sndCmplt.eh.pres) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
|
||||
} else {
|
||||
|
@ -284,6 +281,7 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd);
|
||||
get_facility_ie(ftdmchan, &cnStEvnt->facilityStr);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
|
@ -351,34 +349,17 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
case MI_PROGRESS:
|
||||
case MI_ALERTING:
|
||||
get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd);
|
||||
get_facility_ie(ftdmchan, &cnStEvnt->facilityStr);
|
||||
|
||||
if (signal_data->ignore_cause_value != SNGISDN_OPT_TRUE &&
|
||||
cnStEvnt->causeDgn[0].eh.pres && cnStEvnt->causeDgn[0].causeVal.pres) {
|
||||
|
||||
switch(cnStEvnt->causeDgn[0].causeVal.val) {
|
||||
case 17: /* User Busy */
|
||||
case 18: /* No User responding */
|
||||
case 19: /* User alerting, no answer */
|
||||
case 21: /* Call rejected, the called party does not with to accept this call */
|
||||
case 27: /* Destination out of order */
|
||||
case 31: /* Normal, unspecified */
|
||||
case 34: /* Circuit/Channel congestion */
|
||||
case 41: /* Temporary failure */
|
||||
case 42: /* Switching equipment is experiencing a period of high traffic */
|
||||
case 47: /* Resource unavailable */
|
||||
case 58: /* Bearer Capability not available */
|
||||
case 63: /* Service or option not available */
|
||||
case 65: /* Bearer Cap not implemented, not supported */
|
||||
case 79: /* Service or option not implemented, unspecified */
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Cause requires disconnect (cause:%d)\n", cnStEvnt->causeDgn[0].causeVal.val);
|
||||
ftdmchan->caller_data.hangup_cause = cnStEvnt->causeDgn[0].causeVal.val;
|
||||
if (sngisdn_cause_val_requires_disconnect(ftdmchan, &cnStEvnt->causeDgn[0]) == FTDM_SUCCESS) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Cause requires disconnect (cause:%d)\n", cnStEvnt->causeDgn[0].causeVal.val);
|
||||
ftdmchan->caller_data.hangup_cause = cnStEvnt->causeDgn[0].causeVal.val;
|
||||
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
goto sngisdn_process_cnst_ind_end;
|
||||
}
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
goto sngisdn_process_cnst_ind_end;
|
||||
}
|
||||
|
||||
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
|
@ -461,7 +442,6 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
uint32_t spInstId = sngisdn_event->spInstId;
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
DiscEvnt *discEvnt = &sngisdn_event->event.discEvnt;
|
||||
|
||||
|
@ -476,14 +456,9 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
if (discEvnt->facilityStr.eh.pres) {
|
||||
if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) {
|
||||
get_facility_ie(ftdmchan, &discEvnt->facilityStr);
|
||||
} else {
|
||||
/* Call libsng_isdn facility decode function and copy variables here */
|
||||
}
|
||||
}
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
get_facility_ie(ftdmchan, &discEvnt->facilityStr);
|
||||
|
||||
if (discEvnt->causeDgn[0].eh.pres && discEvnt->causeDgn[0].causeVal.pres) {
|
||||
ftdmchan->caller_data.hangup_cause = discEvnt->causeDgn[0].causeVal.val;
|
||||
} else {
|
||||
|
@ -527,7 +502,6 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
uint32_t spInstId = sngisdn_event->spInstId;
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
RelEvnt *relEvnt = &sngisdn_event->event.relEvnt;
|
||||
|
||||
|
@ -574,13 +548,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
if (((sngisdn_chan_data_t*)ftdmchan->call_data)->suInstId == suInstId ||
|
||||
((sngisdn_chan_data_t*)ftdmchan->call_data)->spInstId == spInstId) {
|
||||
|
||||
if (relEvnt->facilityStr.eh.pres) {
|
||||
if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) {
|
||||
get_facility_ie(ftdmchan, &relEvnt->facilityStr);
|
||||
} else {
|
||||
/* Call libsng_isdn facility decode function and copy variables here */
|
||||
}
|
||||
}
|
||||
get_facility_ie(ftdmchan, &relEvnt->facilityStr);
|
||||
|
||||
if (relEvnt->causeDgn[0].eh.pres && relEvnt->causeDgn[0].causeVal.pres) {
|
||||
ftdmchan->caller_data.hangup_cause = relEvnt->causeDgn[0].causeVal.val;
|
||||
|
@ -791,11 +759,7 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
{
|
||||
ftdm_sigmsg_t sigev;
|
||||
if (facEvnt->facElmt.facStr.pres) {
|
||||
if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) {
|
||||
get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len);
|
||||
} else {
|
||||
/* Call libsng_isdn facility decode function and copy variables here */
|
||||
}
|
||||
get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len);
|
||||
}
|
||||
memset(&sigev, 0, sizeof(sigev));
|
||||
sigev.chan_id = ftdmchan->chan_id;
|
||||
|
@ -1119,8 +1083,44 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
(evntType == IN_LNK_DWN)?"LNK_DOWN":
|
||||
(evntType == IN_LNK_UP)?"LNK_UP":
|
||||
(evntType == IN_INDCHAN)?"b-channel":
|
||||
(evntType == IN_LNK_DWN_DM_RLS)?"Nfas service procedures":
|
||||
(evntType == IN_LNK_DWN_DM_RLS)?"NFAS service procedures":
|
||||
(evntType == IN_SWCHD_BU_DCHAN)?"NFAS switchover to backup":"Unknown");
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
if (signal_data->ignore_cause_value == SNGISDN_OPT_TRUE) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* By default, we only evaluate cause value on 5ESS switches */
|
||||
if (signal_data->ignore_cause_value == SNGISDN_OPT_DEFAULT &&
|
||||
signal_data->switchtype != SNGISDN_SWITCH_5ESS) {
|
||||
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* ignore_cause_value = SNGISDN_OPT_FALSE or switchtype == 5ESS */
|
||||
switch(causeDgn->causeVal.val) {
|
||||
case 17: /* User Busy */
|
||||
case 18: /* No User responding */
|
||||
case 19: /* User alerting, no answer */
|
||||
case 21: /* Call rejected, the called party does not with to accept this call */
|
||||
case 27: /* Destination out of order */
|
||||
case 31: /* Normal, unspecified */
|
||||
case 34: /* Circuit/Channel congestion */
|
||||
case 41: /* Temporary failure */
|
||||
case 42: /* Switching equipment is experiencing a period of high traffic */
|
||||
case 47: /* Resource unavailable */
|
||||
case 58: /* Bearer Capability not available */
|
||||
case 63: /* Service or option not available */
|
||||
case 65: /* Bearer Cap not implemented, not supported */
|
||||
case 79: /* Service or option not implemented, unspecified */
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
|
|
@ -310,6 +310,7 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan)
|
|||
cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROCEED (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
|
|
|
@ -283,7 +283,7 @@ ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
|
|||
}
|
||||
|
||||
ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr)
|
||||
{
|
||||
{
|
||||
if (!facilityStr->eh.pres) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -294,18 +294,25 @@ ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr
|
|||
ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t data_len)
|
||||
{
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
if (data_len > sizeof(caller_data->raw_data)-2) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Length of Facility IE exceeds maximum length\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
memset(caller_data->raw_data, 0, sizeof(caller_data->raw_data));
|
||||
/* Always include Facility IE identifier + len so this can be used as a sanity check by the user */
|
||||
caller_data->raw_data[0] = SNGISDN_Q931_FACILITY_IE_ID;
|
||||
caller_data->raw_data[1] = data_len;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
memcpy(&caller_data->raw_data[2], data, data_len);
|
||||
caller_data->raw_data_len = data_len+2;
|
||||
if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) {
|
||||
if (data_len > sizeof(caller_data->raw_data)-2) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Length of Facility IE exceeds maximum length\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
memset(caller_data->raw_data, 0, sizeof(caller_data->raw_data));
|
||||
/* Always include Facility IE identifier + len so this can be used as a sanity check by the user */
|
||||
caller_data->raw_data[0] = SNGISDN_Q931_FACILITY_IE_ID;
|
||||
caller_data->raw_data[1] = data_len;
|
||||
|
||||
memcpy(&caller_data->raw_data[2], data, data_len);
|
||||
caller_data->raw_data_len = data_len+2;
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Raw Facility IE copied available\n");
|
||||
} else {
|
||||
/* Call libsng_isdn to process facility IE's here */
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -394,10 +401,19 @@ ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
|
|||
cgPtyNmb->presInd0.val = caller_data->pres;
|
||||
|
||||
cgPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
|
||||
cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan;
|
||||
if (caller_data->cid_num.plan >= FTDM_NPI_INVALID) {
|
||||
cgPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
|
||||
} else {
|
||||
cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan;
|
||||
}
|
||||
|
||||
cgPtyNmb->typeNmb1.pres = PRSNT_NODEF;
|
||||
cgPtyNmb->typeNmb1.val = caller_data->cid_num.type;
|
||||
|
||||
if (caller_data->cid_num.type >= FTDM_TON_INVALID) {
|
||||
cgPtyNmb->typeNmb1.val = FTDM_TON_UNKNOWN;
|
||||
} else {
|
||||
cgPtyNmb->typeNmb1.val = caller_data->cid_num.type;
|
||||
}
|
||||
|
||||
cgPtyNmb->nmbDigits.pres = PRSNT_NODEF;
|
||||
cgPtyNmb->nmbDigits.len = len;
|
||||
|
@ -418,14 +434,14 @@ ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb)
|
|||
cdPtyNmb->eh.pres = PRSNT_NODEF;
|
||||
|
||||
cdPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
|
||||
if (caller_data->dnis.plan == FTDM_NPI_INVALID) {
|
||||
if (caller_data->dnis.plan >= FTDM_NPI_INVALID) {
|
||||
cdPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
|
||||
} else {
|
||||
cdPtyNmb->nmbPlanId.val = caller_data->dnis.plan;
|
||||
}
|
||||
|
||||
cdPtyNmb->typeNmb0.pres = PRSNT_NODEF;
|
||||
if (caller_data->dnis.type == FTDM_TON_INVALID) {
|
||||
if (caller_data->dnis.type >= FTDM_TON_INVALID) {
|
||||
cdPtyNmb->typeNmb0.val = FTDM_TON_UNKNOWN;
|
||||
} else {
|
||||
cdPtyNmb->typeNmb0.val = caller_data->dnis.type;
|
||||
|
@ -450,14 +466,14 @@ ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb)
|
|||
redirNmb->eh.pres = PRSNT_NODEF;
|
||||
|
||||
redirNmb->nmbPlanId.pres = PRSNT_NODEF;
|
||||
if (caller_data->rdnis.plan == FTDM_NPI_INVALID) {
|
||||
if (caller_data->rdnis.plan >= FTDM_NPI_INVALID) {
|
||||
redirNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
|
||||
} else {
|
||||
redirNmb->nmbPlanId.val = caller_data->rdnis.plan;
|
||||
}
|
||||
|
||||
redirNmb->typeNmb.pres = PRSNT_NODEF;
|
||||
if (caller_data->rdnis.type == FTDM_TON_INVALID) {
|
||||
if (caller_data->rdnis.type >= FTDM_TON_INVALID) {
|
||||
redirNmb->typeNmb.val = FTDM_TON_UNKNOWN;
|
||||
} else {
|
||||
redirNmb->typeNmb.val = caller_data->rdnis.type;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
* Moises Silva <moy@sangoma.com>
|
||||
* David Yat Sin <davidy@sangoma.com>
|
||||
* Nenad Corbic <ncorbic@sangoma.com>
|
||||
* Arnaldo Pereira <arnaldo@sangoma.com>
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -99,7 +100,8 @@ static struct {
|
|||
/* a bunch of this stuff should go into the wanpipe_tdm_api_iface.h */
|
||||
|
||||
FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event);
|
||||
FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event);
|
||||
FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event);
|
||||
FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event);
|
||||
|
||||
/**
|
||||
* \brief Poll for event on a wanpipe socket
|
||||
|
@ -794,7 +796,7 @@ static void wanpipe_write_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_tx_hdr_t *t
|
|||
/* we don't test for 80% full in tx since is typically full for voice channels, should we test tx 80% full for D-channels? */
|
||||
if (ftdmchan->iostats.tx.queue_len >= ftdmchan->iostats.tx.queue_size) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Tx Queue Full (%d/%d)\n",
|
||||
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.tx.queue_size);
|
||||
ftdmchan->iostats.tx.queue_len, ftdmchan->iostats.tx.queue_size);
|
||||
ftdm_set_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
|
||||
} else if (ftdm_test_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL)){
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Tx Queue no longer full (%d/%d)\n",
|
||||
|
@ -861,7 +863,6 @@ static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx
|
|||
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
|
||||
ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
|
||||
} else if (ftdm_test_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)){
|
||||
/* any reason we have wanpipe_tdm_api_iface.h in ftmod_wanpipe/ dir? */
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Rx Queue length reduced 80% threshold (%d/%d)\n",
|
||||
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
|
||||
ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
|
||||
|
@ -944,7 +945,10 @@ static FIO_WRITE_FUNCTION(wanpipe_write)
|
|||
if (bsent > 0) {
|
||||
*datalen = bsent;
|
||||
if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS)) {
|
||||
wanpipe_write_stats(ftdmchan, &hdrframe);
|
||||
/* BRI cards do not support TX queues for now */
|
||||
if(!FTDM_SPAN_IS_BRI(ftdmchan->span)) {
|
||||
wanpipe_write_stats(ftdmchan, &hdrframe);
|
||||
}
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
@ -1181,13 +1185,155 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves an event from a wanpipe channel
|
||||
* \param channel Channel to retrieve event from
|
||||
* \param event FreeTDM event to return
|
||||
* \return Success or failure
|
||||
*/
|
||||
FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event)
|
||||
{
|
||||
ftdm_status_t status;
|
||||
ftdm_oob_event_t event_id;
|
||||
wanpipe_tdm_api_t tdm_api;
|
||||
ftdm_span_t *span = ftdmchan->span;
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_EVENT))
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_EVENT);
|
||||
|
||||
memset(&tdm_api, 0, sizeof(tdm_api));
|
||||
status = sangoma_tdm_read_event(ftdmchan->sockfd, &tdm_api);
|
||||
if (status != FTDM_SUCCESS) {
|
||||
snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno));
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to read event from channel: %s\n", strerror(errno));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "read wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
||||
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type) {
|
||||
|
||||
case WP_TDMAPI_EVENT_LINK_STATUS:
|
||||
{
|
||||
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
|
||||
case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
|
||||
event_id = FTDM_OOB_ALARM_CLEAR;
|
||||
break;
|
||||
default:
|
||||
event_id = FTDM_OOB_ALARM_TRAP;
|
||||
break;
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
||||
case WP_TDMAPI_EVENT_RXHOOK:
|
||||
{
|
||||
if (ftdmchan->type == FTDM_CHAN_TYPE_FXS) {
|
||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_OFFHOOK : FTDM_OOB_ONHOOK;
|
||||
if (event_id == FTDM_OOB_OFFHOOK) {
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_FLASH)) {
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_FLASH);
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_WINK);
|
||||
event_id = FTDM_OOB_FLASH;
|
||||
goto event;
|
||||
} else {
|
||||
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_WINK);
|
||||
}
|
||||
} else {
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_WINK)) {
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_WINK);
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_FLASH);
|
||||
event_id = FTDM_OOB_WINK;
|
||||
goto event;
|
||||
} else {
|
||||
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_FLASH);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
wanpipe_tdm_api_t onhook_tdm_api;
|
||||
memset(&onhook_tdm_api, 0, sizeof(onhook_tdm_api));
|
||||
status = sangoma_tdm_txsig_onhook(ftdmchan->sockfd, &onhook_tdm_api);
|
||||
if (status) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "ONHOOK Failed");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
event_id = onhook_tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_ONHOOK : FTDM_OOB_NOOP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WP_TDMAPI_EVENT_RING_DETECT:
|
||||
{
|
||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_RING_START : FTDM_OOB_RING_STOP;
|
||||
}
|
||||
break;
|
||||
/*
|
||||
disabled this ones when configuring, we don't need them, do we?
|
||||
case WP_TDMAPI_EVENT_RING_TRIP_DETECT:
|
||||
{
|
||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_ONHOOK : FTDM_OOB_OFFHOOK;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case WP_TDMAPI_EVENT_RBS:
|
||||
{
|
||||
event_id = FTDM_OOB_CAS_BITS_CHANGE;
|
||||
ftdmchan->rx_cas_bits = wanpipe_swap_bits(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits);
|
||||
}
|
||||
break;
|
||||
case WP_TDMAPI_EVENT_DTMF:
|
||||
{
|
||||
char tmp_dtmf[2] = { tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_digit, 0 };
|
||||
event_id = FTDM_OOB_NOOP;
|
||||
|
||||
if (tmp_dtmf[0] == 'f') {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Ignoring wanpipe DTMF: %c, fax tones will be passed through!\n", tmp_dtmf[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_PRESENT) {
|
||||
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_MUTE);
|
||||
}
|
||||
|
||||
if (tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_STOP) {
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_MUTE);
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c\n", tmp_dtmf[0]);
|
||||
ftdm_channel_queue_dtmf(ftdmchan, tmp_dtmf);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WP_TDMAPI_EVENT_ALARM:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Got wanpipe alarms %d\n", tdm_api.wp_tdm_cmd.event.wp_api_event_alarm);
|
||||
event_id = FTDM_OOB_ALARM_TRAP;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unhandled wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
||||
event_id = FTDM_OOB_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
event:
|
||||
|
||||
ftdmchan->last_event_time = 0;
|
||||
span->event_header.e_type = FTDM_EVENT_OOB;
|
||||
span->event_header.enum_id = event_id;
|
||||
span->event_header.channel = ftdmchan;
|
||||
*event = &span->event_header;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves an event from a wanpipe span
|
||||
* \param span Span to retrieve event from
|
||||
* \param event FreeTDM event to return
|
||||
* \return Success or failure
|
||||
*/
|
||||
FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event)
|
||||
FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event)
|
||||
{
|
||||
uint32_t i,err;
|
||||
ftdm_oob_event_t event_id;
|
||||
|
@ -1419,7 +1565,8 @@ static FIO_IO_LOAD_FUNCTION(wanpipe_init)
|
|||
wanpipe_interface.read = wanpipe_read;
|
||||
wanpipe_interface.write = wanpipe_write;
|
||||
wanpipe_interface.poll_event = wanpipe_poll_event;
|
||||
wanpipe_interface.next_event = wanpipe_next_event;
|
||||
wanpipe_interface.next_event = wanpipe_span_next_event;
|
||||
wanpipe_interface.channel_next_event = wanpipe_channel_next_event;
|
||||
wanpipe_interface.channel_destroy = wanpipe_channel_destroy;
|
||||
wanpipe_interface.get_alarms = wanpipe_get_alarms;
|
||||
*fio = &wanpipe_interface;
|
||||
|
|
|
@ -351,6 +351,7 @@ typedef struct ftdm_channel_config {
|
|||
ftdm_chan_type_t type;
|
||||
float rxgain;
|
||||
float txgain;
|
||||
uint8_t debugdtmf;
|
||||
} ftdm_channel_config_t;
|
||||
|
||||
/*!
|
||||
|
@ -431,9 +432,38 @@ typedef enum {
|
|||
FTDM_COMMAND_WINK,
|
||||
FTDM_COMMAND_ENABLE_PROGRESS_DETECT,
|
||||
FTDM_COMMAND_DISABLE_PROGRESS_DETECT,
|
||||
|
||||
/*!< Start tracing input and output from channel to the given file */
|
||||
FTDM_COMMAND_TRACE_INPUT,
|
||||
FTDM_COMMAND_TRACE_OUTPUT,
|
||||
|
||||
/*!< Stop both Input and Output trace, closing the files */
|
||||
FTDM_COMMAND_TRACE_END_ALL,
|
||||
|
||||
/*!< Enable DTMF debugging */
|
||||
FTDM_COMMAND_ENABLE_DEBUG_DTMF,
|
||||
|
||||
/*!< Disable DTMF debugging (if not disabled explicitly, it is disabled automatically when calls hangup) */
|
||||
FTDM_COMMAND_DISABLE_DEBUG_DTMF,
|
||||
|
||||
/*!< Start dumping all input to a circular buffer. The size of the circular buffer can be specified, default used otherwise */
|
||||
FTDM_COMMAND_ENABLE_INPUT_DUMP,
|
||||
|
||||
/*!< Stop dumping all input to a circular buffer. */
|
||||
FTDM_COMMAND_DISABLE_INPUT_DUMP,
|
||||
|
||||
/*!< Start dumping all output to a circular buffer. The size of the circular buffer can be specified, default used otherwise */
|
||||
FTDM_COMMAND_ENABLE_OUTPUT_DUMP,
|
||||
|
||||
/*!< Stop dumping all output to a circular buffer. */
|
||||
FTDM_COMMAND_DISABLE_OUTPUT_DUMP,
|
||||
|
||||
/*!< Dump the current input circular buffer to the specified FILE* structure */
|
||||
FTDM_COMMAND_DUMP_INPUT,
|
||||
|
||||
/*!< Dump the current output circular buffer to the specified FILE* structure */
|
||||
FTDM_COMMAND_DUMP_OUTPUT,
|
||||
|
||||
FTDM_COMMAND_ENABLE_CALLERID_DETECT,
|
||||
FTDM_COMMAND_DISABLE_CALLERID_DETECT,
|
||||
FTDM_COMMAND_ENABLE_ECHOCANCEL,
|
||||
|
@ -483,6 +513,7 @@ struct ftdm_memory_handler {
|
|||
#define FIO_SPAN_GET_SIG_STATUS_ARGS (ftdm_span_t *span, ftdm_signaling_status_t *status)
|
||||
#define FIO_SPAN_POLL_EVENT_ARGS (ftdm_span_t *span, uint32_t ms, short *poll_events)
|
||||
#define FIO_SPAN_NEXT_EVENT_ARGS (ftdm_span_t *span, ftdm_event_t **event)
|
||||
#define FIO_CHANNEL_NEXT_EVENT_ARGS (ftdm_channel_t *ftdmchan, ftdm_event_t **event)
|
||||
#define FIO_SIGNAL_CB_ARGS (ftdm_sigmsg_t *sigmsg)
|
||||
#define FIO_EVENT_CB_ARGS (ftdm_channel_t *ftdmchan, ftdm_event_t *event)
|
||||
#define FIO_CONFIGURE_SPAN_ARGS (ftdm_span_t *span, const char *str, ftdm_chan_type_t type, char *name, char *number)
|
||||
|
@ -514,6 +545,7 @@ typedef ftdm_status_t (*fio_span_set_sig_status_t) FIO_SPAN_SET_SIG_STATUS_ARGS;
|
|||
typedef ftdm_status_t (*fio_span_get_sig_status_t) FIO_SPAN_GET_SIG_STATUS_ARGS;
|
||||
typedef ftdm_status_t (*fio_span_poll_event_t) FIO_SPAN_POLL_EVENT_ARGS ;
|
||||
typedef ftdm_status_t (*fio_span_next_event_t) FIO_SPAN_NEXT_EVENT_ARGS ;
|
||||
typedef ftdm_status_t (*fio_channel_next_event_t) FIO_CHANNEL_NEXT_EVENT_ARGS ;
|
||||
typedef ftdm_status_t (*fio_signal_cb_t) FIO_SIGNAL_CB_ARGS ;
|
||||
typedef ftdm_status_t (*fio_event_cb_t) FIO_EVENT_CB_ARGS ;
|
||||
typedef ftdm_status_t (*fio_configure_span_t) FIO_CONFIGURE_SPAN_ARGS ;
|
||||
|
@ -546,6 +578,7 @@ typedef ftdm_status_t (*fio_api_t) FIO_API_ARGS ;
|
|||
#define FIO_SPAN_GET_SIG_STATUS_FUNCTION(name) ftdm_status_t name FIO_SPAN_GET_SIG_STATUS_ARGS
|
||||
#define FIO_SPAN_POLL_EVENT_FUNCTION(name) ftdm_status_t name FIO_SPAN_POLL_EVENT_ARGS
|
||||
#define FIO_SPAN_NEXT_EVENT_FUNCTION(name) ftdm_status_t name FIO_SPAN_NEXT_EVENT_ARGS
|
||||
#define FIO_CHANNEL_NEXT_EVENT_FUNCTION(name) ftdm_status_t name FIO_CHANNEL_NEXT_EVENT_ARGS
|
||||
#define FIO_SIGNAL_CB_FUNCTION(name) ftdm_status_t name FIO_SIGNAL_CB_ARGS
|
||||
#define FIO_EVENT_CB_FUNCTION(name) ftdm_status_t name FIO_EVENT_CB_ARGS
|
||||
#define FIO_CONFIGURE_SPAN_FUNCTION(name) ftdm_status_t name FIO_CONFIGURE_SPAN_ARGS
|
||||
|
@ -584,6 +617,7 @@ struct ftdm_io_interface {
|
|||
fio_write_t write; /*!< Write data to the channel */
|
||||
fio_span_poll_event_t poll_event; /*!< Poll for events on the whole span */
|
||||
fio_span_next_event_t next_event; /*!< Retrieve an event from the span */
|
||||
fio_channel_next_event_t channel_next_event; /*!< Retrieve an event from channel */
|
||||
fio_api_t api; /*!< Execute a text command */
|
||||
};
|
||||
|
||||
|
@ -902,6 +936,23 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_add_to_group(const char* name, ftdm_chann
|
|||
/*! \brief Remove the channel from a hunt group */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_remove_from_group(ftdm_group_t* group, ftdm_channel_t* ftdmchan);
|
||||
|
||||
/*!
|
||||
* \brief Retrieves an event from the span
|
||||
*
|
||||
* \note
|
||||
* This function is non-reentrant and not thread-safe.
|
||||
* The event returned may be modified if the function is called again
|
||||
* from a different thread or even the same. It is recommended to
|
||||
* handle events from the same span in a single thread.
|
||||
*
|
||||
* \param ftdmchan The channel to retrieve the event from
|
||||
* \param event Pointer to store the pointer to the event
|
||||
*
|
||||
* \retval FTDM_SUCCESS success (at least one event available)
|
||||
* \retval FTDM_FAIL failure
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_read_event(ftdm_channel_t *ftdmchan, ftdm_event_t **event);
|
||||
|
||||
/*! \brief Find a hunt group by id */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_group_find(uint32_t id, ftdm_group_t **group);
|
||||
|
||||
|
|
|
@ -342,21 +342,24 @@ typedef enum {
|
|||
FTDM_TYPE_CHANNEL
|
||||
} ftdm_data_type_t;
|
||||
|
||||
#ifdef FTDM_DEBUG_DTMF
|
||||
/* number of bytes for the circular buffer (5 seconds worth of audio) */
|
||||
#define DTMF_DEBUG_SIZE 8 * 5000
|
||||
/* number of 20ms cycles before timeout and close the debug dtmf file (5 seconds) */
|
||||
#define DTMF_DEBUG_TIMEOUT 250
|
||||
/* number of bytes for the IO dump circular buffer (5 seconds worth of audio by default) */
|
||||
#define FTDM_IO_DUMP_DEFAULT_BUFF_SIZE 8 * 5000
|
||||
typedef struct {
|
||||
FILE *file;
|
||||
char buffer[DTMF_DEBUG_SIZE];
|
||||
char *buffer;
|
||||
ftdm_size_t size;
|
||||
int windex;
|
||||
int wrapped;
|
||||
int closetimeout;
|
||||
} ftdm_io_dump_t;
|
||||
|
||||
/* number of interval cycles before timeout and close the debug dtmf file (5 seconds if interval is 20) */
|
||||
#define DTMF_DEBUG_TIMEOUT 250
|
||||
typedef struct {
|
||||
uint8_t enabled;
|
||||
uint8_t requested;
|
||||
FILE *file;
|
||||
int32_t closetimeout;
|
||||
ftdm_mutex_t *mutex;
|
||||
} ftdm_dtmf_debug_t;
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
const char *file;
|
||||
|
@ -471,9 +474,9 @@ struct ftdm_channel {
|
|||
void *user_private;
|
||||
ftdm_timer_id_t hangup_timer;
|
||||
ftdm_channel_iostats_t iostats;
|
||||
#ifdef FTDM_DEBUG_DTMF
|
||||
ftdm_dtmf_debug_t dtmfdbg;
|
||||
#endif
|
||||
ftdm_io_dump_t rxdump;
|
||||
ftdm_io_dump_t txdump;
|
||||
};
|
||||
|
||||
struct ftdm_span {
|
||||
|
|
|
@ -58,6 +58,7 @@ typedef int ftdm_filehandle_t;
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define FTDM_COMMAND_OBJ_SIZE *((ftdm_size_t *)obj)
|
||||
#define FTDM_COMMAND_OBJ_INT *((int *)obj)
|
||||
#define FTDM_COMMAND_OBJ_CHAR_P (char *)obj
|
||||
#define FTDM_COMMAND_OBJ_FLOAT *(float *)obj
|
||||
|
|
|
@ -49,7 +49,9 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#ifdef __linux__
|
||||
#ifndef __USE_BSD
|
||||
#define __USE_BSD
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "freetdm.h"
|
||||
|
|
|
@ -878,6 +878,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_set_realm(switch_ivr_dmachin
|
|||
SWITCH_DECLARE(switch_status_t) switch_ivr_get_file_handle(switch_core_session_t *session, switch_file_handle_t **fh);
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_release_file_handle(switch_core_session_t *session, switch_file_handle_t **fh);
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_process_fh(switch_core_session_t *session, const char *cmd, switch_file_handle_t *fhp);
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_insert_file(switch_core_session_t *session, const char *file, const char *insert_file, switch_size_t sample_point);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
|
|
@ -495,7 +495,7 @@ switch_status_t callprogress_detector_stop(switch_core_session_t *session)
|
|||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_media_bug_t *bug = switch_channel_get_private(channel, TONE_PRIVATE);
|
||||
if (bug) {
|
||||
switch_core_media_bug_close(&bug);
|
||||
switch_core_media_bug_remove(session, &bug);
|
||||
switch_channel_set_private(channel, TONE_PRIVATE, NULL);
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
Adds an extra switch_rtp_destroy or switch_rtp_release_port when a session ends
|
||||
- to make sure the port is returned to FS. thx to Peter Olsson.
|
||||
fix issues with Progress message type if pre_answer enabled
|
||||
fix crashes on FSH323Connection calls in on_hangup routine in different threads.
|
||||
move PTrace level set to FSH323EndPoint::Initialise
|
||||
partially apply patch from from Peter Olsson, Remove UnLock() when TryLock() failed and DEBUG_RTP_PACKETS directive.
|
||||
|
|
|
@ -343,7 +343,7 @@ PString GetH245CodecName(const H323Capability* cap)
|
|||
}
|
||||
|
||||
FSProcess::FSProcess()
|
||||
: PLibraryProcess("Test", "mod_h323", 1, 0, AlphaCode, 1)
|
||||
: PLibraryProcess("FreeSWITCH", "mod_h323", 1, 0, AlphaCode, 1)
|
||||
, m_h323endpoint(NULL){
|
||||
}
|
||||
|
||||
|
@ -742,6 +742,14 @@ FSH323Connection::~FSH323Connection()
|
|||
switch_core_session_unlock_codec_write(m_fsSession);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"------------->switch_core_session_unlock_codec_write [%p]\n",m_fsSession);
|
||||
}
|
||||
|
||||
if (tech_pvt->rtp_session) {
|
||||
switch_rtp_destroy(&tech_pvt->rtp_session);
|
||||
tech_pvt->rtp_session = NULL;
|
||||
} else if (m_RTPlocalPort) {
|
||||
switch_rtp_release_port((const char *)m_RTPlocalIP.AsString(), m_RTPlocalPort);
|
||||
}
|
||||
|
||||
tech_pvt->me = NULL;
|
||||
// switch_mutex_unlock(tech_pvt->h323_mutex);
|
||||
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"------------->h323_mutex_unlock\n");
|
||||
|
@ -1148,7 +1156,7 @@ void FSH323Connection::AnsweringCall(AnswerCallResponse response)
|
|||
if (!mediaWaitForConnect) {
|
||||
// create a new facility PDU if doing AnswerDeferredWithMedia
|
||||
H323SignalPDU want245PDU;
|
||||
//H225_Progress_UUIE & prog = want245PDU.BuildProgress(*this);
|
||||
want245PDU.BuildProgress(*this);
|
||||
PBoolean sendPDU = TRUE;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,"mediaWaitForConnect = FALSE\n");
|
||||
/* if (SendFastStartAcknowledge(prog.m_fastStart)){
|
||||
|
|
|
@ -95,16 +95,6 @@ should be opened for the channel. Limited to 25ms min, 500ms max.
|
|||
<param name="r2-preconnect-wait" value="250"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Enable/disable native bridge mode (known in pt_BR as "trombone") for calls
|
||||
in the Khomp channel, passing the audio inside the board when both channels
|
||||
(incoming and outgoing) are of type Khomp. This reduces the echo and the
|
||||
audio delay, and frees the host from most audio processing.
|
||||
(default = yes)
|
||||
|
||||
<param name="native-bridge" value="yes"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Defines the incoming context for calls on E1 channels. Some wildcards are
|
||||
accepted, and described in the bottom of this file.
|
||||
|
@ -239,48 +229,30 @@ is enabled on the board configuration. Possible values:
|
|||
<param name="input-volume" value="0"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Sets the default AMA flags, affecting the categorization of entries in
|
||||
the call detail records.
|
||||
(default = default)
|
||||
|
||||
<param name="amaflags" value="default"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Sets the account code for calls placed on the channel. The account code may
|
||||
be any alphanumeric string
|
||||
(default = KhompBoard)
|
||||
default = <empty>)
|
||||
|
||||
<param name="accountcode" value="KhompBoard"/>
|
||||
<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"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Set the music on hold class of the channel (useful for selecting a group of
|
||||
songs to play on hold).
|
||||
(default = default)
|
||||
|
||||
<param name="mohclass" value="default"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
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.
|
||||
|
||||
For more example of how to use this option, see channel README file,
|
||||
section 'Opcoes do application Bridge', item '<action application="bridge" data="Khomp/r304" />'.
|
||||
(default = 0)
|
||||
|
||||
<param name="fxs-global-orig" value="0200"/>
|
||||
<param name="fxs-global-orig" value="0"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
|
@ -300,14 +272,6 @@ a FXS branch.
|
|||
<param name="fxs-bina" value="yes"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Enable/disable using CTbus for Khomp CTI boards in native bridge.
|
||||
(WARNING: just used for internal testings!)
|
||||
(default = no)
|
||||
|
||||
<param name="has-ctbus" value="no"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
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
|
||||
|
@ -337,18 +301,6 @@ not have any tone. Values are in milliseconds.
|
|||
<param name="delay-ringback-pbx" value="2500"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Defines if the channel should optimize audio delay by droping longstanding
|
||||
packets from audio buffer. This guarantees the minimal audio delay for the
|
||||
user, and avoid delays associated with miscoded SIP clients. However,
|
||||
depending on the system's scheduling policy (some 2.6 kernel releases),
|
||||
this may result on excessive drop of packets, and audible audio skipping.
|
||||
This should not be changed naively.
|
||||
(default = no)
|
||||
|
||||
<param name="optimize-audio-path" value="no"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
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
|
||||
|
@ -526,9 +478,8 @@ 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,
|
||||
mohclass, amaflags, accountcode, calleridnum,
|
||||
calleridname, mailbox, flash-to-digits.
|
||||
context, input-volume, output-volume, language,
|
||||
accountcode, calleridnum, calleridname, flash-to-digits.
|
||||
-->
|
||||
</fxs-options>
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
MODNAME := mod_khomp
|
||||
VERBOSE := 1
|
||||
|
||||
#FreeSWITCH source PATH is needed:
|
||||
# Set FREESWITCH_PATH
|
||||
|
||||
ifeq ($(strip $(FREESWITCH_PATH)),)
|
||||
BASE := ../../../../
|
||||
else
|
||||
|
@ -11,12 +14,12 @@ curr_dir := $(shell pwd)
|
|||
|
||||
versions := -DFS_VERSION_MAJOR=$(shell bash $(curr_dir)/tools/getversion.sh "SWITCH_VERSION_MAJOR" $(BASE)) -DFS_VERSION_MINOR=$(shell bash $(curr_dir)/tools/getversion.sh "SWITCH_VERSION_MINOR" $(BASE)) -DFS_VERSION_MICRO=$(shell bash $(curr_dir)/tools/getversion.sh "SWITCH_VERSION_MICRO" $(BASE))
|
||||
|
||||
LOCAL_CFLAGS = -I./ -I./include -I./commons -I./support -D_REENTRANT -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DK3L_HOSTSYSTEM -DCOMMONS_LIBRARY_USING_FREESWITCH -g -ggdb #-DDEBUG_FLAGS
|
||||
LOCAL_CFLAGS = -I./ -I./include -I./commons -I./commons/base -I./support -D_REENTRANT -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DK3L_HOSTSYSTEM -DCOMMONS_LIBRARY_USING_FREESWITCH -g -ggdb #-DDEBUG_FLAGS
|
||||
LOCAL_CFLAGS += $(versions)
|
||||
|
||||
LOCAL_LDFLAGS = -lk3l
|
||||
|
||||
LOCAL_OBJS = ./commons/k3lapi.o ./commons/k3lutil.o ./commons/config_options.o ./commons/format.o ./commons/strings.o ./commons/ringbuffer.o ./commons/verbose.o ./commons/saved_condition.o ./commons/regex.o ./commons/timer.o ./commons/configurator/configfile.o ./commons/configurator/option.o ./commons/configurator/section.o ./commons/configurator/restriction.o
|
||||
LOCAL_OBJS = ./commons/base/k3lapi.o ./commons/base/k3lutil.o ./commons/base/config_options.o ./commons/base/format.o ./commons/base/strings.o ./commons/base/ringbuffer.o ./commons/base/verbose.o ./commons/base/saved_condition.o ./commons/base/regex.o ./commons/base/timer.o ./commons/base/configurator/configfile.o ./commons/base/configurator/option.o ./commons/base/configurator/section.o ./commons/base/configurator/restriction.o ./commons/base/verbose_traits.o
|
||||
LOCAL_OBJS += ./support/klog-config.o ./support/klog-options.o ./support/config_defaults.o
|
||||
LOCAL_OBJS += ./src/globals.o ./src/opt.o ./src/frame.o ./src/utils.o ./src/lock.o ./src/spec.o ./src/applications.o ./src/khomp_pvt_fxo.o ./src/khomp_pvt_gsm.o ./src/khomp_pvt_kxe1.o ./src/khomp_pvt_passive.o ./src/khomp_pvt.o ./src/logger.o ./src/cli.o
|
||||
|
||||
|
@ -27,7 +30,20 @@ conf_file_install = $(sysconfdir)/autoload_configs
|
|||
|
||||
include $(BASE)/build/modmake.rules
|
||||
|
||||
local_depend:
|
||||
@if test ! -f $(curr_dir)/commons/base/verbose_traits.hpp || test ! -f $(curr_dir)/commons/base/verbose_traits.cpp ; then \
|
||||
echo "Generating verbose_traits" ;\
|
||||
bash $(curr_dir)/commons/tools/generate-verbose-headers.sh commons/base/ include/k3l.h ;\
|
||||
fi;
|
||||
|
||||
depend_install:
|
||||
@if test "w`kserver --version 2>/dev/null | grep 2.1`" == "w" ; then \
|
||||
echo "###############################################################################" ;\
|
||||
echo "Install k3l from KHOMP." ;\
|
||||
echo "Run: $(curr_dir)/tools/getk3l.sh" ;\
|
||||
echo "###############################################################################" ;\
|
||||
exit 1;\
|
||||
fi;
|
||||
@echo "Copy $(conf_file_name)"
|
||||
@if test -d $(conf_file_install) ; then \
|
||||
if test -f $(conf_file_dir)/$(conf_file_name) ; then \
|
||||
|
|
|
@ -64,17 +64,31 @@ namespace Atomic
|
|||
PunnedType pval; pval.valtype = VAL; \
|
||||
unsigned long long vexp = *(pexp.podtype); \
|
||||
unsigned long long vval = *(pval.podtype); \
|
||||
unsigned long long res = (unsigned long long)exp; \
|
||||
unsigned long vval32 = (unsigned long)vval; \
|
||||
unsigned char chg = 0; \
|
||||
asm volatile("lock; cmpxchg8b %2; sete %1;" \
|
||||
asm volatile( \
|
||||
"xchgl %%ebx, %4;" \
|
||||
"lock; cmpxchg8b %2; sete %1;" \
|
||||
"movl %4, %%ebx; " \
|
||||
: "+A" (vexp), /* 0 (result) */ \
|
||||
"=q" (chg) /* 1 */ \
|
||||
"=c" (chg) /* 1 */ \
|
||||
: "m" (*(unsigned char**)(PTR)), /* 2 */ \
|
||||
"b" ((unsigned long)(vval)), \
|
||||
"c" ((unsigned long)(vval >> 32))); \
|
||||
"c" ((unsigned long)(vval >> 32)), \
|
||||
"m" (vval32)); \
|
||||
*(pexp.podtype) = vexp; \
|
||||
return (chg != 0 ? true : false);
|
||||
|
||||
// "movl %%ecx, %4;"
|
||||
//
|
||||
// "m" (*((unsigned long*)(*(pval.podtype)))),
|
||||
// "m" ((unsigned long)(vval >> 32))
|
||||
//
|
||||
// "m" (*((unsigned long*)(&vval))),
|
||||
// "m" ((unsigned long)(vval >> 32))
|
||||
//
|
||||
// unsigned long long vval = *(pval.podtype);
|
||||
// unsigned long long res = (unsigned long long)exp;
|
||||
//
|
||||
// Types used for making CMPXCHG instructions independent from base type.
|
||||
|
||||
template < typename ValType, typename PodType >
|
|
@ -63,7 +63,12 @@
|
|||
#error Unknown implementation selected. Please define COMMONS_LIBRARY_USING_* correctly.
|
||||
#endif
|
||||
|
||||
#define COMMONS_INCLUDE(file) <COMMONS_IMPLEMENTATION/file>
|
||||
#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_ */
|
||||
|
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
KHOMP generic endpoint/channel library.
|
||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
(the "License"); you may not use this file except in compliance with the
|
||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||||
the specific language governing rights and limitations under the License.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
||||
case the provisions of "LGPL License" are applicable instead of those above.
|
||||
|
||||
If you wish to allow use of your version of this file only under the terms of
|
||||
the LGPL License and not to allow others to use your version of this file under
|
||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
||||
with the notice and other provisions required by the LGPL License. If you do not
|
||||
delete the provisions above, a recipient may use your version of this file under
|
||||
either the MPL or the LGPL License.
|
||||
|
||||
The LGPL header follows below:
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <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;
|
||||
}
|
|
@ -0,0 +1,772 @@
|
|||
/*
|
||||
KHOMP generic endpoint/channel library.
|
||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
(the "License"); you may not use this file except in compliance with the
|
||||
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||||
the specific language governing rights and limitations under the License.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
"GNU Lesser General Public License 2.1" license (the “LGPL" License), in which
|
||||
case the provisions of "LGPL License" are applicable instead of those above.
|
||||
|
||||
If you wish to allow use of your version of this file only under the terms of
|
||||
the LGPL License and not to allow others to use your version of this file under
|
||||
the MPL, indicate your decision by deleting the provisions above and replace them
|
||||
with the notice and other provisions required by the LGPL License. If you do not
|
||||
delete the provisions above, a recipient may use your version of this file under
|
||||
either the MPL or the LGPL License.
|
||||
|
||||
The LGPL header follows below:
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_OPTIONS_HPP_
|
||||
#define _CONFIG_OPTIONS_HPP_
|
||||
|
||||
#include <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)
|
||||
{
|
||||
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, 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_ */
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
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,7 +1,7 @@
|
|||
/*
|
||||
/*
|
||||
KHOMP generic endpoint/channel library.
|
||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
||||
|
||||
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/
|
||||
|
@ -23,20 +23,20 @@
|
|||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
@ -53,38 +53,38 @@
|
|||
|
||||
struct Configfile: public Section
|
||||
{
|
||||
typedef std::list < std::string > ErrorVector;
|
||||
typedef std::set < std::string > NameSet;
|
||||
typedef std::list < std::string > ErrorVector;
|
||||
typedef std::set < std::string > NameSet;
|
||||
|
||||
Configfile(std::string name, std::string desc)
|
||||
: Section(name, desc), _good(false) {};
|
||||
Configfile(const std::string & name, const std::string & desc)
|
||||
: Section(name, desc), _good(false) {};
|
||||
|
||||
virtual ~Configfile() {};
|
||||
virtual ~Configfile() {};
|
||||
|
||||
bool good() { return _good; };
|
||||
std::string & filename() { return _filename; };
|
||||
bool good() const { return _good; };
|
||||
const std::string & filename() const { return _filename; };
|
||||
|
||||
ErrorVector & errors() { return _errors; };
|
||||
const ErrorVector & errors() const { return _errors; };
|
||||
|
||||
void ignore(std::string);
|
||||
void ignore(const std::string &);
|
||||
|
||||
virtual bool obtain();
|
||||
virtual bool provide();
|
||||
virtual bool obtain();
|
||||
virtual bool provide();
|
||||
|
||||
protected:
|
||||
virtual bool select(Section **, std::string str = "");
|
||||
virtual bool adjust(Section *, std::string & opt, std::string & val);
|
||||
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 &);
|
||||
virtual bool deserialize(std::ifstream &);
|
||||
virtual bool serialize(std::ofstream &);
|
||||
|
||||
void recurse(std::ofstream &, Section *);
|
||||
void recurse(std::ofstream &, Section *);
|
||||
|
||||
protected:
|
||||
bool _good;
|
||||
ErrorVector _errors;
|
||||
NameSet _ignores;
|
||||
std::string _filename;
|
||||
bool _good;
|
||||
ErrorVector _errors;
|
||||
NameSet _ignores;
|
||||
std::string _filename;
|
||||
};
|
||||
|
||||
#endif /* _CONFIG_CONFIGFILE_HPP_ */
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
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,7 +1,7 @@
|
|||
/*
|
||||
/*
|
||||
KHOMP generic endpoint/channel library.
|
||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
||||
|
||||
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/
|
||||
|
@ -23,20 +23,20 @@
|
|||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
@ -45,6 +45,7 @@
|
|||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include <format.hpp>
|
||||
#include <strings.hpp>
|
||||
|
||||
#include <configurator/restriction.hpp>
|
||||
|
@ -56,67 +57,72 @@ struct Option
|
|||
{
|
||||
enum FlagTypes
|
||||
{
|
||||
F_MODIFIED = 0x0, /* if option was modified */
|
||||
F_ADJUSTED = 0x1, /* if option was correctly formated */
|
||||
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) {};
|
||||
};
|
||||
struct Flags: public std::vector<bool>
|
||||
{
|
||||
Flags(): std::vector<bool>(2) {};
|
||||
};
|
||||
|
||||
typedef Restriction::Value Value;
|
||||
typedef Restriction::Vector Vector;
|
||||
typedef Restriction::Value Value;
|
||||
typedef Restriction::Vector Vector;
|
||||
|
||||
/* exception */
|
||||
struct InvalidDefaultValue
|
||||
struct InvalidDefaultValue: public std::runtime_error
|
||||
{
|
||||
InvalidDefaultValue(std::string name, std::string value)
|
||||
: _name(name), _value(value) {};
|
||||
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)
|
||||
{};
|
||||
|
||||
std::string & name() { return _name; };
|
||||
std::string & value() { return _value; };
|
||||
~InvalidDefaultValue() throw ()
|
||||
{};
|
||||
|
||||
const std::string & name() const { return _name; };
|
||||
const std::string & value() const { return _value; };
|
||||
|
||||
protected:
|
||||
std::string _name;
|
||||
std::string _value;
|
||||
const std::string _name;
|
||||
const std::string _value;
|
||||
};
|
||||
|
||||
Option(std::string name, std::string desc, std::string defvalue, Restriction restriction)
|
||||
: _name(name), _desc(desc), _restriction(restriction), _modified(true)
|
||||
{
|
||||
std::string value(defvalue);
|
||||
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(value)[F_ADJUSTED]))
|
||||
if (!(set(defvalue)[F_ADJUSTED]))
|
||||
throw InvalidDefaultValue(name, defvalue);
|
||||
}
|
||||
}
|
||||
|
||||
const std::string & name() { return _name; };
|
||||
const std::string & description() { return _desc; };
|
||||
const std::string & name() const { return _name; };
|
||||
const std::string & description() const { return _description; };
|
||||
|
||||
Restriction & restriction() { return _restriction; };
|
||||
bool modified() { return _modified; };
|
||||
const Restriction & restriction() const { return _restriction; };
|
||||
bool modified() const { return _modified; };
|
||||
|
||||
public:
|
||||
bool load(std::string &);
|
||||
bool change(std::string &);
|
||||
bool store(std::string &);
|
||||
bool load(const std::string &);
|
||||
bool change(const std::string &);
|
||||
bool store(std::string &) const;
|
||||
|
||||
Flags set(const char *);
|
||||
Flags set(Value &);
|
||||
Flags set(Vector &);
|
||||
// Flags set(const char *);
|
||||
Flags set(const Value &);
|
||||
Flags set(const Vector &);
|
||||
|
||||
bool get(Value &);
|
||||
bool get(Vector &);
|
||||
bool get(Value &) const;
|
||||
bool get(Vector &) const;
|
||||
|
||||
bool equals(std::string &);
|
||||
bool equals(const std::string &) const;
|
||||
|
||||
protected:
|
||||
std::string _name;
|
||||
std::string _desc;
|
||||
const std::string _name;
|
||||
const std::string _description;
|
||||
|
||||
Restriction _restriction;
|
||||
bool _modified;
|
||||
Restriction _restriction;
|
||||
bool _modified;
|
||||
};
|
||||
|
||||
#endif /* _CONFIG_OPTION_HPP_ */
|
|
@ -0,0 +1,358 @@
|
|||
/*
|
||||
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();
|
||||
}
|
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
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,7 +1,7 @@
|
|||
/*
|
||||
/*
|
||||
KHOMP generic endpoint/channel library.
|
||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
||||
|
||||
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/
|
||||
|
@ -23,108 +23,114 @@
|
|||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <configurator/section.hpp>
|
||||
|
||||
void Section::options(Section::OptionVector & vec)
|
||||
void Section::options(Section::OptionVector & vec) const
|
||||
{
|
||||
for (OptionMap::iterator it = _options.begin(); it != _options.end();)
|
||||
{
|
||||
vec.push_back(&((*it).second));
|
||||
++it;
|
||||
}
|
||||
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)
|
||||
void Section::sections(Section::SectionVector & vec) const
|
||||
{
|
||||
for (SectionMap::iterator it = _sections.begin(); it != _sections.end();)
|
||||
{
|
||||
vec.push_back((*it).second);
|
||||
++it;
|
||||
}
|
||||
for (SectionMap::const_iterator it = _sections.begin(); it != _sections.end();)
|
||||
{
|
||||
vec.push_back(const_cast< Section * >(it->second));
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
/*********/
|
||||
|
||||
Option * Section::option_find(std::string & str, bool recurse)
|
||||
Option * Section::option_find(const std::string & str, bool recurse) const
|
||||
{
|
||||
OptionMap::iterator i = _options.find(str);
|
||||
OptionMap::const_iterator i = _options.find(str);
|
||||
|
||||
if (i == _options.end())
|
||||
if (i == _options.end())
|
||||
{
|
||||
if (!recurse)
|
||||
throw not_found();
|
||||
throw OptionNotFound(str, _name);
|
||||
// throw not_found();
|
||||
|
||||
for (SectionMap::iterator i = _sections.begin(); i != _sections.end(); i++)
|
||||
for (SectionMap::const_iterator i = _sections.begin(); i != _sections.end(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
return i->second->option_find(str, recurse);
|
||||
}
|
||||
catch (not_found & e)
|
||||
catch (NotFound & e)
|
||||
{
|
||||
/* keep looping! */
|
||||
};
|
||||
}
|
||||
|
||||
throw not_found();
|
||||
// throw not_found();
|
||||
throw OptionNotFound(str, _name);
|
||||
}
|
||||
|
||||
return &((*i).second);
|
||||
return const_cast< Option * >(&(i->second));
|
||||
}
|
||||
|
||||
/*
|
||||
Option * Section::option_find(const char * str, bool recurse)
|
||||
{
|
||||
std::string sstr(str);
|
||||
return option_find(sstr, recurse);
|
||||
std::string sstr(str);
|
||||
return option_find(sstr, recurse);
|
||||
}
|
||||
*/
|
||||
|
||||
/*********/
|
||||
|
||||
Section * Section::section_find(std::string & str, bool recurse)
|
||||
Section * Section::section_find(const std::string & str, bool recurse) const
|
||||
{
|
||||
SectionMap::iterator i = _sections.find(str);
|
||||
SectionMap::const_iterator i = _sections.find(str);
|
||||
|
||||
if (i == _sections.end())
|
||||
if (i == _sections.end())
|
||||
{
|
||||
if (!recurse)
|
||||
throw not_found();
|
||||
throw SectionNotFound(str, _name);
|
||||
|
||||
for (SectionMap::iterator i = _sections.begin(); i != _sections.end(); i++)
|
||||
for (SectionMap::const_iterator i = _sections.begin(); i != _sections.end(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
return i->second->section_find(str, recurse);
|
||||
}
|
||||
catch (not_found & e)
|
||||
catch (NotFound & e)
|
||||
{
|
||||
/* keep looping! */
|
||||
};
|
||||
}
|
||||
|
||||
throw not_found();
|
||||
throw SectionNotFound(str, _name);
|
||||
}
|
||||
|
||||
return ((*i).second);
|
||||
return const_cast< Section * >(i->second);
|
||||
}
|
||||
|
||||
/*
|
||||
Section * Section::section_find(const char * str, bool recurse)
|
||||
{
|
||||
std::string sstr(str);
|
||||
return section_find(sstr, recurse);
|
||||
std::string sstr(str);
|
||||
return section_find(sstr, recurse);
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
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_ */
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
#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_ */
|
|
@ -42,27 +42,7 @@
|
|||
#include "format.hpp"
|
||||
//#include <iostream>
|
||||
|
||||
Format::Format(const char * format_string, bool raise_exception)
|
||||
: _format(format_string), _valid(true), _raise(raise_exception)
|
||||
{
|
||||
initialize(format_string);
|
||||
}
|
||||
|
||||
/*
|
||||
Format::Format(std::string & format_string, bool raise_exception)
|
||||
: _format(NULL), _valid(true), _raise(raise_exception)
|
||||
{
|
||||
initialize(format_string.c_str());
|
||||
}
|
||||
*/
|
||||
|
||||
Format::Format(std::string format_string, bool raise_exception)
|
||||
: _format(format_string), _valid(true), _raise(raise_exception)
|
||||
{
|
||||
initialize(format_string.c_str());
|
||||
}
|
||||
|
||||
void Format::initialize(const char * format_string)
|
||||
void FormatTraits::initialize(const char * format_string)
|
||||
{
|
||||
std::string txt;
|
||||
|
||||
|
@ -82,7 +62,6 @@ void Format::initialize(const char * format_string)
|
|||
if (*ptr2 == '%')
|
||||
{
|
||||
txt += *ptr;
|
||||
|
||||
ptr += 2;
|
||||
continue;
|
||||
}
|
||||
|
@ -238,36 +217,20 @@ void Format::initialize(const char * format_string)
|
|||
push_argument(txt, T_LITERAL);
|
||||
}
|
||||
|
||||
void Format::mark_invalid(std::string & msg)
|
||||
void FormatTraits::push_argument(std::string & data, FormatTraits::Type type)
|
||||
{
|
||||
if (_valid)
|
||||
{
|
||||
_valid = false;
|
||||
// std::cerr << "pushing type (" << type << ") with format (" << data << ")" << std::endl;
|
||||
|
||||
std::string finalmsg;
|
||||
|
||||
finalmsg += "** INVALID FORMAT: ";
|
||||
finalmsg += msg;
|
||||
finalmsg += " **";
|
||||
|
||||
_result = finalmsg;
|
||||
}
|
||||
_args.push(Argument(data, type));
|
||||
data.clear();
|
||||
}
|
||||
|
||||
void Format::raise_check(void)
|
||||
void FormatTraits::pop_argument(void)
|
||||
{
|
||||
if (!_valid && _raise)
|
||||
throw InvalidFormat(_result);
|
||||
_args.pop();
|
||||
}
|
||||
|
||||
bool Format::validity_check(void)
|
||||
{
|
||||
raise_check();
|
||||
|
||||
return _valid;
|
||||
}
|
||||
|
||||
const Format::Argument * Format::next_argument(void)
|
||||
const FormatTraits::Argument * FormatTraits::next_argument(void)
|
||||
{
|
||||
// std::cerr << "size: " << _args.size() << std::endl;
|
||||
|
||||
|
@ -294,38 +257,81 @@ const Format::Argument * Format::next_argument(void)
|
|||
}
|
||||
}
|
||||
|
||||
void Format::pop_argument(void)
|
||||
/******************************************************************/
|
||||
|
||||
#if 0
|
||||
Format::Format(const char * format_string, bool raise_exception)
|
||||
: _format(format_string), _valid(true), _raise(raise_exception)
|
||||
{
|
||||
_args.pop();
|
||||
FormatTraits::initialize(format_string);
|
||||
}
|
||||
|
||||
void Format::push_argument(std::string & data, Format::Type type)
|
||||
Format::Format(std::string format_string, bool raise_exception)
|
||||
: _format(format_string), _valid(true), _raise(raise_exception)
|
||||
{
|
||||
// std::cerr << "pushing type (" << type << ") with format (" << data << ")" << std::endl;
|
||||
FormatTraits::initialize(format_string.c_str());
|
||||
}
|
||||
|
||||
_args.push(Argument(data, type));
|
||||
data.clear();
|
||||
/*
|
||||
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 (!validity_check())
|
||||
if (!valid())
|
||||
return _result;
|
||||
|
||||
if (next_argument() == NULL)
|
||||
// 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;
|
||||
|
||||
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
|
|
@ -52,37 +52,35 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#ifdef WIN32 // WINDOWS
|
||||
#include <KHostSystem.h>
|
||||
# include <KHostSystem.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* macros used for shortening lines and making the code clearer */
|
||||
#define STG(x) (x).str()
|
||||
#define FMT(x) Format(x)
|
||||
|
||||
struct Format
|
||||
struct InvalidFormat
|
||||
{
|
||||
static const unsigned int strings_base_length = 64;
|
||||
static const unsigned int generic_base_length = 64;
|
||||
InvalidFormat(std::string _msg) : msg(_msg) {}
|
||||
const std::string msg;
|
||||
};
|
||||
|
||||
struct InvalidFormat
|
||||
template < bool E >
|
||||
struct FormatException
|
||||
{
|
||||
void raise(const std::string & msg) const
|
||||
{
|
||||
InvalidFormat(std::string msg) : _msg(msg) {}
|
||||
|
||||
std::string _msg;
|
||||
/* DO NOTHING */
|
||||
};
|
||||
};
|
||||
|
||||
explicit Format(const char * format_string, bool raise_exception = false);
|
||||
explicit Format(std::string format_string, bool raise_exception = false);
|
||||
|
||||
void initialize(const char *);
|
||||
|
||||
std::string str(void);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
protected:
|
||||
template < >
|
||||
struct FormatException < true >
|
||||
{
|
||||
void raise(const std::string & msg) const
|
||||
{
|
||||
throw InvalidFormat(msg);
|
||||
};
|
||||
};
|
||||
|
||||
struct FormatTraits
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
T_ANYTHING = 1,
|
||||
|
@ -113,24 +111,240 @@ struct Format
|
|||
Argument(std::string fmts, Type type)
|
||||
: _fmts(fmts), _type(type) {};
|
||||
|
||||
Type type(void) const { return _type; }
|
||||
const Type type(void) const { return _type; }
|
||||
const std::string & fmts(void) const { return _fmts; }
|
||||
|
||||
protected:
|
||||
std::string _fmts;
|
||||
Type _type;
|
||||
const std::string _fmts;
|
||||
const Type _type;
|
||||
};
|
||||
|
||||
typedef std::queue < Argument > ArgumentQueue;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
public:
|
||||
//////////////////////////////////
|
||||
|
||||
template < typename V >
|
||||
Format & operator%( V value )
|
||||
bool number_verify_signed_short( V value ) const
|
||||
{
|
||||
if (!validity_check())
|
||||
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();
|
||||
|
@ -149,7 +363,7 @@ struct Format
|
|||
{
|
||||
char temp[generic_base_length];
|
||||
|
||||
if (!generic_verify(value, top->type()))
|
||||
if (!FormatTraits::generic_verify(value, top->type()))
|
||||
{
|
||||
std::string msg;
|
||||
|
||||
|
@ -171,14 +385,14 @@ struct Format
|
|||
pop_argument();
|
||||
}
|
||||
|
||||
raise_check();
|
||||
raise();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template < typename V >
|
||||
Format & operator%( V * value )
|
||||
FormatBase & operator%( V * value )
|
||||
{
|
||||
if (!validity_check())
|
||||
if (!valid())
|
||||
return *this;
|
||||
|
||||
const Argument * top = next_argument();
|
||||
|
@ -256,20 +470,13 @@ struct Format
|
|||
pop_argument();
|
||||
}
|
||||
|
||||
raise_check();
|
||||
raise();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
Format & operator%( std::string value )
|
||||
FormatBase & operator%( const std::string value )
|
||||
{
|
||||
return operator%(value);
|
||||
}
|
||||
*/
|
||||
|
||||
Format & operator%( const std::string value )
|
||||
{
|
||||
if (!validity_check())
|
||||
if (!valid())
|
||||
return *this;
|
||||
|
||||
const Argument * top = next_argument();
|
||||
|
@ -313,200 +520,42 @@ struct Format
|
|||
pop_argument();
|
||||
}
|
||||
|
||||
raise_check();
|
||||
raise();
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
template < typename V >
|
||||
bool number_verify_signed_short( V value )
|
||||
protected:
|
||||
void mark_invalid(std::string & msg)
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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, Type type )
|
||||
{
|
||||
switch (type)
|
||||
if (_valid)
|
||||
{
|
||||
/* 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));
|
||||
_valid = false;
|
||||
|
||||
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;
|
||||
_result = "** INVALID FORMAT: ";
|
||||
_result += msg;
|
||||
_result += " **";
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
void mark_invalid(std::string &);
|
||||
|
||||
bool validity_check(void);
|
||||
void raise_check(void);
|
||||
|
||||
/*
|
||||
struct NoArgumentLeft
|
||||
void raise(void) const
|
||||
{
|
||||
NoArgumentLeft(): empty(0) {};
|
||||
|
||||
unsigned int empty;
|
||||
};
|
||||
*/
|
||||
|
||||
const Argument * next_argument(void);
|
||||
|
||||
void pop_argument(void);
|
||||
void push_argument(std::string & data, Type type);
|
||||
if (!_valid)
|
||||
{
|
||||
// call specialized class
|
||||
FormatException< E >::raise(_result);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::string _format;
|
||||
|
||||
bool _valid;
|
||||
bool _raise;
|
||||
|
||||
std::string _result;
|
||||
ArgumentQueue _args;
|
||||
const std::string _format;
|
||||
bool _valid;
|
||||
};
|
||||
|
||||
#endif /* _FORMAT_H_ */
|
||||
/* 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_ */
|
|
@ -46,12 +46,13 @@
|
|||
|
||||
namespace Function
|
||||
{
|
||||
struct EmptyFunction {};
|
||||
struct EmptyFunction {};
|
||||
struct NonMemberFunction {};
|
||||
|
||||
/**/
|
||||
|
||||
template < typename FunctionTraits >
|
||||
struct StorageBase: NEW_REFCOUNTER(StorageBase < FunctionTraits >)
|
||||
struct StorageBase: COUNTER_SUPER(StorageBase < FunctionTraits >)
|
||||
{
|
||||
typedef typename FunctionTraits::BaseType BaseType;
|
||||
|
||||
|
@ -59,27 +60,33 @@ namespace Function
|
|||
typedef typename FunctionTraits::ObjType ObjType;
|
||||
|
||||
template < typename Functor >
|
||||
StorageBase(Functor f)
|
||||
: _object(reinterpret_cast<ObjType>(new Functor(f))),
|
||||
_function(reinterpret_cast<FunType>(&(Functor::operator()))),
|
||||
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()))),
|
||||
: _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)),
|
||||
: _object(reinterpret_cast< ObjType >(0)),
|
||||
_function(reinterpret_cast< FunType >(0)),
|
||||
_malloced(false)
|
||||
{};
|
||||
|
||||
StorageBase(const StorageBase & o)
|
||||
: INC_REFCOUNTER(o, StorageBase < FunctionTraits >),
|
||||
: COUNTER_REFER(o, StorageBase < FunctionTraits >),
|
||||
_object(o._object), _function(o._function), _malloced(o._malloced)
|
||||
{};
|
||||
|
||||
|
@ -95,9 +102,9 @@ namespace Function
|
|||
template < typename Functor >
|
||||
void operator=(Functor f)
|
||||
{
|
||||
_object = reinterpret_cast<ObjType>(new Functor(f)),
|
||||
_function = reinterpret_cast<FunType>(&(Functor::operator()));
|
||||
_malloced = false;
|
||||
_object = reinterpret_cast< ObjType >(new Functor(f)),
|
||||
_function = reinterpret_cast< FunType >(&Functor::operator());
|
||||
_malloced = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -229,10 +236,15 @@ namespace Function
|
|||
typedef StorageBase < Function0Traits < R > > Storage;
|
||||
|
||||
template < typename Functor >
|
||||
Function0(Functor f): Storage(f) {};
|
||||
Function0(const Functor f)
|
||||
: Storage(f) {};
|
||||
|
||||
template < typename Functor >
|
||||
Function0(Functor & f, bool m): Storage(f, m) {};
|
||||
Function0(Functor & f, bool m)
|
||||
: Storage(f, m) {};
|
||||
|
||||
Function0(const typename Function0Traits < R >::FunType * m)
|
||||
: Storage(m) {};
|
||||
|
||||
Function0() {};
|
||||
|
||||
|
@ -243,6 +255,18 @@ namespace Function
|
|||
|
||||
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 >
|
||||
|
@ -251,10 +275,15 @@ namespace Function
|
|||
typedef StorageBase < Function1Traits < R, A0 > > Storage;
|
||||
|
||||
template < typename Functor >
|
||||
Function1(Functor f): Storage(f) {};
|
||||
Function1(const Functor f)
|
||||
: Storage(f) {};
|
||||
|
||||
template < typename Functor >
|
||||
Function1(Functor & f, bool m): Storage(f, m) {};
|
||||
Function1(Functor & f, bool m)
|
||||
: Storage(f, m) {};
|
||||
|
||||
Function1(const typename Function1Traits < R, A0 >::FunType * m)
|
||||
: Storage(m) {};
|
||||
|
||||
Function1() {};
|
||||
|
||||
|
@ -265,6 +294,18 @@ namespace Function
|
|||
|
||||
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 >
|
||||
|
@ -273,10 +314,15 @@ namespace Function
|
|||
typedef StorageBase < Function2Traits < R, A0, A1 > > Storage;
|
||||
|
||||
template < typename Functor >
|
||||
Function2(Functor f): Storage(f) {};
|
||||
Function2(const Functor f)
|
||||
: Storage(f) {};
|
||||
|
||||
template < typename Functor >
|
||||
Function2(Functor & f, bool m): Storage(f, m) {};
|
||||
Function2(Functor & f, bool m)
|
||||
: Storage(f, m) {};
|
||||
|
||||
Function2(const typename Function2Traits < R, A0, A1 >::FunType * m)
|
||||
: Storage(m) {};
|
||||
|
||||
Function2() {};
|
||||
|
||||
|
@ -287,6 +333,18 @@ namespace Function
|
|||
|
||||
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 >
|
||||
|
@ -295,20 +353,37 @@ namespace Function
|
|||
typedef StorageBase < Function3Traits < R, A0, A1, A2 > > Storage;
|
||||
|
||||
template < typename Functor >
|
||||
Function3(Functor f): Storage(f) {};
|
||||
Function3(const Functor f)
|
||||
: Storage(f) {};
|
||||
|
||||
template < typename Functor >
|
||||
Function3(Functor & f, bool m): Storage(f, m) {};
|
||||
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<void *>(Storage::_object) == 0)
|
||||
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 >
|
||||
|
@ -317,10 +392,15 @@ namespace Function
|
|||
typedef StorageBase < Function4Traits < R, A0, A1, A2, A3 > > Storage;
|
||||
|
||||
template < typename Functor >
|
||||
Function4(Functor f): Storage(f) {};
|
||||
Function4(const Functor f)
|
||||
: Storage(f) {};
|
||||
|
||||
template < typename Functor >
|
||||
Function4(Functor & f, bool m): Storage(f, m) {};
|
||||
Function4(Functor & f, bool m)
|
||||
: Storage(f, m) {};
|
||||
|
||||
Function4(const typename Function4Traits < R, A0, A1, A2, A3 >::FunType * m)
|
||||
: Storage(m) {};
|
||||
|
||||
Function4() {};
|
||||
|
||||
|
@ -331,6 +411,18 @@ namespace Function
|
|||
|
||||
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);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
@ -47,32 +47,32 @@
|
|||
template < typename Type >
|
||||
struct Initializer: public std::vector< Type >
|
||||
{
|
||||
typedef std::vector< Type > super;
|
||||
typedef std::vector< Type > Super;
|
||||
|
||||
Initializer(Type e) { push_back(e); };
|
||||
Initializer(Type & e) { push_back(e); };
|
||||
Initializer(Type e) { Super::push_back(e); };
|
||||
Initializer(Type & e) { Super::push_back(e); };
|
||||
|
||||
Initializer & operator&(Initializer v)
|
||||
Initializer & operator&(const Initializer v)
|
||||
{
|
||||
insert(super::end(), v.begin(), v.end());
|
||||
Super::insert(Super::end(), v.begin(), v.end());
|
||||
return *this;
|
||||
};
|
||||
|
||||
Initializer & operator&(Initializer & v)
|
||||
{
|
||||
insert(super::end(), v.begin(), v.end());
|
||||
Super::insert(Super::end(), v.begin(), v.end());
|
||||
return *this;
|
||||
};
|
||||
|
||||
Initializer & operator&(Type v)
|
||||
{
|
||||
insert(super::end(), v);
|
||||
Super::insert(Super::end(), v);
|
||||
return *this;
|
||||
};
|
||||
|
||||
Initializer & operator&(Type & v)
|
||||
{
|
||||
insert(super::end(), v);
|
||||
Super::insert(Super::end(), v);
|
||||
return *this;
|
||||
};
|
||||
};
|
|
@ -41,18 +41,16 @@
|
|||
|
||||
#include <k3lapi.hpp>
|
||||
|
||||
#include <format.hpp>
|
||||
#include <verbose.hpp>
|
||||
#include <string.h>
|
||||
|
||||
K3LAPI::K3LAPI(bool has_exceptions)
|
||||
: _has_exceptions(has_exceptions),
|
||||
_device_count(0), _channel_count(0), _link_count(0),
|
||||
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 K3LAPI::start(void)
|
||||
void K3LAPIBase::start(void)
|
||||
{
|
||||
/* tie the used k3l to the compiled k3l version */
|
||||
char *ret = k3lStart(k3lApiMajorVersion, k3lApiMinorVersion, 0); //k3lApiBuildVersion);
|
||||
|
@ -64,7 +62,7 @@ void K3LAPI::start(void)
|
|||
init();
|
||||
}
|
||||
|
||||
void K3LAPI::stop(void)
|
||||
void K3LAPIBase::stop(void)
|
||||
{
|
||||
k3lStop();
|
||||
fini();
|
||||
|
@ -72,7 +70,7 @@ void K3LAPI::stop(void)
|
|||
|
||||
/* envio de comandos para placa */
|
||||
|
||||
void K3LAPI::mixer(int32 dev, int32 obj, byte track, KMixerSource src, int32 index)
|
||||
void K3LAPIBase::mixer(int32 dev, int32 obj, byte track, KMixerSource src, int32 index) const
|
||||
{
|
||||
KMixerCommand mix;
|
||||
|
||||
|
@ -83,7 +81,7 @@ void K3LAPI::mixer(int32 dev, int32 obj, byte track, KMixerSource src, int32 ind
|
|||
command(dev, obj, CM_MIXER, (const char *) &mix);
|
||||
}
|
||||
|
||||
void K3LAPI::mixerRecord(int32 dev, int32 obj, byte track, KMixerSource src, int32 index)
|
||||
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 };
|
||||
|
@ -131,12 +129,12 @@ void K3LAPI::mixerRecord(int32 dev, int32 obj, byte track, KMixerSource src, int
|
|||
break;
|
||||
}
|
||||
|
||||
int32 dsp = get_dsp(dev, DSP_AUDIO);
|
||||
int32 dsp = get_dsp(type, DSP_AUDIO);
|
||||
|
||||
raw_command(dev, dsp, cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
void K3LAPI::mixerCTbus(int32 dev, int32 obj, byte track, KMixerSource src, int32 index)
|
||||
void K3LAPIBase::mixerCTbus(int32 dev, int32 obj, byte track, KMixerSource src, int32 index) const
|
||||
{
|
||||
KMixerCommand mix;
|
||||
|
||||
|
@ -147,12 +145,12 @@ void K3LAPI::mixerCTbus(int32 dev, int32 obj, byte track, KMixerSource src, int3
|
|||
command(dev, obj, CM_MIXER_CTBUS, (const char *) &mix);
|
||||
}
|
||||
|
||||
void K3LAPI::command(int32 dev, int32 obj, int32 code, std::string & str)
|
||||
void K3LAPIBase::command(int32 dev, int32 obj, int32 code, std::string & str) const
|
||||
{
|
||||
command(dev, obj, code, str.c_str());
|
||||
}
|
||||
|
||||
void K3LAPI::command (int32 dev, int32 obj, int32 code, const char * parms)
|
||||
void K3LAPIBase::command (int32 dev, int32 obj, int32 code, const char * parms) const
|
||||
{
|
||||
K3L_COMMAND cmd;
|
||||
|
||||
|
@ -166,12 +164,12 @@ void K3LAPI::command (int32 dev, int32 obj, int32 code, const char * parms)
|
|||
throw failed_command(code, dev, obj, rc);
|
||||
}
|
||||
|
||||
void K3LAPI::raw_command(int32 dev, int32 dsp, std::string & str)
|
||||
void K3LAPIBase::raw_command(int32 dev, int32 dsp, std::string & str) const
|
||||
{
|
||||
raw_command(dev, dsp, str.data(), str.size());
|
||||
}
|
||||
|
||||
void K3LAPI::raw_command(int32 dev, int32 dsp, const char * cmds, int32 size)
|
||||
void K3LAPIBase::raw_command(int32 dev, int32 dsp, const char * cmds, int32 size) const
|
||||
{
|
||||
std::string str(cmds, size);
|
||||
|
||||
|
@ -181,7 +179,7 @@ void K3LAPI::raw_command(int32 dev, int32 dsp, const char * cmds, int32 size)
|
|||
throw failed_raw_command(dev, dsp, rc);
|
||||
}
|
||||
|
||||
KLibraryStatus K3LAPI::get_param(K3L_EVENT *ev, const char *name, std::string &res)
|
||||
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));
|
||||
|
@ -195,7 +193,7 @@ KLibraryStatus K3LAPI::get_param(K3L_EVENT *ev, const char *name, std::string &r
|
|||
return ksSuccess;
|
||||
}
|
||||
|
||||
std::string K3LAPI::get_param(K3L_EVENT *ev, const char *name)
|
||||
std::string K3LAPIBase::get_param(K3L_EVENT *ev, const char *name) const
|
||||
{
|
||||
std::string res;
|
||||
|
||||
|
@ -207,7 +205,7 @@ std::string K3LAPI::get_param(K3L_EVENT *ev, const char *name)
|
|||
return res;
|
||||
}
|
||||
|
||||
void K3LAPI::init(void)
|
||||
void K3LAPIBase::init(void)
|
||||
{
|
||||
if (_device_count != 0) return;
|
||||
|
||||
|
@ -217,20 +215,16 @@ void K3LAPI::init(void)
|
|||
_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];
|
||||
_channel_count = new unsigned int[_device_count];
|
||||
_link_count = new unsigned int[_device_count];
|
||||
|
||||
for (unsigned int dev = 0; dev < _device_count; dev++)
|
||||
{
|
||||
KLibraryStatus ret = ksSuccess;
|
||||
|
||||
_device_type[dev] = (KDeviceType) k3lGetDeviceType(dev);
|
||||
|
||||
/* caches each device config */
|
||||
ret = (KLibraryStatus)k3lGetDeviceConfig(dev, ksoDevice + dev, &(_device_config[dev]), sizeof(_device_config[dev]));
|
||||
|
||||
if (ret != ksSuccess)
|
||||
throw start_failed(STG(FMT("k3lGetDeviceConfig(dev=%d): %s") % dev % Verbose::status(ret)));
|
||||
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;
|
||||
|
@ -241,10 +235,9 @@ void K3LAPI::init(void)
|
|||
|
||||
for (unsigned int obj = 0; obj < _channel_count[dev]; obj++)
|
||||
{
|
||||
ret = (KLibraryStatus)k3lGetDeviceConfig(dev, ksoChannel + obj, &(_channel_config[dev][obj]), sizeof(_channel_config[dev][obj]));
|
||||
|
||||
if (ret != ksSuccess)
|
||||
throw start_failed(STG(FMT("k3lGetDeviceConfig(dev=%d,chan=%d): %s") % dev % obj % Verbose::status(ret)));
|
||||
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 */
|
||||
|
@ -255,15 +248,14 @@ void K3LAPI::init(void)
|
|||
|
||||
for (unsigned int obj = 0; obj < _link_count[dev]; obj++)
|
||||
{
|
||||
ret = (KLibraryStatus)k3lGetDeviceConfig(dev, ksoLink + obj, &(_link_config[dev][obj]), sizeof(_link_config[dev][obj]));
|
||||
|
||||
if (ret != ksSuccess)
|
||||
throw start_failed(STG(FMT("k3lGetDeviceConfig(dev=%d,link=%d): %s") % dev % obj % Verbose::status(ret)));
|
||||
if (k3lGetDeviceConfig(dev, ksoLink + obj, &(_link_config[dev][obj]),
|
||||
sizeof(_link_config[dev][obj])) != ksSuccess)
|
||||
throw start_failed("k3lGetDeviceConfig(link)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void K3LAPI::fini(void)
|
||||
void K3LAPIBase::fini(void)
|
||||
{
|
||||
for (unsigned int dev = 0; dev < _device_count; dev++)
|
||||
{
|
||||
|
@ -290,9 +282,9 @@ void K3LAPI::fini(void)
|
|||
if (_link_count) { delete[] _link_count; _link_count = NULL; }
|
||||
}
|
||||
|
||||
int32 K3LAPI::get_dsp(int32 dev, K3LAPI::DspType type)
|
||||
int32 K3LAPIBase::get_dsp(KDeviceType devtype, K3LAPI::DspType type) const
|
||||
{
|
||||
switch (device_type(dev))
|
||||
switch (devtype)
|
||||
{
|
||||
case kdtFXO:
|
||||
case kdtFXOVoIP:
|
||||
|
@ -311,3 +303,7 @@ int32 K3LAPI::get_dsp(int32 dev, K3LAPI::DspType type)
|
|||
}
|
||||
}
|
||||
|
||||
int32 K3LAPIBase::get_dsp(const K3LAPIBase::GenericTarget & tgt, K3LAPI::DspType type) const
|
||||
{
|
||||
return get_dsp(_device_type[tgt.device], type);
|
||||
}
|
|
@ -40,6 +40,9 @@
|
|||
*/
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <format.hpp>
|
||||
|
||||
#include <k3l.h>
|
||||
|
||||
|
@ -59,15 +62,110 @@
|
|||
#ifndef _K3LAPI_HPP_
|
||||
#define _K3LAPI_HPP_
|
||||
|
||||
struct K3LAPI
|
||||
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
|
||||
struct start_failed: public std::runtime_error
|
||||
{
|
||||
start_failed(const char * _msg) : msg(_msg) {};
|
||||
start_failed(std::string _msg) : msg(_msg) {};
|
||||
std::string msg;
|
||||
start_failed(const char * msg)
|
||||
: std::runtime_error(msg) {};
|
||||
};
|
||||
|
||||
struct failed_command
|
||||
|
@ -91,30 +189,6 @@ struct K3LAPI
|
|||
int32 rc;
|
||||
};
|
||||
|
||||
struct invalid_device
|
||||
{
|
||||
invalid_device(int32 _device)
|
||||
: device(_device) {};
|
||||
|
||||
int32 device;
|
||||
};
|
||||
|
||||
struct invalid_channel
|
||||
{
|
||||
invalid_channel(int32 _device, int32 _channel)
|
||||
: device(_device), channel(_channel) {};
|
||||
|
||||
int32 device, channel;
|
||||
};
|
||||
|
||||
struct invalid_link
|
||||
{
|
||||
invalid_link(unsigned int _device, unsigned int _link)
|
||||
: device(_device), link(_link) {};
|
||||
|
||||
int32 device, link;
|
||||
};
|
||||
|
||||
struct get_param_failed
|
||||
{
|
||||
get_param_failed(std::string _name, int32 _rc)
|
||||
|
@ -124,6 +198,8 @@ struct K3LAPI
|
|||
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;
|
||||
|
@ -132,8 +208,8 @@ struct K3LAPI
|
|||
|
||||
/* constructors/destructors */
|
||||
|
||||
K3LAPI(bool has_exceptions = false);
|
||||
virtual ~K3LAPI() {};
|
||||
K3LAPIBase();
|
||||
virtual ~K3LAPIBase() {};
|
||||
|
||||
/* (init|final)ialize the whole thing! */
|
||||
|
||||
|
@ -142,239 +218,106 @@ struct K3LAPI
|
|||
|
||||
/* verificacao de intervalos */
|
||||
|
||||
inline bool valid_device(int32 dev)
|
||||
inline bool valid_device(int32 dev) const
|
||||
{
|
||||
return (dev >= 0 && dev < ((int32)_device_count));
|
||||
}
|
||||
|
||||
inline bool valid_channel(int32 dev, int32 obj)
|
||||
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)
|
||||
inline bool valid_link(int32 dev, int32 obj) const
|
||||
{
|
||||
return (valid_device(dev) && obj >= 0 && obj < ((int32)_link_count[dev]));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief High level object identifier
|
||||
Since Khomp works with an object concept, this is used to map the
|
||||
object id with its proper type.
|
||||
*/
|
||||
struct target
|
||||
{
|
||||
/*! The types a target can have */
|
||||
typedef enum { DEVICE, CHANNEL, MIXER, LINK } target_type;
|
||||
|
||||
target(K3LAPI & k3lapi, target_type type_init, int32 device_value, int32 object_value)
|
||||
: type(type_init),
|
||||
device((unsigned short)device_value),
|
||||
object((unsigned short)object_value)
|
||||
{
|
||||
switch (type_init)
|
||||
{
|
||||
case DEVICE:
|
||||
if (!k3lapi.valid_device(device_value))
|
||||
throw invalid_device(device_value);
|
||||
break;
|
||||
|
||||
case CHANNEL:
|
||||
case MIXER:
|
||||
if (!k3lapi.valid_channel(device_value, object_value))
|
||||
throw invalid_channel(device_value, object_value);
|
||||
break;
|
||||
|
||||
case LINK:
|
||||
if (!k3lapi.valid_link(device_value, object_value))
|
||||
throw invalid_link(device_value, object_value);
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const target_type type;
|
||||
|
||||
const unsigned short device;
|
||||
const unsigned short object;
|
||||
};
|
||||
|
||||
/* envio de comandos para placa (geral) */
|
||||
|
||||
void raw_command(int32 dev, int32 dsp, std::string & str);
|
||||
void raw_command(int32 dev, int32 dsp, const char * cmds, int32 size);
|
||||
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)
|
||||
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);
|
||||
void mixerRecord(int32 dev, int32 obj, byte track, KMixerSource src, int32 index);
|
||||
void mixerCTbus(int32 dev, int32 obj, byte track, KMixerSource src, int32 index);
|
||||
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);
|
||||
void command (int32 dev, int32 obj, int32 code, const char * parms = NULL);
|
||||
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;
|
||||
|
||||
/* obter dados 'cacheados' (sem identificadores) */
|
||||
|
||||
inline unsigned int channel_count(int32 dev)
|
||||
{
|
||||
if (!valid_device(dev))
|
||||
{
|
||||
if (_has_exceptions)
|
||||
throw invalid_device(dev);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _channel_count[dev];
|
||||
}
|
||||
|
||||
inline unsigned int link_count(int32 dev)
|
||||
{
|
||||
if (!valid_device(dev))
|
||||
{
|
||||
if (_has_exceptions)
|
||||
throw invalid_device(dev);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _link_count[dev];
|
||||
}
|
||||
|
||||
inline uint32 channel_stats(int32 dev, int32 obj, uint32 index)
|
||||
{
|
||||
if (!valid_channel(dev, obj))
|
||||
{
|
||||
if (_has_exceptions)
|
||||
throw invalid_channel(dev, obj);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 res_value = (uint32)-1;
|
||||
stt_code stt_res = ksFail;
|
||||
|
||||
#if K3L_AT_LEAST(2,1,0)
|
||||
stt_res = k3lGetChannelStats(dev, obj, index, &res_value);
|
||||
#endif
|
||||
|
||||
if(stt_res != ksSuccess)
|
||||
{
|
||||
return (uint32)-1;
|
||||
}
|
||||
|
||||
return res_value;
|
||||
}
|
||||
|
||||
KDeviceType device_type(int32 dev)
|
||||
{
|
||||
if (!valid_device(dev))
|
||||
{
|
||||
if (_has_exceptions)
|
||||
throw invalid_device(dev);
|
||||
else
|
||||
return kdtDevTypeCount;
|
||||
}
|
||||
|
||||
return _device_type[dev];
|
||||
}
|
||||
|
||||
|
||||
K3L_DEVICE_CONFIG & device_config(int32 dev)
|
||||
{
|
||||
if (!valid_device(dev))
|
||||
throw invalid_device(dev);
|
||||
|
||||
return _device_config[dev];
|
||||
}
|
||||
|
||||
K3L_CHANNEL_CONFIG & channel_config(int32 dev, int32 obj)
|
||||
{
|
||||
if (!valid_channel(dev, obj))
|
||||
throw invalid_channel(dev, obj);
|
||||
|
||||
return _channel_config[dev][obj];
|
||||
}
|
||||
|
||||
K3L_LINK_CONFIG & link_config(int32 dev, int32 obj)
|
||||
{
|
||||
if (!valid_link(dev, obj))
|
||||
throw invalid_channel(dev, obj);
|
||||
|
||||
return _link_config[dev][obj];
|
||||
}
|
||||
|
||||
/* envio de comandos para placa (com identificadores) */
|
||||
|
||||
void mixer(target & tgt, byte track, KMixerSource src, int32 index)
|
||||
void mixer(const GenericTarget & tgt, byte track, KMixerSource src, int32 index) const
|
||||
{
|
||||
mixer((int32)tgt.device, (int32)tgt.object, track, src, index);
|
||||
mixer(tgt.device, tgt.object, track, src, index);
|
||||
}
|
||||
|
||||
void mixerRecord(target & tgt, byte track, KMixerSource src, int32 index)
|
||||
void mixerRecord(const GenericTarget & tgt, byte track, KMixerSource src, int32 index) const
|
||||
{
|
||||
mixerRecord((int32)tgt.device, (int32)tgt.object, track, src, index);
|
||||
mixerRecord((int32)tgt.device, _device_type[tgt.device], (int32)tgt.object, track, src, index);
|
||||
}
|
||||
|
||||
void mixerCTbus(target & tgt, byte track, KMixerSource src, int32 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 (target & tgt, int32 code, std::string & str)
|
||||
void command(const GenericTarget & tgt, int32 code, std::string & str) const
|
||||
{
|
||||
command((int32)tgt.device, (int32)tgt.object, code, str);
|
||||
};
|
||||
|
||||
void command (target & tgt, int32 code, const char * parms = NULL)
|
||||
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(target & tgt)
|
||||
inline unsigned int channel_count(const GenericTarget & tgt) const
|
||||
{
|
||||
return _channel_count[tgt.device];
|
||||
}
|
||||
|
||||
inline unsigned int link_count(target & tgt)
|
||||
inline unsigned int link_count(const GenericTarget & tgt) const
|
||||
{
|
||||
return _link_count[tgt.device];
|
||||
}
|
||||
|
||||
KDeviceType device_type(target & tgt)
|
||||
KDeviceType device_type(const GenericTarget & tgt) const
|
||||
{
|
||||
return _device_type[tgt.device];
|
||||
}
|
||||
|
||||
|
||||
K3L_DEVICE_CONFIG & device_config(target & tgt)
|
||||
const K3L_DEVICE_CONFIG & device_config(const GenericTarget & tgt) const
|
||||
{
|
||||
return _device_config[tgt.device];
|
||||
}
|
||||
|
||||
K3L_CHANNEL_CONFIG & channel_config(target & tgt)
|
||||
const K3L_CHANNEL_CONFIG & channel_config(const Target<GenericTarget::CHANNEL> & tgt) const
|
||||
{
|
||||
return _channel_config[tgt.device][tgt.object];
|
||||
}
|
||||
|
||||
K3L_LINK_CONFIG & link_config(target & tgt)
|
||||
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);
|
||||
std::string get_param(K3L_EVENT *ev, const char *name);
|
||||
KLibraryStatus get_param(K3L_EVENT *ev, const char *name, std::string &res) const;
|
||||
std::string get_param(K3L_EVENT *ev, const char *name) const;
|
||||
|
||||
/* inicializa valores em cache */
|
||||
|
||||
|
@ -389,12 +332,12 @@ struct K3LAPI
|
|||
DSP_SIGNALING,
|
||||
};
|
||||
|
||||
int32 get_dsp(int32, DspType);
|
||||
int32 get_dsp(KDeviceType, DspType) const;
|
||||
|
||||
int32 get_dsp(const GenericTarget &, DspType) const;
|
||||
|
||||
protected:
|
||||
|
||||
const bool _has_exceptions;
|
||||
|
||||
unsigned int _device_count;
|
||||
unsigned int * _channel_count;
|
||||
unsigned int * _link_count;
|
||||
|
@ -405,4 +348,145 @@ struct K3LAPI
|
|||
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_ */
|
|
@ -46,7 +46,8 @@ std::string K3LUtil::channelStatus(int32 dev, int32 channel,
|
|||
{
|
||||
try
|
||||
{
|
||||
K3L_CHANNEL_CONFIG & config = _k3lapi.channel_config(dev, channel);
|
||||
const K3L_CHANNEL_CONFIG & config = _k3lapi.channel_config(dev, channel);
|
||||
|
||||
K3L_CHANNEL_STATUS status;
|
||||
|
||||
KLibraryStatus ret = (KLibraryStatus) k3lGetDeviceStatus (dev,
|
||||
|
@ -60,7 +61,7 @@ std::string K3LUtil::channelStatus(int32 dev, int32 channel,
|
|||
: "Unknown (fail)");
|
||||
}
|
||||
}
|
||||
catch(K3LAPI::invalid_channel & e)
|
||||
catch(K3LAPITraits::invalid_channel & e)
|
||||
{
|
||||
return (fmt == Verbose::EXACT ? "<unknown[fail]>" : "Unknown (fail)");
|
||||
}
|
||||
|
@ -83,64 +84,35 @@ std::string K3LUtil::callStatus(int32 dev, int32 channel,
|
|||
}
|
||||
|
||||
std::string K3LUtil::linkStatus(int32 dev, int32 link,
|
||||
Verbose::Presentation fmt, KSignaling sig)
|
||||
Verbose::Presentation fmt, KSignaling signaling, bool simpleStatus)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (sig == ksigInactive)
|
||||
if (signaling == ksigInactive)
|
||||
{
|
||||
K3L_LINK_CONFIG & config = _k3lapi.link_config(dev, link);
|
||||
sig = config.Signaling;
|
||||
const K3L_LINK_CONFIG & config = _k3lapi.link_config(dev, link);
|
||||
signaling = config.Signaling;
|
||||
}
|
||||
|
||||
K3L_LINK_STATUS status;
|
||||
K3L_LINK_STATUS status;
|
||||
|
||||
KLibraryStatus ret = (KLibraryStatus) k3lGetDeviceStatus (dev,
|
||||
link + ksoLink, &status, sizeof(status));
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case ksSuccess: return Verbose::linkStatus(sig, status.E1, fmt);
|
||||
case ksSuccess: return Verbose::linkStatus(signaling, status.E1, fmt, simpleStatus);
|
||||
default: return (fmt == Verbose::EXACT ?
|
||||
"<unknown[failure]>" : "Unknown (failure)");
|
||||
}
|
||||
}
|
||||
catch(K3LAPI::invalid_channel & e)
|
||||
catch(K3LAPITraits::invalid_channel & e)
|
||||
{
|
||||
return (fmt == Verbose::EXACT ? "<unknown[failure]>"
|
||||
: "Unknown (failure)");
|
||||
}
|
||||
}
|
||||
|
||||
std::string K3LUtil::getLinkStatus(int32 dev, int32 link,
|
||||
Verbose::Presentation fmt)
|
||||
{
|
||||
switch (_k3lapi.device_type(dev))
|
||||
{
|
||||
#if K3L_AT_LEAST(1,6,0)
|
||||
case kdtFXS:
|
||||
case kdtFXSSpx:
|
||||
return linkStatus(dev, link, fmt, ksigAnalogTerminal);
|
||||
|
||||
#if K3L_AT_LEAST(2,1,0)
|
||||
case kdtE1FXSSpx:
|
||||
if (link == 1)
|
||||
return linkStatus(dev, link, fmt, ksigAnalogTerminal);
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
K3L_LINK_CONFIG & conf = _k3lapi.link_config(dev, link);
|
||||
|
||||
std::string res = linkStatus(dev, link, fmt);
|
||||
|
||||
if (conf.ReceivingClock & 0x01)
|
||||
res += (fmt == Verbose::EXACT ? ",sync" : " (sync)");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
unsigned int K3LUtil::physicalLinkCount(int32 dev, bool count_virtual)
|
||||
{
|
||||
|
@ -199,7 +171,7 @@ unsigned int K3LUtil::physicalLinkCount(int32 dev, bool count_virtual)
|
|||
break;
|
||||
}
|
||||
}
|
||||
catch(K3LAPI::invalid_device & e)
|
||||
catch(K3LAPITraits::invalid_device & e)
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -64,10 +64,8 @@ struct K3LUtil
|
|||
|
||||
std::string linkStatus(int32, int32,
|
||||
Verbose::Presentation fmt = Verbose::HUMAN,
|
||||
KSignaling sig = ksigInactive);
|
||||
|
||||
std::string getLinkStatus(int32, int32,
|
||||
Verbose::Presentation fmt = Verbose::HUMAN);
|
||||
KSignaling sig = ksigInactive,
|
||||
bool simpleStatus = false);
|
||||
|
||||
unsigned int physicalLinkCount(int32 dev, bool count_virtual = false);
|
||||
|
|
@ -55,6 +55,7 @@
|
|||
#if defined(COMMONS_LIBRARY_USING_ASTERISK)
|
||||
extern "C"
|
||||
{
|
||||
#include <asterisk.h>
|
||||
#include <asterisk/localtime.h>
|
||||
}
|
||||
#elif defined(COMMONS_LIBRARY_USING_CALLWEAVER)
|
||||
|
@ -443,35 +444,17 @@ struct Logger
|
|||
localtime_r (&tv, <);
|
||||
#endif
|
||||
|
||||
out_msg += STG(FMT("[%04d-%02d-%02d %02d:%02d:%02d] ")
|
||||
% (lt.tm_year + 1900) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour
|
||||
% lt.tm_min % lt.tm_sec);
|
||||
|
||||
#elif defined(COMMONS_LIBRARY_USING_CALLWEAVER)
|
||||
#elif 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("[%04d-%02d-%02d %02d:%02d:%02d] ")
|
||||
% (lt.tm_year + 1900) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour
|
||||
% lt.tm_min % lt.tm_sec);
|
||||
|
||||
#elif defined(COMMONS_LIBRARY_USING_FREESWITCH)
|
||||
time_t tv;
|
||||
struct tm lt;
|
||||
|
||||
time (&tv);
|
||||
|
||||
localtime_r (&tv, <);
|
||||
|
||||
out_msg += STG(FMT("[%04d-%02d-%02d %02d:%02d:%02d] ")
|
||||
% (lt.tm_year + 1900) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour
|
||||
% lt.tm_min % lt.tm_sec);
|
||||
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
|
||||
if (opt._flags[Option::DATETIMEMS])
|
||||
|
@ -497,16 +480,16 @@ struct Logger
|
|||
#endif
|
||||
|
||||
#if ASTERISK_AT_LEAST(1,6,0)
|
||||
out_msg += STG(FMT("[%04d-%02d-%02d %02d:%02d:%02d:%04d] ")
|
||||
% (lt.tm_year + 1900) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour % lt.tm_min
|
||||
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.tv_usec / 1000));
|
||||
#else
|
||||
out_msg += STG(FMT("[%04d-%02d-%02d %02d:%02d:%02d:%04d] ")
|
||||
% (lt.tm_year + 1900) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour % lt.tm_min
|
||||
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
|
||||
|
||||
#elif defined(COMMONS_LIBRARY_USING_CALLWEAVER)
|
||||
#elif defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
|
||||
time_t tv;
|
||||
struct tm lt;
|
||||
|
||||
|
@ -514,22 +497,9 @@ struct Logger
|
|||
|
||||
localtime_r (&tv, <);
|
||||
|
||||
out_msg += STG(FMT("[%04d-%02d-%02d %02d:%02d:%02d:%04d] ")
|
||||
% (lt.tm_year + 1900) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour % lt.tm_min
|
||||
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));
|
||||
|
||||
#elif defined(COMMONS_LIBRARY_USING_FREESWITCH)
|
||||
time_t tv;
|
||||
struct tm lt;
|
||||
|
||||
time (&tv);
|
||||
|
||||
localtime_r (&tv, <);
|
||||
|
||||
out_msg += STG(FMT("[%04d-%02d-%02d %02d:%02d:%02d:%04d] ")
|
||||
% (lt.tm_year + 1900) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour % lt.tm_min
|
||||
% lt.tm_sec % (tv * 1000));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -538,7 +508,7 @@ struct Logger
|
|||
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("t=%08p ") % ((void*)pthread_self()));
|
||||
out_msg += STG(FMT("%08x ") % ((unsigned long)pthread_self()));
|
||||
#endif
|
||||
}
|
||||
|
|
@ -45,6 +45,11 @@
|
|||
#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))
|
||||
|
||||
|
@ -179,13 +184,13 @@ struct ReferenceCounter
|
|||
};
|
||||
|
||||
template < typename T >
|
||||
struct ReferenceContainer: NEW_REFCOUNTER(ReferenceContainer< T >)
|
||||
struct ReferenceContainer: COUNTER_SUPER(ReferenceContainer< T >)
|
||||
{
|
||||
/* type */
|
||||
typedef T Type;
|
||||
|
||||
/* shorthand */
|
||||
typedef ReferenceCounter < ReferenceContainer< Type > > Counter;
|
||||
typedef COUNTER_CLASS(ReferenceContainer< Type >) Counter;
|
||||
|
||||
// TODO: make this a generic exception someday
|
||||
struct NotFound {};
|
||||
|
@ -249,7 +254,7 @@ struct ReferenceContainer: NEW_REFCOUNTER(ReferenceContainer< T >)
|
|||
};
|
||||
|
||||
// return value (pointer)!
|
||||
Type * operator()(void)
|
||||
Type * operator()(void) const
|
||||
{
|
||||
return _reference_value;
|
||||
};
|
|
@ -74,7 +74,7 @@ void Regex::Expression::initialize(void)
|
|||
_errorstate = regcomp(&_comp_regex, _expression, _flags);
|
||||
}
|
||||
|
||||
std::string Regex::Expression::regerror_as_string(void)
|
||||
std::string Regex::Expression::regerror_as_string(void) const
|
||||
{
|
||||
unsigned int count = regerror(_errorstate, &_comp_regex, 0, 0) + 1;
|
||||
|
||||
|
@ -95,6 +95,7 @@ void Regex::Match::initialize(void)
|
|||
{
|
||||
_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);
|
||||
}
|
||||
|
@ -117,7 +118,7 @@ std::string Regex::Match::replace(Regex::ReplaceMap & map)
|
|||
try
|
||||
{
|
||||
if (_submatches[0].rm_so != 0 && (map.find(0) != map.end()))
|
||||
return _basestring.replace(_submatches[0].rm_so, _submatches[0].rm_eo - _submatches[0].rm_so, map.find(0)->second);
|
||||
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++)
|
||||
{
|
|
@ -111,12 +111,12 @@ struct Regex
|
|||
}
|
||||
}
|
||||
|
||||
bool valid(void) { return (_errorstate == 0); }
|
||||
bool valid(void) const { return (_errorstate == 0); }
|
||||
|
||||
unsigned int subcount(void) { return _subcounter; }
|
||||
const regex_t * repr(void) { return &_comp_regex; }
|
||||
unsigned int subcount(void) const { return _subcounter; }
|
||||
const regex_t * repr(void) const { return &_comp_regex; }
|
||||
|
||||
std::string error(void)
|
||||
std::string error(void) const
|
||||
{
|
||||
switch (_errorstate)
|
||||
{
|
||||
|
@ -127,31 +127,33 @@ struct Regex
|
|||
}
|
||||
|
||||
private:
|
||||
void initialize(void);
|
||||
std::string regerror_as_string(void);
|
||||
std::string regerror_as_string(void) const;
|
||||
|
||||
private:
|
||||
void initialize(void);
|
||||
|
||||
protected:
|
||||
const char * _expression;
|
||||
bool _alloced;
|
||||
const bool _alloced;
|
||||
|
||||
unsigned int _subcounter;
|
||||
|
||||
int _errorstate;
|
||||
regex_t _comp_regex;
|
||||
|
||||
unsigned int _flags;
|
||||
const unsigned int _flags;
|
||||
};
|
||||
|
||||
struct Match: NEW_REFCOUNTER(Match)
|
||||
struct Match: COUNTER_SUPER(Match)
|
||||
{
|
||||
Match(const char * basestring, Expression & expression, unsigned int flags = 0)
|
||||
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(std::string & basestring, Expression & expression, unsigned int flags = 0)
|
||||
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)
|
||||
{
|
||||
|
@ -159,7 +161,7 @@ struct Regex
|
|||
}
|
||||
|
||||
Match(const Match & o)
|
||||
: INC_REFCOUNTER(o, Match),
|
||||
: COUNTER_REFER(o, Match),
|
||||
_basestring(o._basestring), _expression(o._expression),
|
||||
_subcounter(o._subcounter), _submatches(o._submatches),
|
||||
_have_match(o._have_match), _flags(o._flags)
|
||||
|
@ -169,6 +171,10 @@ struct Regex
|
|||
void unreference()
|
||||
{
|
||||
delete[] _submatches;
|
||||
delete[] _subcaching;
|
||||
|
||||
_submatches = 0;
|
||||
_subcaching = 0;
|
||||
}
|
||||
|
||||
bool matched(void)
|
||||
|
@ -184,34 +190,23 @@ struct Regex
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string submatch(int number)
|
||||
const std::string & submatch(int number)
|
||||
{
|
||||
if (!matched(number))
|
||||
return "";
|
||||
return _subcaching[_subcounter - 1 /* invalid, always empty! */ ];
|
||||
|
||||
return _basestring.substr(_submatches[number].rm_so,
|
||||
_submatches[number].rm_eo - _submatches[number].rm_so);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief gets a map with all matches
|
||||
* \return std::map<int,std::string> with all matches
|
||||
* \note index 0 in map, is the complete string
|
||||
* \author Eduardo Nunes Pereira
|
||||
*
|
||||
* If fails the empty map is returned
|
||||
*/
|
||||
std::map<int, std::string> obtain_match_map()
|
||||
{
|
||||
int match_counter = 0;
|
||||
std::map<int,std::string> tmp_map;
|
||||
while(matched(match_counter))
|
||||
if (_subcaching[number].empty())
|
||||
{
|
||||
tmp_map.insert(std::make_pair(match_counter,submatch(match_counter)));
|
||||
match_counter++;
|
||||
_subcaching[number].assign(_basestring, _submatches[number].rm_so,
|
||||
_submatches[number].rm_eo - _submatches[number].rm_so);
|
||||
}
|
||||
|
||||
return tmp_map;
|
||||
return _subcaching[number];
|
||||
}
|
||||
|
||||
const std::string & operator[](int number)
|
||||
{
|
||||
return submatch(number);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -226,25 +221,21 @@ struct Regex
|
|||
std::string replace(ReplaceMap &);
|
||||
std::string replace(std::string, unsigned int index = REP_BASE);
|
||||
|
||||
std::string operator[](int number)
|
||||
{
|
||||
return submatch(number);
|
||||
}
|
||||
|
||||
// NOTE: there is already a way to get subcount defined on EXPRESSION class!
|
||||
|
||||
private:
|
||||
void initialize(void);
|
||||
|
||||
protected:
|
||||
std::string _basestring;
|
||||
Expression & _expression;
|
||||
const std::string _basestring;
|
||||
const Expression & _expression;
|
||||
|
||||
unsigned int _subcounter;
|
||||
regmatch_t * _submatches;
|
||||
|
||||
std::string * _subcaching;
|
||||
bool _have_match;
|
||||
unsigned int _flags;
|
||||
|
||||
const unsigned int _flags;
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,485 @@
|
|||
/*
|
||||
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;
|
||||
}
|
|
@ -46,6 +46,12 @@
|
|||
|
||||
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>
|
||||
|
@ -61,7 +67,7 @@
|
|||
|
||||
struct Buffer_pointer
|
||||
{
|
||||
Buffer_pointer(unsigned int _complete = 0u, unsigned short _partial = 0u)
|
||||
Buffer_pointer(unsigned int _complete, unsigned short _partial)
|
||||
: complete(_complete), partial(_partial)
|
||||
{};
|
||||
|
||||
|
@ -134,6 +140,10 @@ __attribute__((packed));
|
|||
|
||||
struct Ringbuffer_traits
|
||||
{
|
||||
struct BufferFull {};
|
||||
struct BufferEmpty {};
|
||||
|
||||
protected:
|
||||
Ringbuffer_traits(unsigned int block, unsigned int size)
|
||||
: _block(block), _size(size)
|
||||
{};
|
||||
|
@ -155,6 +165,28 @@ struct Ringbuffer_traits
|
|||
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;
|
||||
|
@ -163,11 +195,8 @@ struct Ringbuffer_traits
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
struct Ringbuffer: protected Ringbuffer_traits, public NonCopyable
|
||||
struct Ringbuffer: public Ringbuffer_traits, public NonCopyable
|
||||
{
|
||||
struct BufferFull {};
|
||||
struct BufferEmpty {};
|
||||
|
||||
Ringbuffer(unsigned int size)
|
||||
: Ringbuffer_traits(sizeof(T), size)
|
||||
{
|
||||
|
@ -189,15 +218,17 @@ struct Ringbuffer: protected Ringbuffer_traits, public NonCopyable
|
|||
}
|
||||
|
||||
/***** GENERIC RANGE/INDEX CALCULATION FUNCTIONS *****/
|
||||
bool may_write(Buffer_table & cache)
|
||||
|
||||
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) != 1) && (!(r == 0 && w == _size)));
|
||||
return (((r - w) != 0) && (!(r == 0 && w == _size)));
|
||||
}
|
||||
|
||||
bool may_read(Buffer_table & cache)
|
||||
inline bool may_read(const Buffer_table & cache) const
|
||||
{
|
||||
if ((cache.writer.complete - cache.reader.complete) == 1)
|
||||
return false;
|
||||
|
@ -205,7 +236,7 @@ struct Ringbuffer: protected Ringbuffer_traits, public NonCopyable
|
|||
return true;
|
||||
}
|
||||
|
||||
unsigned int writer_next(Buffer_pointer & cache, Buffer_pointer & index)
|
||||
inline unsigned int writer_next(const Buffer_pointer & cache, Buffer_pointer & index) const
|
||||
{
|
||||
unsigned int dest = cache.complete - 1,
|
||||
temp = cache.complete + 1;
|
||||
|
@ -218,7 +249,7 @@ struct Ringbuffer: protected Ringbuffer_traits, public NonCopyable
|
|||
return dest;
|
||||
};
|
||||
|
||||
void reader_next(Buffer_pointer & cache, Buffer_pointer & index)
|
||||
inline void reader_next(const Buffer_pointer & cache, Buffer_pointer & index) const
|
||||
{
|
||||
unsigned int temp = cache.complete + 1;
|
||||
|
||||
|
@ -230,6 +261,7 @@ struct Ringbuffer: protected Ringbuffer_traits, public NonCopyable
|
|||
|
||||
/***** BUFFER FUNCTIONS *****/
|
||||
|
||||
public:
|
||||
bool provide(const T & value)
|
||||
{
|
||||
Buffer_table cache = _pointers;
|
||||
|
@ -280,9 +312,9 @@ struct Ringbuffer: protected Ringbuffer_traits, public NonCopyable
|
|||
}
|
||||
|
||||
/* writes everything or nothing */
|
||||
inline bool provide(const T * value, unsigned int amount, bool skip_overwrite = true)
|
||||
inline bool provide(const T * value, unsigned int amount, bool do_not_overwrite = true)
|
||||
{
|
||||
return traits_provide((char *)_buffer, (const char *) value, amount, skip_overwrite);
|
||||
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') */
|
||||
|
@ -337,7 +369,7 @@ struct Ringbuffer: protected Ringbuffer_traits, public NonCopyable
|
|||
// fprintf(stderr, "%p> write: %d/%d [%d/%d]\n", this, _pointers.reader, _pointers.writer, _pointers.reader_partial, _pointers.writer_partial);
|
||||
}
|
||||
|
||||
T & consumer_start(void)
|
||||
const T & consumer_start(void)
|
||||
{
|
||||
Buffer_table cache = _pointers;
|
||||
|
||||
|
@ -391,13 +423,13 @@ struct Ringbuffer: protected Ringbuffer_traits, public NonCopyable
|
|||
/* returns the number of items written to from buffer to stream */
|
||||
inline unsigned int put(std::ostream &fd, unsigned int amount)
|
||||
{
|
||||
return traits_put((char *)_buffer, fd, 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((const char *)_buffer, fd, amount);
|
||||
return traits_get((char *)_buffer, fd, amount);
|
||||
}
|
||||
|
||||
void clear()
|
|
@ -55,7 +55,7 @@
|
|||
* implement the "unreference()" method for releasing resources. */
|
||||
|
||||
template < typename Implementor >
|
||||
struct SimpleLockCommon: NEW_REFCOUNTER( SimpleLockCommon < Implementor > )
|
||||
struct SimpleLockCommon: COUNTER_SUPER( SimpleLockCommon < Implementor > )
|
||||
{
|
||||
friend class ReferenceCounter < SimpleLockCommon < Implementor > >;
|
||||
|
||||
|
@ -71,7 +71,7 @@ struct SimpleLockCommon: NEW_REFCOUNTER( SimpleLockCommon < Implementor > )
|
|||
{};
|
||||
|
||||
SimpleLockCommon(const SimpleLockCommon & o)
|
||||
: INC_REFCOUNTER(o, SimpleLockCommon)
|
||||
: COUNTER_REFER(o, SimpleLockCommon)
|
||||
{};
|
||||
|
||||
virtual ~SimpleLockCommon()
|
|
@ -141,6 +141,38 @@ unsigned int Strings::tokenize(const std::string & str, Strings::vector_type & t
|
|||
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);
|
||||
|
@ -153,11 +185,11 @@ bool Strings::toboolean(std::string str)
|
|||
throw invalid_value(str);
|
||||
}
|
||||
|
||||
long Strings::tolong(std::string str, int base)
|
||||
unsigned long Strings::toulong(const char * str, int base)
|
||||
{
|
||||
char *str_end = 0;
|
||||
|
||||
unsigned long value = strtol(str.c_str(), &str_end, base);
|
||||
unsigned long value = strtoul(str, &str_end, base);
|
||||
|
||||
if (str_end && *str_end == 0)
|
||||
return value;
|
||||
|
@ -165,26 +197,14 @@ long Strings::tolong(std::string str, int base)
|
|||
throw invalid_value(str);
|
||||
}
|
||||
|
||||
unsigned long Strings::toulong(std::string str, int base)
|
||||
{
|
||||
char *str_end = 0;
|
||||
|
||||
unsigned long value = strtoul(str.c_str(), &str_end, base);
|
||||
|
||||
if (str_end && *str_end == 0)
|
||||
return value;
|
||||
|
||||
throw invalid_value(str);
|
||||
}
|
||||
|
||||
unsigned long long Strings::toulonglong(std::string str, int base)
|
||||
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.c_str(), &str_end, base);
|
||||
unsigned long long value = strtoull(str, &str_end, base);
|
||||
|
||||
if (str_end && *str_end == 0)
|
||||
return value;
|
||||
|
@ -193,11 +213,11 @@ unsigned long long Strings::toulonglong(std::string str, int base)
|
|||
#endif
|
||||
}
|
||||
|
||||
double Strings::todouble(std::string str)
|
||||
double Strings::todouble(const char * str)
|
||||
{
|
||||
char *str_end = 0;
|
||||
|
||||
double value = strtod(str.c_str(), &str_end);
|
||||
double value = strtod(str, &str_end);
|
||||
|
||||
if (str_end && *str_end == 0)
|
||||
return value;
|
|
@ -68,6 +68,8 @@ struct Strings
|
|||
|
||||
bool empty() { return _list.empty(); };
|
||||
|
||||
const list_type & list() { return _list; };
|
||||
|
||||
protected:
|
||||
list_type _list;
|
||||
};
|
||||
|
@ -75,8 +77,8 @@ struct Strings
|
|||
public:
|
||||
struct invalid_value
|
||||
{
|
||||
invalid_value(const char * value): _value(value) {};
|
||||
invalid_value(std::string value): _value(value) {};
|
||||
invalid_value(const char * value): _value(value) {};
|
||||
invalid_value(const std::string & value): _value(value) {};
|
||||
|
||||
std::string & value() { return _value; }
|
||||
|
||||
|
@ -92,10 +94,15 @@ struct Strings
|
|||
static bool toboolean(std::string);
|
||||
static std::string fromboolean(bool);
|
||||
|
||||
static long tolong(std::string, int base = 10);
|
||||
static unsigned long toulong(std::string, int base = 10);
|
||||
static unsigned long long toulonglong(std::string, int base = 10);
|
||||
static double todouble(std::string);
|
||||
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);
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
/*
|
||||
KHOMP generic endpoint/channel library.
|
||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
||||
|
||||
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/
|
||||
|
@ -23,40 +23,40 @@
|
|||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include "saved_condition.hpp"
|
||||
|
||||
bool SavedCondition::wait(unsigned int msec)
|
||||
{
|
||||
bool ret = true;
|
||||
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;
|
||||
}
|
||||
|
||||
if (switch_thread_cond_timedwait(_condition, _mutex, (switch_interval_time_t)msec * 1000) != 0)
|
||||
ret = false;
|
||||
}
|
||||
|
||||
_signaled = false;
|
||||
|
||||
switch_mutex_unlock(_mutex);
|
||||
switch_mutex_unlock(_mutex);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
/*
|
||||
KHOMP generic endpoint/channel library.
|
||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
||||
|
||||
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/
|
||||
|
@ -23,20 +23,20 @@
|
|||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _SAVED_CONDITION_
|
||||
|
@ -104,7 +104,7 @@ struct SavedCondition : public SavedConditionCommon// : public RefCounter < Save
|
|||
|
||||
if (!_signaled)
|
||||
switch_thread_cond_wait(_condition, _mutex);
|
||||
|
||||
|
||||
_signaled = false;
|
||||
|
||||
switch_mutex_unlock(_mutex);
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
/*
|
||||
KHOMP generic endpoint/channel library.
|
||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
||||
|
||||
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/
|
||||
|
@ -23,20 +23,20 @@
|
|||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _SIMPLE_LOCK_HPP_
|
||||
|
@ -72,7 +72,7 @@ struct SimpleLockBasic: public SimpleLockCommon < Implementor >
|
|||
{
|
||||
/* do nothing */
|
||||
};
|
||||
|
||||
|
||||
void unreference()
|
||||
{
|
||||
switch_mutex_destroy(_mutex);
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
/*
|
||||
KHOMP generic endpoint/channel library.
|
||||
Copyright (C) 2007-2009 Khomp Ind. & Com.
|
||||
|
||||
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/
|
||||
|
@ -23,20 +23,20 @@
|
|||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _THREAD_HPP_
|
||||
|
@ -66,7 +66,7 @@ struct Thread : ThreadCommon
|
|||
T _data;
|
||||
A _arg;
|
||||
};
|
||||
|
||||
|
||||
template<typename T, typename R>
|
||||
struct ThreadData < T, R, void > : ThreadDataCommon
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ struct Thread : ThreadCommon
|
|||
|
||||
T _data;
|
||||
};
|
||||
|
||||
|
||||
template<typename T, typename A>
|
||||
struct ThreadData < T, void, A > : ThreadDataCommon
|
||||
{
|
||||
|
@ -111,7 +111,7 @@ struct Thread : ThreadCommon
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
Thread(T obj, switch_memory_pool_t *pool=NULL) :
|
||||
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)
|
||||
|
@ -134,7 +134,7 @@ struct Thread : ThreadCommon
|
|||
}
|
||||
|
||||
switch_threadattr_stacksize_set(
|
||||
(switch_threadattr_t *)_thread_info->_attribute,
|
||||
(switch_threadattr_t *)_thread_info->_attribute,
|
||||
SWITCH_THREAD_STACKSIZE);
|
||||
|
||||
if(!priority())
|
||||
|
@ -143,9 +143,9 @@ struct Thread : ThreadCommon
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<typename T, typename A>
|
||||
Thread(T obj, A arg, switch_memory_pool_t *pool=NULL) :
|
||||
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)
|
||||
|
@ -168,7 +168,7 @@ struct Thread : ThreadCommon
|
|||
}
|
||||
|
||||
switch_threadattr_stacksize_set(
|
||||
(switch_threadattr_t *)_thread_info->_attribute,
|
||||
(switch_threadattr_t *)_thread_info->_attribute,
|
||||
SWITCH_THREAD_STACKSIZE);
|
||||
|
||||
if(!priority())
|
||||
|
@ -178,11 +178,11 @@ struct Thread : ThreadCommon
|
|||
|
||||
}
|
||||
|
||||
~Thread()
|
||||
~Thread()
|
||||
{
|
||||
if(_thread_info)
|
||||
delete _thread_info;
|
||||
|
||||
|
||||
if (_can_delete_pool)
|
||||
switch_core_destroy_memory_pool(&_pool);
|
||||
}
|
||||
|
@ -202,10 +202,10 @@ struct Thread : ThreadCommon
|
|||
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,
|
||||
switch_thread_create((switch_thread_t**)&_thread_info->_self,
|
||||
(switch_threadattr_t *)_thread_info->_attribute,
|
||||
run,
|
||||
_thread_info,
|
||||
_pool);
|
||||
|
||||
if(!_thread_info->_self)
|
||||
|
@ -223,13 +223,13 @@ struct Thread : ThreadCommon
|
|||
*
|
||||
* 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,
|
||||
if(switch_thread_join((switch_status_t*)&retval,
|
||||
(switch_thread_t *)_thread_info->_self) != 0)
|
||||
return -1;
|
||||
|
||||
|
@ -267,7 +267,7 @@ private:
|
|||
{
|
||||
#ifndef WIN32
|
||||
struct sched_param param;
|
||||
|
||||
|
||||
struct apr_threadattr_t *myattr = (struct apr_threadattr_t *)_thread_info->_attribute;
|
||||
|
||||
if (pthread_attr_setschedpolicy(
|
||||
|
@ -307,13 +307,13 @@ protected:
|
|||
|
||||
static void *SWITCH_THREAD_FUNC run(BaseThreadType *thread, void * obj)
|
||||
{
|
||||
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
||||
//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,
|
||||
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
||||
// "Stopping new Thread = %d\n", retval);
|
||||
|
||||
((Thread *)(data->_thread))->exit(retval);
|
|
@ -42,11 +42,14 @@
|
|||
#ifndef _TAGGED_UNION_HPP_
|
||||
#define _TAGGED_UNION_HPP_
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <typeinfo>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
#include <format.hpp>
|
||||
|
||||
namespace Tagged
|
||||
{
|
||||
struct EmptyUnion
|
||||
|
@ -69,7 +72,7 @@ namespace Tagged
|
|||
|
||||
~EmptyUnion() { _adjusted = false; };
|
||||
|
||||
bool operator==(const EmptyUnion & o)
|
||||
bool operator==(const EmptyUnion & o) const
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
@ -80,24 +83,24 @@ namespace Tagged
|
|||
void setup(void) { _adjusted = true; };
|
||||
|
||||
protected:
|
||||
bool value_set(void) { return false; };
|
||||
bool value_get(void) { return false; };
|
||||
bool value_set(void) const { return false; };
|
||||
bool value_get(void) const { return false; };
|
||||
|
||||
bool value_check(void) { return false; };
|
||||
bool value_check(void) const { return false; };
|
||||
|
||||
template < typename S >
|
||||
bool value_visit(S & visitor, typename S::ReturnType & ret)
|
||||
bool value_visit(S & visitor, typename S::ReturnType & ret) const
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
template < typename S >
|
||||
bool value_visit_void(S & visitor)
|
||||
bool value_visit_void(S & visitor) const
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
bool adjusted() { return _adjusted; };
|
||||
bool adjusted() const { return _adjusted; };
|
||||
|
||||
private:
|
||||
bool _adjusted;
|
||||
|
@ -114,7 +117,7 @@ namespace Tagged
|
|||
|
||||
// constructor with initializer
|
||||
template < typename U >
|
||||
Union( U value )
|
||||
Union(U value)
|
||||
: _value(0)
|
||||
{
|
||||
set(value);
|
||||
|
@ -123,7 +126,7 @@ namespace Tagged
|
|||
// copy constructor
|
||||
Union(const Union & o)
|
||||
: E(static_cast<const E&>(o)),
|
||||
_value( (o._value ? new const V(*(o._value)) : 0) )
|
||||
_value( (o._value ? new V(*(o._value)) : 0) )
|
||||
{};
|
||||
|
||||
// copy assignment operator
|
||||
|
@ -137,7 +140,7 @@ namespace Tagged
|
|||
|
||||
if (o._value)
|
||||
{
|
||||
_value = new const V(*(o._value));
|
||||
_value = new V(*(o._value));
|
||||
}
|
||||
|
||||
E::operator=(static_cast<const E&>(o));
|
||||
|
@ -163,18 +166,21 @@ namespace Tagged
|
|||
}
|
||||
|
||||
template < typename U >
|
||||
bool check(void)
|
||||
bool check(void) const
|
||||
{
|
||||
return value_check(static_cast<const U * const>(0));
|
||||
return value_check(static_cast< const U * const>(0));
|
||||
};
|
||||
|
||||
template < typename U >
|
||||
const U & get(void)
|
||||
U & get(void) const
|
||||
{
|
||||
const U * res = 0;
|
||||
U * res = 0;
|
||||
|
||||
if (!E::adjusted())
|
||||
throw std::runtime_error("tagged union empty!");
|
||||
|
||||
if (!value_get(&res) || !res)
|
||||
throw std::runtime_error("type mismatch");
|
||||
throw std::runtime_error(STG(FMT("type mismatch when asked for '%s'") % typeid(U).name()));
|
||||
|
||||
return *res;
|
||||
};
|
||||
|
@ -190,7 +196,7 @@ namespace Tagged
|
|||
};
|
||||
|
||||
template < typename S >
|
||||
typename S::ReturnType visit(S visitor)
|
||||
typename S::ReturnType visit(S visitor) const
|
||||
{
|
||||
typename S::ReturnType ret;
|
||||
|
||||
|
@ -201,7 +207,7 @@ namespace Tagged
|
|||
};
|
||||
|
||||
template < typename S >
|
||||
void visit_void(S visitor)
|
||||
void visit_void(S visitor) const
|
||||
{
|
||||
if (!value_visit_void(visitor))
|
||||
throw std::runtime_error("unable to visit empty value");
|
||||
|
@ -219,7 +225,7 @@ namespace Tagged
|
|||
};
|
||||
|
||||
// compare (equal) operator
|
||||
bool operator==(const Union & o)
|
||||
bool operator==(const Union & o) const
|
||||
{
|
||||
bool are_equal = false;
|
||||
|
||||
|
@ -236,7 +242,7 @@ namespace Tagged
|
|||
};
|
||||
|
||||
// compare types
|
||||
bool sameType(const Union & o)
|
||||
bool sameType(const Union & o) const
|
||||
{
|
||||
if ((!(_value) && !(o._value)) || (_value && o._value))
|
||||
return E::operator==(static_cast<const E&>(o));
|
||||
|
@ -254,13 +260,13 @@ namespace Tagged
|
|||
|
||||
bool value_set(V val)
|
||||
{
|
||||
_value = new const V(val);
|
||||
_value = new V(val);
|
||||
E::setup();
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool value_get(const V ** val)
|
||||
bool value_get(V ** val) const
|
||||
{
|
||||
if (!_value)
|
||||
return false;
|
||||
|
@ -269,14 +275,14 @@ namespace Tagged
|
|||
return true;
|
||||
}
|
||||
|
||||
bool value_check(const V * const junk)
|
||||
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)
|
||||
bool value_visit(S & visitor, typename S::ReturnType & ret) const
|
||||
{
|
||||
if (_value)
|
||||
{
|
||||
|
@ -288,7 +294,7 @@ namespace Tagged
|
|||
};
|
||||
|
||||
template < typename S >
|
||||
bool value_visit_void(S & visitor)
|
||||
bool value_visit_void(S & visitor) const
|
||||
{
|
||||
if (_value)
|
||||
{
|
||||
|
@ -300,7 +306,7 @@ namespace Tagged
|
|||
};
|
||||
|
||||
private:
|
||||
const V * _value;
|
||||
V * _value;
|
||||
};
|
||||
};
|
||||
|
|
@ -276,6 +276,20 @@ bool TimerTraits::traits_restart (TimerTraits::Index & idx, bool force)
|
|||
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;
|
|
@ -125,6 +125,8 @@ struct TimerTraits
|
|||
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);
|
||||
|
@ -169,7 +171,7 @@ struct TimerTraits
|
|||
};
|
||||
|
||||
template < typename F, typename D >
|
||||
struct TimerTemplate: NEW_REFCOUNTER(TimerTemplate< F, D >)
|
||||
struct TimerTemplate: COUNTER_SUPER(TimerTemplate< F, D >)
|
||||
{
|
||||
typedef TimerTraits::Index Index;
|
||||
typedef TimerTraits::Control Control;
|
||||
|
@ -179,7 +181,7 @@ struct TimerTemplate: NEW_REFCOUNTER(TimerTemplate< F, D >)
|
|||
{};
|
||||
|
||||
TimerTemplate(const TimerTemplate< F, D > & o)
|
||||
: INC_REFCOUNTER(o, TimerTemplate< F, D >),
|
||||
: COUNTER_REFER(o, TimerTemplate< F, D >),
|
||||
_timer(o._timer)
|
||||
{};
|
||||
|
||||
|
@ -192,6 +194,11 @@ struct TimerTemplate: NEW_REFCOUNTER(TimerTemplate< F, D >)
|
|||
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);
|
|
@ -55,15 +55,33 @@
|
|||
/*** Used for checking information on classes and stuff.. ***/
|
||||
|
||||
template< typename T >
|
||||
class IsClass
|
||||
struct IsClass
|
||||
{
|
||||
protected:
|
||||
template< typename X > static char ( &A( void(X::*)() ) )[1];
|
||||
template< typename X > static char ( &A( X ) )[2];
|
||||
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 >
|
|
@ -11,7 +11,7 @@
|
|||
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
|
||||
"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
|
||||
|
@ -41,87 +41,84 @@
|
|||
|
||||
#include <refcounter.hpp>
|
||||
|
||||
#include <typeinfo>
|
||||
#ifndef _VARIABLE_HPP_
|
||||
#define _VARIABLE_HPP_
|
||||
|
||||
#ifndef _VARIANT_H_
|
||||
#define _VARIANT_H_
|
||||
|
||||
/* this is internal, should not be used by the user */
|
||||
struct NoArgumentDefined {};
|
||||
|
||||
template < typename UserReturnType, typename UserArgumentType = NoArgumentDefined >
|
||||
struct VariantBaseType
|
||||
template < typename R >
|
||||
struct VariableBaseTable
|
||||
{
|
||||
typedef UserReturnType ReturnType;
|
||||
typedef UserArgumentType ArgumentType;
|
||||
|
||||
virtual ~VariantBaseType() {};
|
||||
|
||||
virtual int which() = 0;
|
||||
|
||||
virtual ReturnType visit(void) { return ReturnType(); };
|
||||
virtual ReturnType visit(ArgumentType) { return ReturnType(); };
|
||||
R value;
|
||||
};
|
||||
|
||||
template < typename BaseType = VariantBaseType < void > >
|
||||
struct Variant: NEW_REFCOUNTER(Variant < BaseType >)
|
||||
struct EmptyVariable {};
|
||||
|
||||
template < typename R >
|
||||
struct Variable
|
||||
{
|
||||
typedef typename BaseType::ReturnType ReturnType;
|
||||
typedef typename BaseType::ArgumentType ArgumentType;
|
||||
protected:
|
||||
typedef VariableBaseTable< R > BaseType;
|
||||
|
||||
struct InvalidType {};
|
||||
typedef const BaseType * ConstObjType;
|
||||
typedef BaseType * ObjType;
|
||||
typedef R BaseType::* VarType;
|
||||
|
||||
Variant(BaseType * value, bool is_owner = false)
|
||||
: _value(value), _is_owner(is_owner) {};
|
||||
public:
|
||||
template < typename ConstructorObjType >
|
||||
Variable(R ConstructorObjType::* v)
|
||||
: _adjusted(true),
|
||||
_variable(reinterpret_cast<const VarType>(v))
|
||||
{};
|
||||
|
||||
Variant(const Variant & v)
|
||||
: INC_REFCOUNTER(v, Variant < BaseType >),
|
||||
_value(v._value), _is_owner(v._is_owner) {};
|
||||
Variable()
|
||||
: _adjusted(false)
|
||||
{};
|
||||
|
||||
virtual ~Variant() {};
|
||||
|
||||
void unreference()
|
||||
template < typename MemberType >
|
||||
void operator=(const MemberType v)
|
||||
{
|
||||
if (_is_owner && _value)
|
||||
{
|
||||
delete _value;
|
||||
_value = 0;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename ValueType >
|
||||
ValueType & get(void)
|
||||
{
|
||||
try
|
||||
{
|
||||
ValueType & ret = dynamic_cast < ValueType & > (*_value);
|
||||
return ret;
|
||||
}
|
||||
catch (std::bad_cast & e)
|
||||
{
|
||||
throw InvalidType();
|
||||
}
|
||||
};
|
||||
|
||||
int which()
|
||||
{
|
||||
return _value->which();
|
||||
_adjusted = true;
|
||||
_variable = reinterpret_cast<const VarType>(v);
|
||||
}
|
||||
|
||||
ReturnType visit(void)
|
||||
template < typename Type >
|
||||
R & operator()(Type * obj) const
|
||||
{
|
||||
return _value->visit();
|
||||
if (!_adjusted)
|
||||
throw EmptyVariable();
|
||||
|
||||
return (reinterpret_cast< ObjType >(obj))->*(_variable);
|
||||
}
|
||||
|
||||
ReturnType visit(ArgumentType arg)
|
||||
template < typename Type >
|
||||
R & operator()(Type & obj) const
|
||||
{
|
||||
return _value->visit(arg);
|
||||
if (!_adjusted)
|
||||
throw EmptyVariable();
|
||||
|
||||
return (reinterpret_cast< ObjType >(&obj))->*(_variable);
|
||||
}
|
||||
|
||||
protected:
|
||||
BaseType * _value;
|
||||
bool _is_owner;
|
||||
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 /* _VARIANT_H_ */
|
||||
|
||||
#endif /* _VARIABLE_HPP_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,303 @@
|
|||
/*
|
||||
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,710 +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>
|
||||
|
||||
ConfigOption::ConfigOption(std::string name, const ConfigOption::StringType & value, const ConfigOption::StringType defvalue, string_allowed_type allowed, bool list_me)
|
||||
: _my_name(name), _value_data(new StringData(const_cast<StringType &>(value), defvalue, allowed), true),
|
||||
_list_me(list_me), _values(NULL), _loaded(false)
|
||||
{};
|
||||
|
||||
ConfigOption::ConfigOption(std::string name, const ConfigOption::StringType & value, const ConfigOption::StringType defvalue, bool list_me)
|
||||
: _my_name(name), _value_data(new StringData(const_cast<StringType &>(value), defvalue, string_allowed_type()), true),
|
||||
_list_me(list_me), _values(NULL), _loaded(false)
|
||||
{};
|
||||
|
||||
ConfigOption::ConfigOption(std::string name, const ConfigOption::SignedIntType & value, const ConfigOption::SignedIntType defvalue,
|
||||
ConfigOption::SignedIntType min, ConfigOption::SignedIntType max, ConfigOption::SignedIntType step, bool list_me)
|
||||
: _my_name(name), _value_data(new SignedIntData(const_cast<SignedIntType &>(value), defvalue, Range<SignedIntType>(min, max, step)), true),
|
||||
_list_me(list_me), _values(NULL), _loaded(false)
|
||||
{};
|
||||
|
||||
ConfigOption::ConfigOption(std::string name, const ConfigOption::UnsignedIntType & value, const ConfigOption::UnsignedIntType defvalue,
|
||||
ConfigOption::UnsignedIntType min, ConfigOption::UnsignedIntType max, ConfigOption::UnsignedIntType step, bool list_me)
|
||||
: _my_name(name), _value_data(new UnsignedIntData(const_cast<UnsignedIntType &>(value), defvalue, Range<UnsignedIntType>(min, max, step)), true),
|
||||
_list_me(list_me), _values(NULL), _loaded(false)
|
||||
{};
|
||||
|
||||
ConfigOption::ConfigOption(std::string name, const ConfigOption::BooleanType & value, const ConfigOption::BooleanType defvalue, bool list_me)
|
||||
: _my_name(name), _value_data(new BooleanData(const_cast<BooleanType &>(value), defvalue), true),
|
||||
_list_me(list_me), _values(NULL), _loaded(false)
|
||||
{};
|
||||
|
||||
ConfigOption::ConfigOption(std::string name, ConfigOption::FunctionType fun, std::string defvalue, string_allowed_type allowed, bool list_me)
|
||||
: _my_name(name), _value_data(new FunctionData(fun, defvalue, allowed), true),
|
||||
_list_me(list_me), _values(NULL), _loaded(false)
|
||||
{};
|
||||
|
||||
ConfigOption::ConfigOption(std::string name, ConfigOption::FunctionType fun, std::string defvalue, bool list_me)
|
||||
: _my_name(name), _value_data(new FunctionData(fun, defvalue, string_allowed_type()), true),
|
||||
_list_me(list_me), _values(NULL), _loaded(false)
|
||||
{};
|
||||
|
||||
ConfigOption::ConfigOption(const ConfigOption & o)
|
||||
: _my_name(o._my_name), _value_data(o._value_data),
|
||||
_list_me(o._list_me), _values(o._values), _loaded(o._loaded)
|
||||
{};
|
||||
|
||||
ConfigOption::~ConfigOption(void)
|
||||
{
|
||||
if (_values)
|
||||
{
|
||||
for (unsigned int i = 0; _values[i] != NULL; i++)
|
||||
delete _values[i];
|
||||
|
||||
delete[] _values;
|
||||
_values = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
void ConfigOption::set(ConfigOption::StringType value)
|
||||
{
|
||||
switch (_value_data.which())
|
||||
{
|
||||
case ID_STRING:
|
||||
{
|
||||
try
|
||||
{
|
||||
StringData & tmp = _value_data.get<StringData>();
|
||||
|
||||
if (tmp.string_allowed.empty())
|
||||
{
|
||||
tmp.string_val = value;
|
||||
_loaded = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tmp.string_allowed.find(value) != tmp.string_allowed.end())
|
||||
{
|
||||
tmp.string_val = value;
|
||||
_loaded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string allowed_string;
|
||||
|
||||
for (string_allowed_type::iterator i = tmp.string_allowed.begin(); i != tmp.string_allowed.end(); i++)
|
||||
{
|
||||
allowed_string += " '";
|
||||
allowed_string += (*i);
|
||||
allowed_string += "'";
|
||||
}
|
||||
|
||||
throw ConfigProcessFailure(STG(FMT("value '%s' not allowed for option '%s' (allowed values:%s)")
|
||||
% value % _my_name % allowed_string));
|
||||
}
|
||||
break;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
case ID_FUN:
|
||||
{
|
||||
try
|
||||
{
|
||||
FunctionData & tmp = _value_data.get<FunctionData>();
|
||||
tmp.fun_val(value);
|
||||
_loaded = true;
|
||||
break;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw ConfigProcessFailure(STG(FMT("option '%s' is not of type string, nor function defined") % _my_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigOption::set(ConfigOption::SignedIntType value)
|
||||
{
|
||||
try
|
||||
{
|
||||
SignedIntData & tmp = _value_data.get<SignedIntData>();
|
||||
|
||||
if (value < tmp.sint_Range.minimum)
|
||||
throw ConfigProcessFailure(STG(FMT("value '%d' out-of-Range for option '%s' (too low)") % value % _my_name));
|
||||
|
||||
if (value > tmp.sint_Range.maximum)
|
||||
throw ConfigProcessFailure(STG(FMT("value '%d' out-of-Range for option '%s' (too high)") % value % _my_name));
|
||||
|
||||
if (((value - tmp.sint_Range.minimum) % tmp.sint_Range.step) != 0)
|
||||
throw ConfigProcessFailure(STG(FMT("value '%d' out-of-Range for option '%s' (outside allowed step)") % value % _my_name));
|
||||
|
||||
tmp.sint_val = value;
|
||||
_loaded = true;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigOption::set(ConfigOption::UnsignedIntType value)
|
||||
{
|
||||
try
|
||||
{
|
||||
UnsignedIntData & tmp = _value_data.get<UnsignedIntData>();
|
||||
|
||||
if (value < tmp.uint_Range.minimum)
|
||||
throw ConfigProcessFailure(STG(FMT("value '%d' out-of-Range for option '%s' (too low)") % value % _my_name));
|
||||
|
||||
if (value > tmp.uint_Range.maximum)
|
||||
throw ConfigProcessFailure(STG(FMT("value '%d' out-of-Range for option '%s' (too high)") % value % _my_name));
|
||||
|
||||
if (((value - tmp.uint_Range.minimum) % tmp.uint_Range.step) != 0)
|
||||
throw ConfigProcessFailure(STG(FMT("value '%d' out-of-Range for option '%s' (outside allowed step)") % value % _my_name));
|
||||
|
||||
tmp.uint_val = value;
|
||||
_loaded = true;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigOption::set(ConfigOption::BooleanType value)
|
||||
{
|
||||
try
|
||||
{
|
||||
BooleanData & tmp = _value_data.get<BooleanData>();
|
||||
tmp.bool_val = value;
|
||||
_loaded = true;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
std::string & ConfigOption::name(void) { return _my_name; };
|
||||
|
||||
ConfigOption::value_id_type ConfigOption::type(void)
|
||||
{
|
||||
return (value_id_type) _value_data.which();
|
||||
};
|
||||
|
||||
const char ** ConfigOption::values(void)
|
||||
{
|
||||
if (_values != NULL)
|
||||
return _values;
|
||||
|
||||
switch ((value_id_type) _value_data.which())
|
||||
{
|
||||
case ConfigOption::ID_BOOL:
|
||||
{
|
||||
_values = new const char*[3];
|
||||
|
||||
_values[0] = strdup("yes");
|
||||
_values[1] = strdup("no");
|
||||
_values[2] = NULL;
|
||||
|
||||
return _values;
|
||||
}
|
||||
|
||||
case ConfigOption::ID_SINT:
|
||||
{
|
||||
try
|
||||
{
|
||||
SignedIntData & tmp = _value_data.get<SignedIntData>();
|
||||
|
||||
|
||||
unsigned int count = ((tmp.sint_Range.maximum - tmp.sint_Range.minimum) / tmp.sint_Range.step) + 1;
|
||||
unsigned int index = 0;
|
||||
|
||||
_values = new const char*[count + 1];
|
||||
|
||||
for (SignedIntType i = tmp.sint_Range.minimum; i <= tmp.sint_Range.maximum; i += tmp.sint_Range.step, index++)
|
||||
_values[index] = strdup(STG(FMT("%d") % i).c_str());
|
||||
|
||||
_values[index] = NULL;
|
||||
|
||||
return _values;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
case ConfigOption::ID_UINT:
|
||||
{
|
||||
try
|
||||
{
|
||||
UnsignedIntData & tmp = _value_data.get<UnsignedIntData>();
|
||||
|
||||
unsigned int count = ((tmp.uint_Range.maximum - tmp.uint_Range.minimum) / tmp.uint_Range.step) + 1;
|
||||
unsigned int index = 0;
|
||||
|
||||
_values = new const char*[count + 1];
|
||||
|
||||
for (UnsignedIntType i = tmp.uint_Range.minimum; i <= tmp.uint_Range.maximum; i += tmp.uint_Range.step, index++)
|
||||
_values[index] = strdup(STG(FMT("%d") % i).c_str());
|
||||
|
||||
_values[index] = NULL;
|
||||
|
||||
return _values;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
case ConfigOption::ID_STRING:
|
||||
{
|
||||
try
|
||||
{
|
||||
StringData & tmp = _value_data.get<StringData>();
|
||||
|
||||
_values = new const char*[ tmp.string_allowed.size() + 1 ];
|
||||
|
||||
unsigned int index = 0;
|
||||
|
||||
for (string_allowed_type::iterator i = tmp.string_allowed.begin(); i != tmp.string_allowed.end(); i++, index++)
|
||||
_values[index] = strdup((*i).c_str());
|
||||
|
||||
_values[index] = NULL;
|
||||
|
||||
return _values;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
case ConfigOption::ID_FUN:
|
||||
{
|
||||
try
|
||||
{
|
||||
FunctionData & tmp = _value_data.get<FunctionData>();
|
||||
|
||||
_values = new const char*[ tmp.fun_allowed.size() + 1 ];
|
||||
|
||||
unsigned int index = 0;
|
||||
|
||||
for (string_allowed_type::iterator i = tmp.fun_allowed.begin(); i != tmp.fun_allowed.end(); i++, index++)
|
||||
_values[index] = strdup((*i).c_str());
|
||||
|
||||
_values[index] = NULL;
|
||||
return _values;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
default:
|
||||
throw ConfigProcessFailure(STG(FMT("unknown type identifier '%d'") % _value_data.which()));
|
||||
}
|
||||
};
|
||||
|
||||
void ConfigOption::reset(void)
|
||||
{
|
||||
_loaded = false;
|
||||
};
|
||||
|
||||
void ConfigOption::commit(void)
|
||||
{
|
||||
if (_loaded)
|
||||
return;
|
||||
|
||||
switch ((value_id_type) _value_data.which())
|
||||
{
|
||||
case ConfigOption::ID_BOOL:
|
||||
{
|
||||
try
|
||||
{
|
||||
BooleanData & tmp = _value_data.get<BooleanData>();
|
||||
tmp.bool_val = tmp.bool_default;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ConfigOption::ID_SINT:
|
||||
{
|
||||
try
|
||||
{
|
||||
SignedIntData & tmp = _value_data.get<SignedIntData>();
|
||||
tmp.sint_val = tmp.sint_default;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ConfigOption::ID_UINT:
|
||||
{
|
||||
try
|
||||
{
|
||||
UnsignedIntData & tmp = _value_data.get<UnsignedIntData>();
|
||||
tmp.uint_val = tmp.uint_default;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ConfigOption::ID_STRING:
|
||||
{
|
||||
try
|
||||
{
|
||||
StringData & tmp = _value_data.get<StringData>();
|
||||
tmp.string_val = tmp.string_default;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ConfigOption::ID_FUN:
|
||||
{
|
||||
try
|
||||
{
|
||||
FunctionData & tmp = _value_data.get<FunctionData>();
|
||||
tmp.fun_val(tmp.fun_default);
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw ConfigProcessFailure(STG(FMT("unknown type identifier '%d'") % _value_data.which()));
|
||||
}
|
||||
|
||||
_loaded = true;
|
||||
};
|
||||
|
||||
void ConfigOption::copy_from(ConfigOption & src)
|
||||
{
|
||||
if (src._value_data.which() != _value_data.which())
|
||||
throw ConfigProcessFailure(STG(FMT("unable to copy options, source type differs from destination.")));
|
||||
|
||||
if (!src._loaded)
|
||||
return;
|
||||
|
||||
switch ((value_id_type) _value_data.which())
|
||||
{
|
||||
case ConfigOption::ID_BOOL:
|
||||
{
|
||||
try
|
||||
{
|
||||
BooleanData & stmp = src._value_data.get<BooleanData>();
|
||||
BooleanData & dtmp = _value_data.get<BooleanData>();
|
||||
/* do not copy references, but values.. */
|
||||
bool tmpval = stmp.bool_val;
|
||||
dtmp.bool_val = tmpval;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ConfigOption::ID_SINT:
|
||||
{
|
||||
try
|
||||
{
|
||||
SignedIntData & stmp = src._value_data.get<SignedIntData>();
|
||||
SignedIntData & dtmp = _value_data.get<SignedIntData>();
|
||||
/* do not copy references, but values.. */
|
||||
int tmpval = stmp.sint_val;
|
||||
dtmp.sint_val = tmpval;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ConfigOption::ID_UINT:
|
||||
{
|
||||
try
|
||||
{
|
||||
UnsignedIntData & stmp = src._value_data.get<UnsignedIntData>();
|
||||
UnsignedIntData & dtmp = _value_data.get<UnsignedIntData>();
|
||||
/* do not copy references, but values.. */
|
||||
unsigned int tmpval = stmp.uint_val;
|
||||
dtmp.uint_val = tmpval;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ConfigOption::ID_STRING:
|
||||
{
|
||||
try
|
||||
{
|
||||
StringData & stmp = src._value_data.get<StringData>();
|
||||
StringData & dtmp = _value_data.get<StringData>();
|
||||
/* do not copy references, but values.. */
|
||||
std::string tmpval = stmp.string_val;
|
||||
dtmp.string_val = tmpval;
|
||||
}
|
||||
catch(ValueType::InvalidType & e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ConfigOption::ID_FUN:
|
||||
{
|
||||
/* TO IMPLEMENT (NEEDS ANOTHER METHOD ON FUNCTION FOR GETTING VALUE) */
|
||||
|
||||
// FunctionData & tmp = boost::get<FunctionData>(_value_data);
|
||||
//
|
||||
// if (!tmp.loaded)
|
||||
// {
|
||||
// tmp.fun_val(tmp.fun_default);
|
||||
// tmp.loaded = true;
|
||||
// }
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw ConfigProcessFailure(STG(FMT("unknown type identifier '%d'") % _value_data.which()));
|
||||
}
|
||||
|
||||
_loaded = true;
|
||||
};
|
||||
|
||||
/*********************************/
|
||||
|
||||
bool ConfigOptions::add(ConfigOption option)
|
||||
{
|
||||
//option_map_type::iterator iter2 = _map.begin();
|
||||
|
||||
//boost::tie(iter2, ok2)
|
||||
std::pair<option_map_type::iterator, bool> ret = _map.insert(option_pair_type(option.name(), option));
|
||||
|
||||
return ret.second;
|
||||
}
|
||||
|
||||
bool ConfigOptions::synonym(std::string equiv_opt, std::string main_opt)
|
||||
{
|
||||
//syn_option_map_type::iterator iter = _syn_map.begin();
|
||||
|
||||
//boost::tie(iter, ok)
|
||||
std::pair<syn_option_map_type::iterator, bool> ret = _syn_map.insert(syn_option_pair_type(equiv_opt, main_opt));
|
||||
|
||||
return ret.second;
|
||||
}
|
||||
|
||||
ConfigOptions::string_set ConfigOptions::options(void)
|
||||
{
|
||||
string_set res;
|
||||
|
||||
for (option_map_type::iterator i = _map.begin(); i != _map.end(); i++)
|
||||
res.insert((*i).first);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void ConfigOptions::process(const char * name, const char * value)
|
||||
{
|
||||
option_map_type::iterator iter = find_option(name);
|
||||
|
||||
if (iter == _map.end())
|
||||
throw ConfigProcessFailure(STG(FMT("unknown option '%s'") % name));
|
||||
|
||||
try
|
||||
{
|
||||
switch ((*iter).second.type())
|
||||
{
|
||||
case ConfigOption::ID_SINT:
|
||||
set<ConfigOption::SignedIntType>((*iter).first, Strings::toulong(value));
|
||||
return;
|
||||
case ConfigOption::ID_UINT:
|
||||
set<ConfigOption::UnsignedIntType>((*iter).first, Strings::tolong(value));
|
||||
return;
|
||||
case ConfigOption::ID_BOOL:
|
||||
set<ConfigOption::BooleanType>((*iter).first, Strings::toboolean(value));
|
||||
return;
|
||||
case ConfigOption::ID_STRING:
|
||||
case ConfigOption::ID_FUN:
|
||||
set<ConfigOption::StringType>((*iter).first, std::string(value));
|
||||
return;
|
||||
default:
|
||||
throw ConfigProcessFailure(STG(FMT("unknown type identifier '%d'") % (*iter).second.type()));
|
||||
}
|
||||
}
|
||||
catch (Strings::invalid_value & e)
|
||||
{
|
||||
throw ConfigProcessFailure(STG(FMT("invalid value '%s' for option '%s'") % value % name));
|
||||
}
|
||||
}
|
||||
|
||||
const char ** ConfigOptions::values(const char * name)
|
||||
{
|
||||
option_map_type::iterator iter = find_option(name);
|
||||
|
||||
if (iter == _map.end())
|
||||
throw ConfigProcessFailure(STG(FMT("unknown option '%s'") % name));
|
||||
|
||||
return (*iter).second.values();
|
||||
}
|
||||
|
||||
const char ** ConfigOptions::values(void)
|
||||
{
|
||||
if (_values != NULL)
|
||||
return _values;
|
||||
|
||||
unsigned int count = 0;
|
||||
|
||||
for (option_map_type::iterator i = _map.begin(); i != _map.end(); i++)
|
||||
if ((*i).second.list_me())
|
||||
++count;
|
||||
|
||||
_values = new const char*[ count + 1 ];
|
||||
|
||||
unsigned int index = 0;
|
||||
|
||||
for (option_map_type::iterator i = _map.begin(); i != _map.end(); i++)
|
||||
{
|
||||
if ((*i).second.list_me())
|
||||
{
|
||||
_values[index] = strdup((*i).first.c_str());
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
_values[index] = NULL;
|
||||
|
||||
return _values;
|
||||
}
|
||||
|
||||
void ConfigOptions::reset(void)
|
||||
{
|
||||
for (option_map_type::iterator i = _map.begin(); i != _map.end(); i++)
|
||||
(*i).second.reset();
|
||||
}
|
||||
|
||||
ConfigOptions::messages_type ConfigOptions::commit(void)
|
||||
{
|
||||
messages_type msgs;
|
||||
|
||||
for (option_map_type::iterator i = _map.begin(); i != _map.end(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
(*i).second.commit();
|
||||
}
|
||||
catch (ConfigProcessFailure & e)
|
||||
{
|
||||
msgs.push_back(e.msg);
|
||||
}
|
||||
}
|
||||
|
||||
return msgs;
|
||||
}
|
||||
|
||||
bool ConfigOptions::loaded(std::string name)
|
||||
{
|
||||
option_map_type::iterator iter = find_option(name);
|
||||
|
||||
if (iter == _map.end())
|
||||
return false;
|
||||
|
||||
return iter->second.loaded();
|
||||
}
|
||||
|
||||
void ConfigOptions::copy_from(ConfigOptions & source, std::string name)
|
||||
{
|
||||
option_map_type::iterator iter_src = source.find_option(name);
|
||||
option_map_type::iterator iter_dst = find_option(name);
|
||||
|
||||
if (iter_src == source._map.end())
|
||||
throw ConfigProcessFailure(STG(FMT("unknown option '%s' on source") % name));
|
||||
|
||||
if (iter_dst == _map.end())
|
||||
throw ConfigProcessFailure(STG(FMT("unknown option '%s' on destination") % name));
|
||||
|
||||
iter_dst->second.copy_from(iter_src->second);
|
||||
}
|
||||
|
||||
ConfigOptions::option_map_type::iterator ConfigOptions::find_option(std::string name)
|
||||
{
|
||||
syn_option_map_type::iterator syn_iter = _syn_map.find(name);
|
||||
|
||||
if (syn_iter != _syn_map.end())
|
||||
name = syn_iter->second;
|
||||
|
||||
option_map_type::iterator iter = _map.find(name);
|
||||
|
||||
return iter;
|
||||
}
|
|
@ -1,286 +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 <set>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <strings.hpp>
|
||||
|
||||
#include <function.hpp>
|
||||
#include <variant.hpp>
|
||||
#include <format.hpp>
|
||||
|
||||
#ifndef _CONFIG_OPTIONS_HPP_
|
||||
#define _CONFIG_OPTIONS_HPP_
|
||||
|
||||
struct ConfigProcessFailure
|
||||
{
|
||||
ConfigProcessFailure(std::string _msg): msg(_msg) {};
|
||||
std::string msg;
|
||||
};
|
||||
|
||||
struct ConfigOption
|
||||
{
|
||||
typedef int SignedIntType;
|
||||
typedef unsigned int UnsignedIntType;
|
||||
typedef bool BooleanType;
|
||||
typedef std::string StringType;
|
||||
|
||||
typedef Function::Function1 < void, std::string > FunctionType;
|
||||
|
||||
typedef std::set < StringType > string_allowed_type;
|
||||
|
||||
/* this should reflect 'variant.which()'! */
|
||||
typedef enum
|
||||
{
|
||||
ID_SINT = 0,
|
||||
ID_UINT = 1,
|
||||
ID_BOOL = 2,
|
||||
ID_STRING = 3,
|
||||
ID_FUN = 4,
|
||||
}
|
||||
value_id_type;
|
||||
|
||||
template < typename number_type >
|
||||
struct Range
|
||||
{
|
||||
Range(number_type _minimum, number_type _maximum, number_type _step)
|
||||
: minimum(_minimum), maximum(_maximum), step(_step) {};
|
||||
|
||||
number_type minimum, maximum, step;
|
||||
};
|
||||
|
||||
struct SignedIntData : public VariantBaseType < void >
|
||||
{
|
||||
SignedIntData(SignedIntType & _sint_val, SignedIntType _sint_default, Range< SignedIntType > _sint_Range)
|
||||
: sint_val(_sint_val), sint_default(_sint_default), sint_Range(_sint_Range) {};
|
||||
|
||||
int which()
|
||||
{
|
||||
return ID_SINT;
|
||||
}
|
||||
|
||||
SignedIntType & sint_val;
|
||||
SignedIntType sint_default;
|
||||
Range<SignedIntType> sint_Range;
|
||||
};
|
||||
|
||||
struct UnsignedIntData : public VariantBaseType < void >
|
||||
{
|
||||
UnsignedIntData(UnsignedIntType & _uint_val, UnsignedIntType _uint_default, Range< UnsignedIntType > _uint_Range)
|
||||
: uint_val(_uint_val), uint_default(_uint_default), uint_Range(_uint_Range) {};
|
||||
|
||||
int which()
|
||||
{
|
||||
return ID_UINT;
|
||||
}
|
||||
|
||||
UnsignedIntType & uint_val;
|
||||
UnsignedIntType uint_default;
|
||||
Range<UnsignedIntType> uint_Range;
|
||||
};
|
||||
|
||||
struct BooleanData : public VariantBaseType < void >
|
||||
{
|
||||
BooleanData(BooleanType & _bool_val, BooleanType _bool_default)
|
||||
: bool_val(_bool_val), bool_default(_bool_default) {};
|
||||
|
||||
int which()
|
||||
{
|
||||
return ID_BOOL;
|
||||
}
|
||||
|
||||
BooleanType & bool_val;
|
||||
BooleanType bool_default;
|
||||
};
|
||||
|
||||
struct StringData : public VariantBaseType < void >
|
||||
{
|
||||
StringData(std::string & _string_val, std::string _string_default, string_allowed_type _string_allowed)
|
||||
: string_val(_string_val), string_default(_string_default), string_allowed(_string_allowed) {};
|
||||
|
||||
int which()
|
||||
{
|
||||
return ID_STRING;
|
||||
}
|
||||
|
||||
std::string & string_val;
|
||||
std::string string_default;
|
||||
string_allowed_type string_allowed;
|
||||
};
|
||||
|
||||
struct FunctionData : public VariantBaseType < void >
|
||||
{
|
||||
FunctionData(FunctionType _fun_val, std::string _fun_default, string_allowed_type _fun_allowed)
|
||||
: fun_val(_fun_val), fun_default(_fun_default), fun_allowed(_fun_allowed) {};
|
||||
|
||||
int which()
|
||||
{
|
||||
return ID_FUN;
|
||||
}
|
||||
|
||||
FunctionType fun_val;
|
||||
std::string fun_default;
|
||||
string_allowed_type fun_allowed;
|
||||
};
|
||||
|
||||
|
||||
typedef Variant < VariantBaseType < void > > ValueType;
|
||||
|
||||
ConfigOption(std::string, const StringType &, const StringType, string_allowed_type allowed, bool list_me = true);
|
||||
ConfigOption(std::string, const StringType &, const StringType = "", bool list_me = true);
|
||||
ConfigOption(std::string, const SignedIntType &, const SignedIntType = 0, SignedIntType min = -INT_MAX, SignedIntType max = INT_MAX, SignedIntType step = 1, bool list_me = true);
|
||||
ConfigOption(std::string, const UnsignedIntType &, const UnsignedIntType = 0, UnsignedIntType min = 0, UnsignedIntType max = UINT_MAX, UnsignedIntType step = 1, bool list_me = true);
|
||||
ConfigOption(std::string, const BooleanType &, const BooleanType = false, bool list_me = true);
|
||||
ConfigOption(std::string, FunctionType, std::string defvalue, string_allowed_type allowed, bool list_me = true);
|
||||
ConfigOption(std::string, FunctionType, std::string defvalue = "", bool list_me = true);
|
||||
|
||||
ConfigOption(const ConfigOption & o);
|
||||
|
||||
~ConfigOption(void);
|
||||
|
||||
void set(StringType value);
|
||||
|
||||
void set(SignedIntType value);
|
||||
void set(UnsignedIntType value);
|
||||
void set(BooleanType value);
|
||||
|
||||
BooleanType get_bool(){ return _value_data.get<BooleanData>().bool_val; }
|
||||
std::string get_str(){ return _value_data.get<StringData>().string_val; }
|
||||
SignedIntType get_sint(){ return _value_data.get<SignedIntData>().sint_val; }
|
||||
UnsignedIntType get_uint(){ return _value_data.get<UnsignedIntData>().uint_val; }
|
||||
|
||||
std::string & name(void);
|
||||
value_id_type type(void);
|
||||
|
||||
const char ** values(void);
|
||||
|
||||
void reset(void);
|
||||
void commit(void);
|
||||
|
||||
bool list_me(void) { return _list_me; };
|
||||
bool loaded(void) { return _loaded; };
|
||||
|
||||
void copy_from(ConfigOption &);
|
||||
|
||||
protected:
|
||||
std::string _my_name;
|
||||
ValueType _value_data;
|
||||
|
||||
bool _list_me;
|
||||
const char ** _values;
|
||||
bool _loaded;
|
||||
};
|
||||
|
||||
struct ConfigOptions
|
||||
{
|
||||
typedef std::vector < std::string > messages_type;
|
||||
|
||||
ConfigOptions(void): _values(NULL) {};
|
||||
|
||||
typedef std::set < std::string > string_set;
|
||||
|
||||
typedef std::map < std::string, ConfigOption > option_map_type;
|
||||
typedef std::pair < std::string, ConfigOption > option_pair_type;
|
||||
|
||||
typedef std::map < std::string, std::string > syn_option_map_type;
|
||||
typedef std::pair < std::string, std::string > syn_option_pair_type;
|
||||
|
||||
bool add(ConfigOption option);
|
||||
|
||||
/* only valid in "process" (for backwards compatibility config files) */
|
||||
bool synonym(std::string, std::string);
|
||||
|
||||
template <typename ValueType>
|
||||
void set(std::string name, ValueType value)
|
||||
{
|
||||
option_map_type::iterator iter = _map.find(name);
|
||||
|
||||
if (iter == _map.end())
|
||||
throw ConfigProcessFailure(STG(FMT("unknown option: %s") % name));
|
||||
|
||||
(*iter).second.set(value);
|
||||
}
|
||||
|
||||
std::string get(std::string name)
|
||||
{
|
||||
option_map_type::iterator iter = _map.find(name);
|
||||
|
||||
if (iter == _map.end())
|
||||
throw ConfigProcessFailure(STG(FMT("unknown option: %s") % name));
|
||||
|
||||
switch((*iter).second.type())
|
||||
{
|
||||
case ConfigOption::ID_BOOL: return (*iter).second.get_bool() ? "yes" : "no";
|
||||
case ConfigOption::ID_STRING: return (*iter).second.get_str();
|
||||
case ConfigOption::ID_UINT: return STG(FMT("%d") % (*iter).second.get_uint());
|
||||
case ConfigOption::ID_SINT: return STG(FMT("%d") % (*iter).second.get_sint());
|
||||
case ConfigOption::ID_FUN: return "";
|
||||
}
|
||||
}
|
||||
|
||||
string_set options(void);
|
||||
|
||||
void process(const char *, const char *); /* process option from file */
|
||||
|
||||
void reset(void); /* reset loaded opts */
|
||||
messages_type commit(void); /* set defaults */
|
||||
|
||||
const char ** values(const char *); /* option value */
|
||||
const char ** values(void); /* values from options */
|
||||
|
||||
bool loaded(std::string); /* return if config was loaded */
|
||||
|
||||
void copy_from(ConfigOptions &, std::string);
|
||||
|
||||
protected:
|
||||
option_map_type::iterator find_option(std::string);
|
||||
|
||||
protected:
|
||||
option_map_type _map;
|
||||
syn_option_map_type _syn_map;
|
||||
|
||||
const char ** _values;
|
||||
};
|
||||
|
||||
#endif /* _CONFIG_OPTIONS_HPP_ */
|
||||
|
|
@ -1,241 +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(std::string str)
|
||||
{
|
||||
_ignores.insert(str);
|
||||
};
|
||||
|
||||
bool Configfile::select(Section **ptr, std::string str)
|
||||
{
|
||||
/* default section == this! */
|
||||
*ptr = this;
|
||||
|
||||
/* always success by default */
|
||||
return true;
|
||||
};
|
||||
|
||||
bool Configfile::adjust(Section * section, std::string & opt, 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::iterator section_iter;
|
||||
typedef Section::OptionMap::iterator option_iter;
|
||||
|
||||
for (option_iter 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 (section_iter 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,185 +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(std::string & value)
|
||||
{
|
||||
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(std::string & value)
|
||||
{
|
||||
bool ret = _restriction.set(Restriction::F_FILE, value);
|
||||
|
||||
if (ret) _modified = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Option::change(std::string & value)
|
||||
{
|
||||
bool ret = _restriction.set(Restriction::F_FILE, value);
|
||||
|
||||
if (ret) _modified = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Option::store(std::string & value)
|
||||
{
|
||||
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(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(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)
|
||||
{
|
||||
return _restriction.get(Restriction::F_USER, value);
|
||||
}
|
||||
|
||||
bool Option::get(Restriction::Vector & values)
|
||||
{
|
||||
return _restriction.get(Restriction::F_USER, values);
|
||||
}
|
|
@ -1,353 +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)
|
||||
{
|
||||
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 (!equalNumber(res, rint(res)))
|
||||
return false;
|
||||
|
||||
final = value;
|
||||
return true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
case B_LIST:
|
||||
for (List::iterator i = _list.begin(); i != _list.end(); i++)
|
||||
{
|
||||
Value & tmp = (*i);
|
||||
|
||||
if (tmp == value)
|
||||
{
|
||||
final = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
case B_MAPS:
|
||||
switch (fmt)
|
||||
{
|
||||
case F_USER:
|
||||
{
|
||||
Map::iterator i = _map_from_usr.find(std::string(value));
|
||||
|
||||
if (i == _map_from_usr.end())
|
||||
return false;
|
||||
|
||||
Value & tmp = (*i).second;
|
||||
|
||||
final = tmp;
|
||||
return true;
|
||||
}
|
||||
|
||||
case F_FILE:
|
||||
{
|
||||
Map::iterator i = _map_from_cfg.find(std::string(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)
|
||||
{
|
||||
switch (_bounds)
|
||||
{
|
||||
case B_MAPS:
|
||||
|
||||
switch (fmt)
|
||||
{
|
||||
case F_USER:
|
||||
{
|
||||
Map::iterator i = _map_from_cfg.find(std::string(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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (_numeral != N_MULTIPLE)
|
||||
return false;
|
||||
|
||||
List & my_values = _value._multiple;
|
||||
|
||||
for (List::iterator i = my_values.begin(); i != my_values.end(); i++)
|
||||
{
|
||||
Value & value = (*i);
|
||||
Value final;
|
||||
|
||||
if (!unprocess(fmt, value, final))
|
||||
return false;
|
||||
|
||||
values.push_back(final);
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/***************************** *****************************/
|
||||
|
||||
bool Restriction::set(Restriction::Format fmt, Restriction::Value &value)
|
||||
{
|
||||
switch (_numeral)
|
||||
{
|
||||
case N_UNIQUE:
|
||||
{
|
||||
Value final;
|
||||
|
||||
if (!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, 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::iterator i = values.begin(); i != values.end(); i++)
|
||||
{
|
||||
Value & value = (*i);
|
||||
Value final;
|
||||
|
||||
if (!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)
|
||||
{
|
||||
switch (_bounds)
|
||||
{
|
||||
case B_FREE:
|
||||
return;
|
||||
|
||||
case B_LIST:
|
||||
for (List::iterator i = _list.begin(); i != _list.end(); i++)
|
||||
vals.push_back((*i));
|
||||
break;
|
||||
|
||||
case B_MAPS:
|
||||
for (Map::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 = (!equalNumber(_init, rint(_init))) || (!equalNumber(_fini, rint(_fini))) || (!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,321 +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>
|
||||
|
||||
#ifndef _CONFIG_RESTRICTION_HPP_
|
||||
#define _CONFIG_RESTRICTION_HPP_
|
||||
|
||||
struct Restriction
|
||||
{
|
||||
/* generic types */
|
||||
enum Format
|
||||
{
|
||||
F_USER,
|
||||
F_FILE
|
||||
};
|
||||
|
||||
enum Kind
|
||||
{
|
||||
// K_INTEGER,
|
||||
// K_FLOAT,
|
||||
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,
|
||||
int init, int fini, int step = 1)
|
||||
: _kind(kind), _bounds(B_RANGE), _numeral(num), _unit(unit),
|
||||
_iinit(init), _ifini(fini), _istep(step),
|
||||
_finit(-1), _ffini(-1), _fstep(-1)
|
||||
{
|
||||
init_class();
|
||||
}
|
||||
|
||||
Restriction(Kind kind, Numeral num,
|
||||
const char *unit, int init, int fini, int step = 1)
|
||||
: _kind(kind), _bounds(B_RANGE), _numeral(num), _unit(unit),
|
||||
_iinit(init), _ifini(fini), _istep(step),
|
||||
_finit(-1), _ffini(-1), _fstep(-1)
|
||||
{
|
||||
init_class();
|
||||
}
|
||||
|
||||
Restriction(Kind kind, Numeral num,
|
||||
std::string unit, int init, int fini, int step = 1)
|
||||
: _kind(kind), _bounds(B_RANGE), _numeral(num), _unit(unit),
|
||||
_iinit(init), _ifini(fini), _istep(step),
|
||||
_finit(-1), _ffini(-1), _fstep(-1)
|
||||
{
|
||||
init_class();
|
||||
}
|
||||
|
||||
Restriction(Kind kind, Numeral num,
|
||||
float init, float fini, float step = 1)
|
||||
: _kind(kind), _bounds(B_RANGE), _numeral(num), _unit(unit),
|
||||
_iinit(-1), _ifini(-1), _istep(-1)
|
||||
_finit(init), _ffini(fini), _fstep(step),
|
||||
{
|
||||
init_class();
|
||||
}
|
||||
|
||||
Restriction(Kind kind, Numeral num,
|
||||
const char *unit, float init, float fini, float step = 1.0)
|
||||
: _kind(kind), _bounds(B_RANGE), _numeral(num), _unit(unit),
|
||||
_iinit(-1), _ifini(-1), _istep(-1)
|
||||
_finit(init), _ffini(fini), _fstep(step),
|
||||
{
|
||||
init_class();
|
||||
}
|
||||
|
||||
Restriction(Kind kind, Numeral num,
|
||||
std::string unit, float init, float fini, float step = 1.0)
|
||||
: _kind(kind), _bounds(B_RANGE), _numeral(num), _unit(unit),
|
||||
_iinit(-1), _ifini(-1), _istep(-1)
|
||||
_finit(init), _ffini(fini), _fstep(step),
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
Kind kind() { return _kind; };
|
||||
Bounds bounds() { return _bounds; };
|
||||
Numeral numeral() { return _numeral; };
|
||||
|
||||
Value unit() { return _unit; };
|
||||
|
||||
bool set(Format, Vector &);
|
||||
bool set(Format, Value &);
|
||||
|
||||
bool get(Format, Vector &);
|
||||
bool get(Format, Value &);
|
||||
|
||||
void allowed(Vector &);
|
||||
|
||||
private:
|
||||
bool process(Format, const Value &, Value &);
|
||||
bool unprocess(Format, const Value &, Value &);
|
||||
void init_class();
|
||||
|
||||
bool equalNumber(const double, const double);
|
||||
|
||||
protected:
|
||||
Kind _kind;
|
||||
Bounds _bounds;
|
||||
Numeral _numeral;
|
||||
|
||||
Value _unit;
|
||||
|
||||
double _init, _fini, _step;
|
||||
|
||||
Map _map_from_usr,
|
||||
_map_from_cfg;
|
||||
|
||||
List _list;
|
||||
|
||||
Generic _value;
|
||||
};
|
||||
|
||||
#endif /* _CONFIG_RESTRICTION_HPP_ */
|
|
@ -1,226 +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 <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include <configurator/option.hpp>
|
||||
|
||||
#ifndef _CONFIG_SECTION_HPP_
|
||||
#define _CONFIG_SECTION_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 not_found {}; /* exception */
|
||||
|
||||
// protected:
|
||||
Section(std::string name, std::string desc, bool recursive = true)
|
||||
: _name(name), _description(desc), _recursive(recursive) {};
|
||||
|
||||
void add(Option o)
|
||||
{
|
||||
_options.insert(std::pair<std::string,Option>(o.name(), o));
|
||||
};
|
||||
|
||||
void del(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() { return _name; };
|
||||
const std::string & description() { return _description; };
|
||||
const bool & recursive() { return _recursive; };
|
||||
|
||||
OptionMap::iterator option_begin() { return _options.begin(); };
|
||||
OptionMap::iterator option_end() { return _options.end(); };
|
||||
|
||||
SectionMap::iterator section_begin() { return _sections.begin(); };
|
||||
SectionMap::iterator section_end() { return _sections.end(); };
|
||||
|
||||
/**/
|
||||
|
||||
Option * option_find(const char *, bool recurse = false);
|
||||
Section * section_find(const char *, bool recurse = false);
|
||||
|
||||
Option * option_find(std::string &, bool recurse = false);
|
||||
Section * section_find(std::string &, bool recurse = false);
|
||||
|
||||
/**/
|
||||
|
||||
void options(OptionVector &);
|
||||
void sections(SectionVector &);
|
||||
|
||||
/**/
|
||||
|
||||
template <typename F>
|
||||
bool search_and_apply(std::string &key, std::string &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 key_value
|
||||
{
|
||||
key_value(std::string &k, std::string &v): _k(k), _v(v) {};
|
||||
std::string & _k, & _v;
|
||||
};
|
||||
|
||||
struct load_section: protected key_value
|
||||
{
|
||||
load_section(std::string &k, std::string &v): key_value(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 key_value
|
||||
{
|
||||
change_section(std::string &k, std::string &v): key_value(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 key_value
|
||||
{
|
||||
store_section(std::string &k, std::string &v): key_value(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 key_value
|
||||
{
|
||||
set_section(std::string &k, std::string &v): key_value(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 key_value
|
||||
{
|
||||
get_section(std::string &k, std::string &v): key_value(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()(OptionMap::value_type &v) { return v.second.modified(); };
|
||||
bool operator()(SectionMap::value_type &v) { return v.second->modified(); };
|
||||
};
|
||||
|
||||
public:
|
||||
bool load(const char * key, std::string value)
|
||||
{
|
||||
std::string skey(key);
|
||||
return search_and_apply(skey, value, load_section(skey, value));
|
||||
}
|
||||
|
||||
bool load(std::string &key, std::string &value)
|
||||
{
|
||||
return search_and_apply(key, value, load_section(key, value));
|
||||
}
|
||||
|
||||
bool change(std::string &key, std::string &value)
|
||||
{
|
||||
return search_and_apply(key, value, change_section(key, value));
|
||||
}
|
||||
|
||||
bool store(std::string &key, std::string &value)
|
||||
{
|
||||
return search_and_apply(key, value, store_section(key, value));
|
||||
}
|
||||
|
||||
bool set(std::string &key, std::string &value)
|
||||
{
|
||||
return search_and_apply(key, value, set_section(key, value));
|
||||
}
|
||||
|
||||
bool get(std::string &key, std::string &value)
|
||||
{
|
||||
return search_and_apply(key, value, get_section(key, value));
|
||||
}
|
||||
|
||||
bool modified()
|
||||
{
|
||||
return ((find_if(_options.begin(), _options.end(), modified_section()) != _options.end()) ||
|
||||
(find_if(_sections.begin(), _sections.end(), modified_section()) != _sections.end()));
|
||||
}
|
||||
|
||||
private:
|
||||
Section() {};
|
||||
|
||||
protected:
|
||||
std::string _name;
|
||||
std::string _description;
|
||||
|
||||
OptionMap _options;
|
||||
SectionMap _sections;
|
||||
|
||||
bool _recursive;
|
||||
};
|
||||
|
||||
#endif /* _CONFIG_SECTION_HPP_ */
|
|
@ -1,575 +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>
|
||||
|
||||
/********** BUFFER FUNCTIONS **********/
|
||||
|
||||
/* writes everything or nothing */
|
||||
bool Ringbuffer_traits::traits_provide(char * buffer, const char * value, unsigned int amount, bool skip_overwrite)
|
||||
{
|
||||
/* avoid using different values */
|
||||
Buffer_table cache = _pointers;
|
||||
|
||||
const unsigned int reader = cache.reader.complete;
|
||||
const unsigned int writer = cache.writer.complete;
|
||||
|
||||
const unsigned int dest = cache.writer.complete - 1;
|
||||
|
||||
const bool reader_less = cache.reader.complete < cache.writer.complete;
|
||||
|
||||
if (amount >= _size)
|
||||
return false;
|
||||
|
||||
bool ret = true;
|
||||
|
||||
/* should we go around the buffer for writing? */
|
||||
if (((writer + amount) > _size) && (reader_less || !skip_overwrite))
|
||||
{
|
||||
/* Documentation of the formula used in the 'if' below.
|
||||
*
|
||||
* [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.
|
||||
*
|
||||
*/
|
||||
|
||||
if ((_size - (writer - reader + 1)) <= amount)
|
||||
{
|
||||
if (skip_overwrite)
|
||||
return false;
|
||||
|
||||
do
|
||||
{
|
||||
Buffer_pointer extra(cache.reader);
|
||||
extra.complete = (extra.complete + amount) % _size;
|
||||
|
||||
if (update(cache.reader, extra))
|
||||
break;
|
||||
}
|
||||
while (true);
|
||||
|
||||
ret = false;
|
||||
}
|
||||
|
||||
unsigned int wr1 = _size - writer + 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[dest]), (const void *) (value), _block * wr1);
|
||||
memcpy((void *) (buffer), (const void *) &(value[wr1]), _block * wr2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!reader_less && ((reader - writer) <= amount))
|
||||
{
|
||||
if (skip_overwrite)
|
||||
return false;
|
||||
|
||||
do
|
||||
{
|
||||
Buffer_pointer extra(cache.reader);
|
||||
extra.complete = (extra.complete + amount) % _size;
|
||||
|
||||
if (update(cache.reader, extra))
|
||||
break;
|
||||
}
|
||||
while (true);
|
||||
|
||||
ret = false;
|
||||
}
|
||||
|
||||
// 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[dest]), (const void *) value, _block * amount);
|
||||
}
|
||||
|
||||
_pointers.writer.complete = ((dest + amount) % _size) + 1;
|
||||
_pointers.writer.partial = 1;
|
||||
|
||||
// fprintf(stderr, "%p> write end: %d [block=%d]\n", this, writer, _block);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 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 writer = _pointers.writer.complete;
|
||||
const unsigned int reader = _pointers.reader.complete;
|
||||
|
||||
const bool writer_less = writer < reader;
|
||||
|
||||
unsigned int total = 0;
|
||||
|
||||
/* should we go around the buffer for reading? */
|
||||
if (writer_less && (reader + amount >= _size))
|
||||
{
|
||||
total = std::min(_size - (reader - writer + 1), amount);
|
||||
|
||||
if ((total == 0) || (atomic_mode && (total < amount)))
|
||||
return 0;
|
||||
|
||||
unsigned int rd1 = _size - reader;
|
||||
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[reader]), _block * rd1);
|
||||
memcpy((void *) &(value[rd1]), (const void *) (buffer), _block * rd2);
|
||||
}
|
||||
else
|
||||
{
|
||||
total = std::min((!writer_less ? writer - (reader + 1) : amount), amount);
|
||||
|
||||
if ((total == 0) || (atomic_mode && (total < amount)))
|
||||
return 0;
|
||||
|
||||
// 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[reader]), _block * total);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
/* jump the reader forward */
|
||||
Buffer_pointer index((cache.reader.complete + total) % _size);
|
||||
|
||||
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)
|
||||
{
|
||||
Buffer_table cache = _pointers;
|
||||
|
||||
/* avoid using different values */
|
||||
const unsigned int reader = cache.reader.complete;
|
||||
const unsigned int writer = cache.writer.complete;
|
||||
|
||||
const bool writer_less = writer < reader;
|
||||
|
||||
unsigned int total = 0;
|
||||
|
||||
/* should we go around the buffer for reading? */
|
||||
if (writer_less && (reader + amount >= _size))
|
||||
{
|
||||
total = std::min(_size - (reader - writer + 1), amount);
|
||||
|
||||
if ((total == 0) || (atomic_mode && (total < amount)))
|
||||
return 0;
|
||||
|
||||
unsigned int rd1 = _size - reader;
|
||||
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[reader]), _block * rd1);
|
||||
memcpy((void *) &(value[rd1]), (const void *) (buffer), _block * rd2);
|
||||
}
|
||||
else
|
||||
{
|
||||
total = std::min((!writer_less ? writer - (reader + 1) : amount), amount);
|
||||
|
||||
if ((total == 0) || (atomic_mode && (total < amount)))
|
||||
return 0;
|
||||
|
||||
// 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[reader]), _block * total);
|
||||
}
|
||||
|
||||
// fprintf(stderr, "%p> read end: %d [%d]\n", this, _reader, _reader_partial);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
bool Ringbuffer_traits::traits_consume_commit(unsigned int amount)
|
||||
{
|
||||
/* avoid using different values */
|
||||
Buffer_table cache = _pointers;
|
||||
|
||||
const unsigned int writer = cache.writer.complete;
|
||||
const unsigned int reader = cache.reader.complete;
|
||||
|
||||
const bool writer_less = writer < reader;
|
||||
|
||||
unsigned int total = 0;
|
||||
|
||||
/* should we go around the buffer for reading? */
|
||||
if (writer_less && (reader + amount >= _size))
|
||||
{
|
||||
total = std::min(_size - (reader - writer + 1), amount);
|
||||
|
||||
if (total < amount)
|
||||
return false;
|
||||
|
||||
// fprintf(stderr, "%p> partial read: (%d/%d) %d/%d [%d/%d]\n", this, rd1, rd2, total, _size, reader, writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
total = std::min((!writer_less ? writer - (reader + 1) : amount), amount);
|
||||
|
||||
if (total < amount)
|
||||
return false;
|
||||
|
||||
// fprintf(stderr, "%p> full read: %d/%d [%d/%d]\n", this, total, _size, reader, writer);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
/* jump the reader forward */
|
||||
Buffer_pointer index(cache.reader);
|
||||
index.complete = (index.complete + total) % _size;
|
||||
|
||||
if (update(cache.reader, index))
|
||||
break;
|
||||
}
|
||||
while (true);
|
||||
|
||||
// fprintf(stderr, "%p> read end: %d [%d]\n", this, _reader, _reader_partial);
|
||||
|
||||
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 reader = (cache.reader.complete * _block) + cache.reader.partial;
|
||||
const unsigned int writer = ((cache.writer.complete - 1) * _block) + cache.writer.partial;
|
||||
|
||||
const unsigned int size = _size * _block;
|
||||
const unsigned int dest = writer - 1;
|
||||
|
||||
// fprintf(stderr, "%p> provide partial: %d/%d [%d/%d]\n", this, reader, writer, amount, size);
|
||||
|
||||
const bool reader_less = reader < writer;
|
||||
|
||||
/* should we go around the buffer for writing? */
|
||||
if (reader_less && ((writer + amount) > size))
|
||||
{
|
||||
/* Documentation of the formula used in the 'if' below.
|
||||
*
|
||||
* [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.
|
||||
*
|
||||
*/
|
||||
|
||||
if ((size - (writer - reader + 1)) <= amount)
|
||||
return false;
|
||||
|
||||
unsigned int wr1 = size - writer + 1; /* writer is already 1 position after */
|
||||
unsigned int wr2 = amount - wr1;
|
||||
|
||||
// fprintf(stderr, "%p> 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[dest]), (const void *) (value), wr1);
|
||||
memcpy((void *) (buffer), (const void *) &(value[wr1]), wr2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!reader_less && ((reader - writer) <= amount))
|
||||
return false;
|
||||
|
||||
// fprintf(stderr, "%p> p full write: %d/%d [r=%d/w=%d]\n", this, amount, size, reader, writer);
|
||||
|
||||
/* we are talking about buffers here, man! */
|
||||
memcpy((void *) &(buffer[dest]), (const void *) value, amount);
|
||||
}
|
||||
|
||||
unsigned int new_writer = ((dest + amount) % size) + 1;
|
||||
|
||||
/* update "full length position" */
|
||||
_pointers.writer.complete = (unsigned int)floor((double) new_writer / (double)_block)+1;
|
||||
_pointers.writer.partial = (unsigned short)(new_writer % _block);
|
||||
|
||||
// fprintf(stderr, "%p> p write end: %d [block=%d]\n", this, new_writer, _block);
|
||||
|
||||
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 writer = ((cache.writer.complete - 1) * _block) + cache.writer.partial;
|
||||
const unsigned int reader = (cache.reader.complete * _block) + cache.reader.partial;
|
||||
|
||||
const unsigned int size = _size * _block;
|
||||
|
||||
// fprintf(stderr, "%p> consume partial: %d/%d [%d/%d]\n", this, reader, writer, amount, size);
|
||||
|
||||
const bool writer_less = writer < reader;
|
||||
|
||||
unsigned int total = 0;
|
||||
|
||||
/* should we go around the buffer for reading? */
|
||||
if (writer_less && (reader + amount >= size))
|
||||
{
|
||||
total = std::min(size - (reader - writer + 1), amount);
|
||||
|
||||
if (total == 0)
|
||||
return 0;
|
||||
|
||||
unsigned int rd1 = size - reader;
|
||||
unsigned int rd2 = total - rd1;
|
||||
|
||||
// fprintf(stderr, "%p> 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[reader]), rd1);
|
||||
memcpy((void *) &(value[rd1]), (const void *) (buffer), rd2);
|
||||
}
|
||||
else
|
||||
{
|
||||
total = std::min((writer_less ? amount : writer - (reader + 1)), amount);
|
||||
|
||||
if (total == 0)
|
||||
return 0;
|
||||
|
||||
// fprintf(stderr, "%p> p full read: %d/%d [r=%d/w=%d]\n", this, total, size, reader, writer);
|
||||
|
||||
/* we are talking about buffers here, man! */
|
||||
memcpy((void *) value, (const void *) &(buffer[reader]), total);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
unsigned int new_reader = (((cache.reader.complete * _block) + cache.reader.partial) + total) % size;
|
||||
|
||||
/* jump the reader forward */
|
||||
Buffer_pointer index((unsigned int)floor((double)new_reader / (double)_block),
|
||||
(unsigned short)(new_reader % _block));
|
||||
|
||||
if (update(cache.reader, index))
|
||||
{
|
||||
// fprintf(stderr, "%p> p read end: %d [block=%d]\n", this, new_reader, _block);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (true);
|
||||
|
||||
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 reader = cache.reader.complete;
|
||||
const unsigned int writer = cache.writer.complete;
|
||||
|
||||
const bool writer_less = writer < reader;
|
||||
|
||||
unsigned int total = 0;
|
||||
|
||||
/* should we go around the buffer for reading? */
|
||||
if (writer_less && (reader + amount >= _size))
|
||||
{
|
||||
total = std::min(_size - (reader - writer + 1), amount);
|
||||
|
||||
if (total == 0)
|
||||
return 0;
|
||||
|
||||
unsigned int rd1 = _size - reader;
|
||||
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[reader]), _block * rd1);
|
||||
fd.write((const char *) (buffer), _block * rd2);
|
||||
}
|
||||
else
|
||||
{
|
||||
total = std::min((!writer_less ? writer - (reader + 1) : amount), amount);
|
||||
|
||||
if (total == 0)
|
||||
return 0;
|
||||
|
||||
// fprintf(stderr, "%p> full read: %d/%d [%d/%d]\n", this, total, _size, reader, writer);
|
||||
|
||||
/* we are talking about buffers here, man! */
|
||||
fd.write((const char *) &(buffer[reader]), _block * total);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
/* jump the reader forward */
|
||||
Buffer_pointer index(cache.reader);
|
||||
index.complete = (index.complete + total) % _size;
|
||||
|
||||
if (update(cache.reader, index))
|
||||
break;
|
||||
}
|
||||
while (true);
|
||||
|
||||
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;
|
||||
|
||||
const unsigned int reader = cache.reader.complete;
|
||||
const unsigned int writer = cache.writer.complete;
|
||||
|
||||
const unsigned int dest = writer - 1;
|
||||
|
||||
const bool reader_less = reader < writer;
|
||||
|
||||
unsigned int real_amount = 0;
|
||||
|
||||
/* should we go around the buffer for writing? */
|
||||
if (reader_less && ((writer + amount) > _size))
|
||||
{
|
||||
/* Documentation of the formula used in the 'if' below.
|
||||
*
|
||||
* [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.
|
||||
*
|
||||
*/
|
||||
|
||||
if ((_size - (writer - reader + 1)) <= amount)
|
||||
return false;
|
||||
|
||||
unsigned int wr1 = _size - writer + 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);
|
||||
|
||||
unsigned int char_amount = 0;
|
||||
|
||||
/* one partial write on the buffer (at the end) */
|
||||
fd.read((char *) &(buffer[dest]), _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
|
||||
{
|
||||
if (!reader_less && ((reader - writer) <= amount))
|
||||
return false;
|
||||
|
||||
// fprintf(stderr, "%p> full write: %d/%d [%d/%d]\n", this, amount, _size, reader, writer);
|
||||
|
||||
/* we are talking about buffers here, man! */
|
||||
fd.read((char *) &(buffer[dest]), _block * amount);
|
||||
|
||||
real_amount = fd.gcount() / _block;
|
||||
}
|
||||
|
||||
_pointers.writer.complete = ((dest + real_amount) % _size) + 1;
|
||||
_pointers.writer.partial = 1;
|
||||
|
||||
return real_amount;
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
#!/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 "$@"
|
|
@ -1,505 +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 <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>
|
||||
|
||||
#ifndef _VERBOSE_HPP_
|
||||
#define _VERBOSE_HPP_
|
||||
|
||||
struct Verbose
|
||||
{
|
||||
typedef enum
|
||||
{
|
||||
K_CM_SEIZE = CM_SEIZE,
|
||||
K_CM_SYNC_SEIZE = CM_SYNC_SEIZE,
|
||||
#if K3L_AT_LEAST(1,6,0)
|
||||
K_CM_SIP_REGISTER = CM_SIP_REGISTER,
|
||||
#endif
|
||||
K_CM_DIAL_DTMF = CM_DIAL_DTMF,
|
||||
K_CM_DISCONNECT = CM_DISCONNECT,
|
||||
K_CM_CONNECT = CM_CONNECT,
|
||||
K_CM_PRE_CONNECT = CM_PRE_CONNECT,
|
||||
K_CM_CAS_CHANGE_LINE_STT = CM_CAS_CHANGE_LINE_STT,
|
||||
K_CM_CAS_SEND_MFC = CM_CAS_SEND_MFC,
|
||||
K_CM_SET_FORWARD_CHANNEL = CM_SET_FORWARD_CHANNEL,
|
||||
K_CM_CAS_SET_MFC_DETECT_MODE = CM_CAS_SET_MFC_DETECT_MODE,
|
||||
K_CM_DROP_COLLECT_CALL = CM_DROP_COLLECT_CALL,
|
||||
K_CM_MAKE_CALL = CM_MAKE_CALL,
|
||||
K_CM_RINGBACK = CM_RINGBACK,
|
||||
K_CM_USER_INFORMATION = CM_USER_INFORMATION,
|
||||
#if !K3L_AT_LEAST(2,2,0)
|
||||
K_CM_VOIP_SEIZE = CM_VOIP_SEIZE, //deprecated
|
||||
#endif
|
||||
K_CM_LOCK_INCOMING = CM_LOCK_INCOMING,
|
||||
K_CM_UNLOCK_INCOMING = CM_UNLOCK_INCOMING,
|
||||
K_CM_LOCK_OUTGOING = CM_LOCK_OUTGOING,
|
||||
K_CM_UNLOCK_OUTGOING = CM_UNLOCK_OUTGOING,
|
||||
K_CM_START_SEND_FAIL = CM_START_SEND_FAIL,
|
||||
K_CM_STOP_SEND_FAIL = CM_STOP_SEND_FAIL,
|
||||
K_CM_END_OF_NUMBER = CM_END_OF_NUMBER,
|
||||
#if K3L_AT_LEAST(1,6,0)
|
||||
K_CM_SS_TRANSFER = CM_SS_TRANSFER,
|
||||
K_CM_GET_SMS = CM_GET_SMS,
|
||||
K_CM_PREPARE_SMS = CM_PREPARE_SMS,
|
||||
K_CM_SEND_SMS = CM_SEND_SMS,
|
||||
#endif
|
||||
#if K3L_HAS_MPTY_SUPPORT
|
||||
K_CM_HOLD_SWITCH = CM_HOLD_SWITCH,
|
||||
K_CM_MPTY_CONF = CM_MPTY_CONF,
|
||||
K_CM_MPTY_SPLIT = CM_MPTY_SPLIT,
|
||||
#endif
|
||||
K_CM_ENABLE_DTMF_SUPPRESSION = CM_ENABLE_DTMF_SUPPRESSION,
|
||||
K_CM_DISABLE_DTMF_SUPPRESSION = CM_DISABLE_DTMF_SUPPRESSION,
|
||||
K_CM_ENABLE_AUDIO_EVENTS = CM_ENABLE_AUDIO_EVENTS,
|
||||
K_CM_DISABLE_AUDIO_EVENTS = CM_DISABLE_AUDIO_EVENTS,
|
||||
K_CM_ENABLE_CALL_PROGRESS = CM_ENABLE_CALL_PROGRESS,
|
||||
K_CM_DISABLE_CALL_PROGRESS = CM_DISABLE_CALL_PROGRESS,
|
||||
K_CM_FLASH = CM_FLASH,
|
||||
K_CM_ENABLE_PULSE_DETECTION = CM_ENABLE_PULSE_DETECTION,
|
||||
K_CM_DISABLE_PULSE_DETECTION = CM_DISABLE_PULSE_DETECTION,
|
||||
K_CM_ENABLE_ECHO_CANCELLER = CM_ENABLE_ECHO_CANCELLER,
|
||||
K_CM_DISABLE_ECHO_CANCELLER = CM_DISABLE_ECHO_CANCELLER,
|
||||
K_CM_ENABLE_AGC = CM_ENABLE_AGC,
|
||||
K_CM_DISABLE_AGC = CM_DISABLE_AGC,
|
||||
K_CM_ENABLE_HIGH_IMP_EVENTS = CM_ENABLE_HIGH_IMP_EVENTS,
|
||||
K_CM_DISABLE_HIGH_IMP_EVENTS = CM_DISABLE_HIGH_IMP_EVENTS,
|
||||
#if K3L_AT_LEAST(1,6,0)
|
||||
K_CM_ENABLE_CALL_ANSWER_INFO = CM_ENABLE_CALL_ANSWER_INFO,
|
||||
K_CM_DISABLE_CALL_ANSWER_INFO = CM_DISABLE_CALL_ANSWER_INFO,
|
||||
#endif
|
||||
K_CM_RESET_LINK = CM_RESET_LINK,
|
||||
#if K3L_AT_LEAST(1,6,0)
|
||||
K_CM_CLEAR_LINK_ERROR_COUNTER = CM_CLEAR_LINK_ERROR_COUNTER,
|
||||
#endif
|
||||
K_CM_SEND_DTMF = CM_SEND_DTMF,
|
||||
K_CM_STOP_AUDIO = CM_STOP_AUDIO,
|
||||
K_CM_HARD_RESET = CM_HARD_RESET,
|
||||
K_CM_SEND_TO_CTBUS = CM_SEND_TO_CTBUS,
|
||||
K_CM_RECV_FROM_CTBUS = CM_RECV_FROM_CTBUS,
|
||||
K_CM_SETUP_H100 = CM_SETUP_H100,
|
||||
K_CM_MIXER = CM_MIXER,
|
||||
K_CM_CLEAR_MIXER = CM_CLEAR_MIXER,
|
||||
K_CM_PLAY_FROM_FILE = CM_PLAY_FROM_FILE,
|
||||
K_CM_RECORD_TO_FILE = CM_RECORD_TO_FILE,
|
||||
K_CM_PLAY_FROM_STREAM = CM_PLAY_FROM_STREAM,
|
||||
K_CM_INTERNAL_PLAY = CM_INTERNAL_PLAY,
|
||||
K_CM_STOP_PLAY = CM_STOP_PLAY,
|
||||
K_CM_STOP_RECORD = CM_STOP_RECORD,
|
||||
K_CM_PAUSE_PLAY = CM_PAUSE_PLAY,
|
||||
K_CM_PAUSE_RECORD = CM_PAUSE_RECORD,
|
||||
K_CM_RESUME_PLAY = CM_RESUME_PLAY,
|
||||
K_CM_RESUME_RECORD = CM_RESUME_RECORD,
|
||||
K_CM_INCREASE_VOLUME = CM_INCREASE_VOLUME,
|
||||
K_CM_DECREASE_VOLUME = CM_DECREASE_VOLUME,
|
||||
K_CM_LISTEN = CM_LISTEN,
|
||||
K_CM_STOP_LISTEN = CM_STOP_LISTEN,
|
||||
K_CM_PREPARE_FOR_LISTEN = CM_PREPARE_FOR_LISTEN,
|
||||
K_CM_PLAY_SOUND_CARD = CM_PLAY_SOUND_CARD,
|
||||
K_CM_STOP_SOUND_CARD = CM_STOP_SOUND_CARD,
|
||||
K_CM_MIXER_CTBUS = CM_MIXER_CTBUS,
|
||||
K_CM_PLAY_FROM_STREAM_EX = CM_PLAY_FROM_STREAM_EX,
|
||||
K_CM_INTERNAL_PLAY_EX = CM_INTERNAL_PLAY_EX,
|
||||
K_CM_ENABLE_PLAYER_AGC = CM_ENABLE_PLAYER_AGC,
|
||||
K_CM_DISABLE_PLAYER_AGC = CM_DISABLE_PLAYER_AGC,
|
||||
K_CM_START_STREAM_BUFFER = CM_START_STREAM_BUFFER,
|
||||
K_CM_ADD_STREAM_BUFFER = CM_ADD_STREAM_BUFFER,
|
||||
K_CM_STOP_STREAM_BUFFER = CM_STOP_STREAM_BUFFER,
|
||||
K_CM_SEND_BEEP = CM_SEND_BEEP,
|
||||
K_CM_SEND_BEEP_CONF = CM_SEND_BEEP_CONF,
|
||||
K_CM_ADD_TO_CONF = CM_ADD_TO_CONF,
|
||||
K_CM_REMOVE_FROM_CONF = CM_REMOVE_FROM_CONF,
|
||||
K_CM_RECORD_TO_FILE_EX = CM_RECORD_TO_FILE_EX,
|
||||
K_CM_SET_VOLUME = CM_SET_VOLUME,
|
||||
K_CM_SET_LINE_CONDITION = CM_SET_LINE_CONDITION,
|
||||
K_CM_SEND_LINE_CONDITION = CM_SEND_LINE_CONDITION,
|
||||
K_CM_SET_CALLER_CATEGORY = CM_SET_CALLER_CATEGORY,
|
||||
K_CM_DIAL_MFC = CM_DIAL_MFC,
|
||||
#if !K3L_AT_LEAST(2,0,0)
|
||||
K_CM_VOIP_START_DEBUG = CM_VOIP_START_DEBUG,
|
||||
K_CM_VOIP_STOP_DEBUG = CM_VOIP_STOP_DEBUG,
|
||||
K_CM_VOIP_DUMP_STAT = CM_VOIP_DUMP_STAT,
|
||||
K_CM_ISDN_DEBUG = CM_ISDN_DEBUG,
|
||||
K_CM_PING = CM_PING,
|
||||
K_CM_LOG_REQUEST = CM_LOG_REQUEST,
|
||||
K_CM_LOG_CREATE_DISPATCHER = CM_LOG_CREATE_DISPATCHER,
|
||||
K_CM_LOG_DESTROY_DISPATCHER = CM_LOG_DESTROY_DISPATCHER,
|
||||
#endif
|
||||
#if K3L_AT_LEAST(1,6,0)
|
||||
K_CM_START_CADENCE = CM_START_CADENCE,
|
||||
K_CM_STOP_CADENCE = CM_STOP_CADENCE,
|
||||
K_CM_CHECK_NEW_SMS = CM_CHECK_NEW_SMS,
|
||||
K_CM_SEND_TO_MODEM = CM_SEND_TO_MODEM,
|
||||
#endif
|
||||
#if K3L_AT_LEAST(2,1,0)
|
||||
K_CM_START_FAX_TX = CM_START_FAX_TX,
|
||||
K_CM_STOP_FAX_TX = CM_STOP_FAX_TX,
|
||||
K_CM_ADD_FAX_FILE = CM_ADD_FAX_FILE,
|
||||
K_CM_ADD_FAX_PAGE_BREAK = CM_ADD_FAX_PAGE_BREAK,
|
||||
K_CM_START_FAX_RX = CM_START_FAX_RX,
|
||||
K_CM_STOP_FAX_RX = CM_STOP_FAX_RX,
|
||||
K_CM_SIM_CARD_SELECT = CM_SIM_CARD_SELECT,
|
||||
#endif
|
||||
|
||||
#if K3L_AT_LEAST(2,1,0)
|
||||
K_CM_NOTIFY_WATCHDOG = CM_NOTIFY_WATCHDOG,
|
||||
K_CM_STOP_WATCHDOG = CM_STOP_WATCHDOG,
|
||||
K_CM_WATCHDOG_COUNT = CM_WATCHDOG_COUNT,
|
||||
K_CM_START_WATCHDOG = CM_START_WATCHDOG,
|
||||
#endif
|
||||
|
||||
}
|
||||
kcommand;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
K_EV_CHANNEL_FREE = EV_CHANNEL_FREE,
|
||||
K_EV_CONNECT = EV_CONNECT,
|
||||
K_EV_DISCONNECT = EV_DISCONNECT,
|
||||
K_EV_CALL_SUCCESS = EV_CALL_SUCCESS,
|
||||
K_EV_CALL_FAIL = EV_CALL_FAIL,
|
||||
K_EV_NO_ANSWER = EV_NO_ANSWER,
|
||||
K_EV_BILLING_PULSE = EV_BILLING_PULSE,
|
||||
K_EV_SEIZE_SUCCESS = EV_SEIZE_SUCCESS,
|
||||
K_EV_SEIZE_FAIL = EV_SEIZE_FAIL,
|
||||
K_EV_SEIZURE_START = EV_SEIZURE_START,
|
||||
K_EV_CAS_LINE_STT_CHANGED = EV_CAS_LINE_STT_CHANGED,
|
||||
K_EV_CAS_MFC_RECV = EV_CAS_MFC_RECV,
|
||||
K_EV_NEW_CALL = EV_NEW_CALL,
|
||||
K_EV_USER_INFORMATION = EV_USER_INFORMATION,
|
||||
K_EV_DIALED_DIGIT = EV_DIALED_DIGIT,
|
||||
#if K3L_AT_LEAST(1,6,0)
|
||||
K_EV_SIP_REGISTER_INFO = EV_SIP_REGISTER_INFO,
|
||||
K_EV_RING_DETECTED = EV_RING_DETECTED,
|
||||
#endif
|
||||
K_EV_CALL_HOLD_START = EV_CALL_HOLD_START,
|
||||
K_EV_CALL_HOLD_STOP = EV_CALL_HOLD_STOP,
|
||||
#if K3L_AT_LEAST(1,6,0)
|
||||
K_EV_SS_TRANSFER_FAIL = EV_SS_TRANSFER_FAIL,
|
||||
K_EV_FLASH = EV_FLASH,
|
||||
#endif
|
||||
K_EV_DTMF_DETECTED = EV_DTMF_DETECTED,
|
||||
K_EV_DTMF_SEND_FINISH = EV_DTMF_SEND_FINISH,
|
||||
K_EV_AUDIO_STATUS = EV_AUDIO_STATUS,
|
||||
K_EV_CADENCE_RECOGNIZED = EV_CADENCE_RECOGNIZED,
|
||||
K_EV_END_OF_STREAM = EV_END_OF_STREAM,
|
||||
K_EV_PULSE_DETECTED = EV_PULSE_DETECTED,
|
||||
K_EV_POLARITY_REVERSAL = EV_POLARITY_REVERSAL,
|
||||
#if K3L_AT_LEAST(1,6,0)
|
||||
K_EV_ISDN_PROGRESS_INDICATOR = EV_ISDN_PROGRESS_INDICATOR,
|
||||
K_EV_CALL_ANSWER_INFO = EV_CALL_ANSWER_INFO,
|
||||
K_EV_COLLECT_CALL = EV_COLLECT_CALL,
|
||||
K_EV_SIP_DTMF_DETECTED = EV_SIP_DTMF_DETECTED,
|
||||
K_EV_RECV_FROM_MODEM = EV_RECV_FROM_MODEM,
|
||||
K_EV_NEW_SMS = EV_NEW_SMS,
|
||||
K_EV_SMS_INFO = EV_SMS_INFO,
|
||||
K_EV_SMS_DATA = EV_SMS_DATA,
|
||||
K_EV_SMS_SEND_RESULT = EV_SMS_SEND_RESULT,
|
||||
#endif
|
||||
#if K3L_HAS_MPTY_SUPPORT
|
||||
K_EV_CALL_MPTY_START = EV_CALL_MPTY_START,
|
||||
K_EV_CALL_MPTY_STOP = EV_CALL_MPTY_STOP,
|
||||
K_EV_GSM_COMMAND_STATUS = EV_GSM_COMMAND_STATUS,
|
||||
#endif
|
||||
K_EV_CHANNEL_FAIL = EV_CHANNEL_FAIL,
|
||||
K_EV_REFERENCE_FAIL = EV_REFERENCE_FAIL,
|
||||
K_EV_INTERNAL_FAIL = EV_INTERNAL_FAIL,
|
||||
K_EV_HARDWARE_FAIL = EV_HARDWARE_FAIL,
|
||||
K_EV_LINK_STATUS = EV_LINK_STATUS,
|
||||
#if K3L_AT_LEAST(1,6,0)
|
||||
K_EV_PHYSICAL_LINK_UP = EV_PHYSICAL_LINK_UP,
|
||||
K_EV_PHYSICAL_LINK_DOWN = EV_PHYSICAL_LINK_DOWN,
|
||||
#endif
|
||||
K_EV_CLIENT_RECONNECT = EV_CLIENT_RECONNECT,
|
||||
K_EV_VOIP_SEIZURE = EV_VOIP_SEIZURE,
|
||||
K_EV_SEIZURE = EV_SEIZURE,
|
||||
|
||||
#if K3L_AT_LEAST(2,1,0)
|
||||
K_EV_FAX_CHANNEL_FREE = EV_FAX_CHANNEL_FREE,
|
||||
K_EV_FAX_FILE_SENT = EV_FAX_FILE_SENT,
|
||||
K_EV_FAX_FILE_FAIL = EV_FAX_FILE_FAIL,
|
||||
K_EV_FAX_MESSAGE_CONFIRMATION = EV_FAX_MESSAGE_CONFIRMATION,
|
||||
K_EV_FAX_TX_TIMEOUT = EV_FAX_TX_TIMEOUT,
|
||||
K_EV_FAX_PAGE_CONFIRMATION = EV_FAX_PAGE_CONFIRMATION,
|
||||
K_EV_FAX_REMOTE_INFO = EV_FAX_REMOTE_INFO,
|
||||
#endif
|
||||
|
||||
#if K3L_AT_LEAST(2,1,0)
|
||||
K_EV_WATCHDOG_COUNT = EV_WATCHDOG_COUNT,
|
||||
#endif
|
||||
|
||||
#if !K3L_AT_LEAST(2,0,0)
|
||||
K_EV_PONG = EV_PONG,
|
||||
#endif
|
||||
}
|
||||
kevent;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
R2_COUNTRY_ARG = 1,
|
||||
R2_COUNTRY_BRA = 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(K3LAPI & api): _api(api) {};
|
||||
|
||||
#if K3L_AT_LEAST(2,0,0)
|
||||
std::string event(int32, K3L_EVENT*, R2CountryType r2_country = R2_COUNTRY_BRA,
|
||||
Presentation fmt = HUMAN);
|
||||
#else
|
||||
std::string event(int32, K3L_EVENT*, Presentation fmt = HUMAN);
|
||||
#endif
|
||||
|
||||
std::string channelStatus(int32, int32, int32, Presentation fmt = HUMAN);
|
||||
|
||||
/* end of dynamic (object) stuff */
|
||||
|
||||
protected:
|
||||
K3LAPI & _api;
|
||||
|
||||
/* used internally */
|
||||
struct internal_not_found {};
|
||||
|
||||
public:
|
||||
|
||||
/* static (class) stuff */
|
||||
|
||||
static std::string echoLocation(KEchoLocation, Presentation fmt = HUMAN);
|
||||
static std::string echoCancellerConfig(KEchoCancellerConfig, Presentation fmt = HUMAN);
|
||||
|
||||
#if K3L_AT_LEAST(2,0,0)
|
||||
static std::string event(KSignaling, int32, K3L_EVENT*, R2CountryType = R2_COUNTRY_BRA,
|
||||
Presentation fmt = HUMAN);
|
||||
#else
|
||||
static std::string event(KSignaling, int32, K3L_EVENT*, Presentation fmt = HUMAN);
|
||||
#endif
|
||||
|
||||
#if K3L_AT_LEAST(2,0,0)
|
||||
static std::string command(int32, K3L_COMMAND*, R2CountryType = R2_COUNTRY_BRA,
|
||||
Presentation fmt = HUMAN);
|
||||
static std::string command(int32, int32, int32, const char *, R2CountryType = R2_COUNTRY_BRA,
|
||||
Presentation fmt = HUMAN);
|
||||
#else
|
||||
static std::string command(int32, K3L_COMMAND*, Presentation fmt = HUMAN);
|
||||
static std::string command(int32, int32, int32, const char *, Presentation fmt = HUMAN);
|
||||
#endif
|
||||
|
||||
|
||||
static std::string deviceName(KDeviceType, int32, Presentation fmt = HUMAN);
|
||||
|
||||
static std::string deviceType(KDeviceType, Presentation fmt = HUMAN);
|
||||
static std::string deviceModel(KDeviceType, int32, Presentation fmt = HUMAN);
|
||||
|
||||
static std::string channelFeatures(int32, Presentation fmt = HUMAN);
|
||||
static std::string signaling(KSignaling, Presentation fmt = HUMAN);
|
||||
static std::string systemObject(KSystemObject, Presentation fmt = HUMAN);
|
||||
static std::string mixerTone(KMixerTone, Presentation fmt = HUMAN);
|
||||
static std::string mixerSource(KMixerSource, Presentation fmt = HUMAN);
|
||||
|
||||
static std::string seizeFail(KSeizeFail, Presentation fmt = HUMAN);
|
||||
|
||||
#if K3L_AT_LEAST(2,0,0)
|
||||
static std::string callFail(KSignaling, R2CountryType, int32, Presentation fmt = HUMAN);
|
||||
#else
|
||||
static std::string callFail(KSignaling, int32, Presentation fmt = HUMAN);
|
||||
#endif
|
||||
|
||||
static std::string channelFail(KSignaling, int32, Presentation fmt = HUMAN);
|
||||
static std::string internalFail(KInternalFail, Presentation fmt = HUMAN);
|
||||
|
||||
static std::string linkErrorCounter(KLinkErrorCounter, Presentation fmt = HUMAN);
|
||||
|
||||
static std::string linkStatus(KSignaling, int32, Presentation fmt = HUMAN);
|
||||
static std::string channelStatus(KSignaling, int32, Presentation fmt = HUMAN);
|
||||
static std::string callStatus(KCallStatus, Presentation fmt = HUMAN);
|
||||
static std::string status(KLibraryStatus, Presentation fmt = HUMAN);
|
||||
|
||||
#if K3L_AT_LEAST(2,0,0)
|
||||
static std::string signGroupB(KSignGroupB, R2CountryType contry = R2_COUNTRY_BRA,
|
||||
Presentation fmt = HUMAN);
|
||||
#else
|
||||
static std::string signGroupB(KSignGroupB, Presentation fmt = HUMAN);
|
||||
#endif
|
||||
|
||||
#if K3L_AT_LEAST(2,0,0)
|
||||
static std::string signGroupII(KSignGroupII, R2CountryType contry = R2_COUNTRY_BRA,
|
||||
Presentation fmt = HUMAN);
|
||||
#else
|
||||
static std::string signGroupII(KSignGroupII, Presentation fmt = HUMAN);
|
||||
#endif
|
||||
|
||||
static std::string h100configIndex(KH100ConfigIndex, Presentation fmt = HUMAN);
|
||||
|
||||
static std::string eventName(int32);
|
||||
static std::string commandName(int32);
|
||||
|
||||
#if K3L_AT_LEAST(1,5,0)
|
||||
static std::string sipFailures(KSIP_Failures, Presentation fmt = HUMAN);
|
||||
#endif
|
||||
|
||||
#if K3L_AT_LEAST(1,5,1)
|
||||
static std::string isdnCause(KQ931Cause, Presentation fmt = HUMAN);
|
||||
#endif
|
||||
|
||||
#if K3L_AT_LEAST(1,5,2)
|
||||
static std::string isdnDebug(int32, Presentation fmt = HUMAN);
|
||||
#endif
|
||||
|
||||
#if K3L_AT_LEAST(1,6,0)
|
||||
static std::string callStartInfo(KCallStartInfo, Presentation fmt = HUMAN);
|
||||
|
||||
static std::string gsmCallCause(KGsmCallCause, Presentation fmt = HUMAN);
|
||||
static std::string gsmMobileCause(KGsmMobileCause, Presentation fmt = HUMAN);
|
||||
static std::string gsmSmsCause(KGsmSmsCause, Presentation fmt = HUMAN);
|
||||
|
||||
static std::string q931ProgressIndication(KQ931ProgressIndication,
|
||||
Presentation fmt = HUMAN);
|
||||
#endif
|
||||
|
||||
#if K3L_AT_LEAST(2,1,0)
|
||||
static std::string faxResult(KFaxResult code, Presentation fmt = HUMAN);
|
||||
static std::string faxFileErrorCause(KFaxFileErrorCause code, Presentation fmt = HUMAN);
|
||||
#endif
|
||||
|
||||
/* end of static (class) stuff */
|
||||
|
||||
private:
|
||||
static std::string internal_deviceType(KDeviceType);
|
||||
static std::string internal_deviceModel(KDeviceType, int32);
|
||||
|
||||
#if K3L_AT_LEAST(1,5,0)
|
||||
static std::string internal_sipFailures(KSIP_Failures, Presentation fmt = HUMAN);
|
||||
#endif
|
||||
#if K3L_AT_LEAST(1,5,1)
|
||||
static std::string internal_isdnCause(KQ931Cause, Presentation fmt = HUMAN);
|
||||
#endif
|
||||
|
||||
#if K3L_AT_LEAST(2,0,0)
|
||||
static std::string internal_signGroupB(KSignGroupB, R2CountryType contry, Presentation fmt = HUMAN);
|
||||
static std::string internal_signGroupII(KSignGroupII, R2CountryType contry, Presentation fmt = HUMAN);
|
||||
#else
|
||||
static std::string internal_signGroupB(KSignGroupB, Presentation fmt = HUMAN);
|
||||
static std::string internal_signGroupII(KSignGroupII, Presentation fmt = HUMAN);
|
||||
#endif
|
||||
|
||||
#if K3L_AT_LEAST(1,6,0)
|
||||
static std::string internal_gsmCallCause(KGsmCallCause, Presentation fmt = HUMAN);
|
||||
static std::string internal_gsmMobileCause(KGsmMobileCause, Presentation fmt = HUMAN);
|
||||
static std::string internal_gsmSmsCause(KGsmSmsCause, Presentation fmt = HUMAN);
|
||||
|
||||
static std::string internal_q931ProgressIndication(KQ931ProgressIndication, 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)
|
||||
{};
|
||||
|
||||
Type type;
|
||||
int32 device;
|
||||
int32 object;
|
||||
};
|
||||
|
||||
static void generate(std::string &, std::string &, Target, std::string &);
|
||||
|
||||
static std::string show(std::string &, std::string, Target, std::string &);
|
||||
static std::string show(std::string &, std::string, Target);
|
||||
|
||||
template < typename ReturnType >
|
||||
static ReturnType presentation(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_ */
|
|
@ -37,17 +37,22 @@
|
|||
</li><li><b>context-fxs</b>: Contexto de entrada para placas FXS (o padrão é "khomp-DD-CC", onde "DD" será substituído, no momento da ligação, pelo número do dispositivo, "CC" pelo número do canal, e "SSSS" pelo número serial do dispositivo);
|
||||
</li><li><b>context-gsm-call</b> (ou "context-gsm"): Contexto de entrada para ligações GSM (o padrão é "khomp-DD-CC", onde "DD" será substituído no momento da ligação pelo número do dispositivo, "CC" pelo número do canal, e "SSSS" pelo número serial do dispositivo);
|
||||
</li><li><b>context-gsm-sms</b>: Contexto de entrada para SMSs (o padrão é "khomp-sms-DD-CC", onde "DD" será substituído pelo número de dispositivo, "CC" pelo número do canal, e "SSSS" pelo número serial do dispositivo);
|
||||
</li><li><b>context-pr</b>: Contexto de entrada para ligações em placas KPR (o padrão é "khomp-DD-CC", onde "DD" será substituído, no momento da ligação, pelo número do dispositivo, "CC" pelo número do canal);
|
||||
</li><li><b>context-pr</b>: Contexto de entrada para ligações em placas KPR (o padrão é "khomp-DD-CC", onde "DD" será substituído, no momento da ligação, pelo número do dispositivo, "CC" pelo número do canal);
|
||||
</li><li><b>delay-ringback-co</b>: Define o tempo de <i>delay</i> para ativar a geração de tom de controle de chamada (<i>ringback</i>) pelo Endpoint da Khomp quando há uma indicação de <i>ringback</i>, e não há áudio sendo enviado por quem indicou a situação de controle da chamada;
|
||||
</li><li><b>delay-ringback-pbx</b>: Define o tempo de <i>delay</i> para ativar a geração de controle de chamada (<i>ringback</i>) pelo Endpoint da Khomp quando há uma indicação de <i>ringback</i>, e o áudio de controle enviado não possui nenhum tom (ou seja, está em silêncio);
|
||||
</li><li><b>disconnect-delay</b>: Define o tempo em milissegundos para realizar o processamento de um evento de desconexão, para ignorar situações onde outros equipamentos realizam o duplo atendimento para derrubar chamadas a cobrar;
|
||||
</li><li><b>drop-collect-call</b>: Ativa ("yes") ou desativa ("no") o derrubamento de chamadas à cobrar. Caso ativo, todas as chamadas à cobrar serão derrubadas não importando o que foi ajustado na variável KDropCollectCall (o valor padrão é "no");
|
||||
</li><li><b>echo-canceller</b>: Ativa ("yes") ou desativa ("no") o cancelamento de eco automático pelo Endpoint;
|
||||
</li><li><b>flash-to-digits</b>: Define os dígitos para serem enviados quando o FLASH é detectado na FXS;
|
||||
</li><li><b>fxo-send-pre-audio</b>: Quando ativada ("yes") libera canal de áudio sainte antes da conexão da chamada em placas KFXO (o valor padrão é "yes");
|
||||
</li><li><b>fxs-digit-timeout</b>: Define o <i>timeout</i>, em segundos, entre dígitos na FXS;
|
||||
</li><li><b>fxs-global-orig</b>: Número inicial para numeração seqüencial de ramais das placas <b>KFXS</b> que não estiverem listadas na seção <b><fxs-branches></b> (a numeração segue ordem crescente por número da placa e número do canal físico) (o padrão é "0");
|
||||
</li><li><b>fxs-co-dialtone</b>: Seqüências de números, separados por vírgula, que disparam um tom contínuo (de central pública) em ramais FXS (ex: "0,99" faz com que, ao discar "0" ou "99", o usuário receba o tom de linha contínuo) (o padrão é vazio);
|
||||
</li><li><b>fxs-bina</b>: Quando ativada ("yes"), ligações para ramais FXS enviarão os dígitos correspondentes ao telefone de origem em sinalização BINA DTMF (o valor padrão é "no");
|
||||
</li><li><b>ignore-letter-dtmfs</b>: Define se o canal deve ignorar DTMFs incomuns detectados pela placa (A, B, C e D). Entretanto, se você necessita passar esses dígitos pela placa, você deve ajustar esta opção para "no" (o valor padrão é "yes");
|
||||
</li><li><b>input-volume</b>: Define o volume de entrada das ligações, varia de -10 a +10 ;
|
||||
</li><li><b>kommuter-activation</b>: Define se a ativação de dispositivos kommuter encontrados no sistema será feita de forma automática ("auto"), ou de forma manual ("manual") pelo usuário, através do comando "khomp kommuter on/off";
|
||||
</li><li><b>kommuter-timeout</b>: Define o <i>timeout</i> (em segundos) com que os kommuters serão inicializados. Se chegarem a este <i>timeout</i> sem receberem notificação do channel, os dispositivos irão comutar para o estado "desligado". O valor mínimo é "0" , onde os links permanecerão sempre comutados no estado "ligado", e o valor máximo é "255";
|
||||
</li><li><b>language</b>: Define idioma para ligações nas placas Khomp;
|
||||
</li><li><b>log-to-console</b>: Define mensagens de log que devem ser impressas na console;
|
||||
</li><li><b>log-to-disk</b>: Define mensagens de log que devem ser salvar em disco;
|
||||
</li><li><b>out-of-band-dtmfs</b>: Ativa ("yes") ou desativa ("no") a supressão DTMF e o envio destes out-of-band;
|
||||
|
@ -55,12 +60,9 @@
|
|||
</li><li><b>pulse-forwarding</b>: Ativa ("yes") ou desativa ("no") a detecção de pulsos e a conversão dos mesmos em DTMFs;
|
||||
</li><li><b>r2-preconnect-wait</b>: Define o tempo de espera do envio da sinalização de ringback, no protocolo R2/MFC, para iniciar o envio de áudio de silêncio. Apenas utilizado quando "r2-strict-behaviour" estiver ajustado para "no";
|
||||
</li><li><b>r2-strict-behaviour</b>: Ativa ("yes") ou desativa ("no") o comportamento da sinalização R2/MFC conforme a norma define. O padrão é "no", e pode ser alterado para "yes" caso seja necessário receber/enviar dados precisos da sinalização do protocolo (condição de B, por exemplo);
|
||||
</li><li><b>ringback-delay-co</b>: Define o tempo de <i>delay</i> para ativar a geração de tom de controle de chamada (<i>ringback</i>) pelo Endpoint da Khomp quando há uma indicação de <i>ringback</i>, e não há áudio sendo enviado por quem indicou a situação de controle da chamada;
|
||||
</li><li><b>ringback-delay-pbx</b>: Define o tempo de <i>delay</i> para ativar a geração de controle de chamada (<i>ringback</i>) pelo Endpoint da Khomp quando há uma indicação de <i>ringback</i>, e o áudio de controle enviado não possui nenhum tom (ou seja, está em silêncio);
|
||||
</li><li><b>suppression-delay</b>: Ativa ("yes") ou desativa ("no") o delay necessário para supressão DTMF. Se desativado ("no"), também desativa supressão de DTMFs;
|
||||
</li><li><b>trace</b>: Define opções de depuração. Não deve ser utilizado em produção a não ser que estritamente necessário;
|
||||
</li><li><b>user-transfer-digits</b>: Define uma seqüência de dígitos DTMF para iniciar a transferencia entre o FreeSWITCH® e um outro PABX (utilizando sinalização de usuário, como QSig ou FXO FLASH);
|
||||
</li><li><b>flash-to-digits</b>: Define os dígitos para serem enviados quando o FLASH é detectado na FXS;
|
||||
</li></ul>
|
||||
<p><br />
|
||||
</p>
|
||||
|
@ -117,15 +119,13 @@
|
|||
<ul><li>context;
|
||||
</li><li>input-volume;
|
||||
</li><li>output-volume;
|
||||
</li><li>accountcode;
|
||||
</li><li>calleridnum;
|
||||
</li><li>calleridname;
|
||||
</li><li>mailbox;
|
||||
</li><li>flash-to-digits.
|
||||
</li></ul>
|
||||
<p>Cada opção é separada uma da outra por um pipe "|" ou uma barra "/" e definidas após dois pontos ":", exemplo:
|
||||
</p>
|
||||
<pre> <param name="200" value="language:en|context:master-branch" />
|
||||
<pre> <param name="200" value="input-volume:1|context:master-branch" />
|
||||
</pre>
|
||||
<p>Para maiores informações sobre a sintaxe e exemplos, favor consultar o arquivo de configuração.
|
||||
</p><p><br />
|
||||
|
|
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue