Merge branch 'master' of ssh://git.freeswitch.org/freeswitch
This commit is contained in:
commit
de66ad246f
|
@ -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;
|
||||
|
|
|
@ -5,8 +5,9 @@ fsdir=../..
|
|||
set -x
|
||||
cp Debug/mod/*.dll $fsdir/Debug/mod/
|
||||
cp mod_freetdm/Debug/*.pdb $fsdir/Debug/mod/
|
||||
cp Debug/*.dll $fsdir/Debug/
|
||||
cp Debug/*.pdb $fsdir/Debug/
|
||||
cp Debug/freetdm.dll $fsdir/Debug/
|
||||
cp Debug/ftmod_*.dll $fsdir/Debug/mod/
|
||||
cp Debug/*.pdb $fsdir/Debug/mod/
|
||||
#cp Debug/testsangomaboost.exe $fsdir/Debug/
|
||||
echo "FRIENDLY REMINDER: RECOMPILE ftmod_wanpipe WHENEVER YOU INSTALL NEW DRIVERS"
|
||||
set +x
|
||||
|
|
|
@ -161,10 +161,8 @@ Global
|
|||
{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
|
||||
|
|
|
@ -149,6 +149,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
|
||||
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
|
||||
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
|
||||
static const char* channel_get_variable(switch_core_session_t *session, switch_event_t *var_event, const char *variable_name);
|
||||
ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session_t **sp);
|
||||
void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream);
|
||||
void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream);
|
||||
|
@ -425,8 +426,11 @@ static switch_status_t channel_on_routing(switch_core_session_t *session)
|
|||
tech_pvt = switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel));
|
||||
assert(tech_pvt->ftdmchan != NULL);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel));
|
||||
|
||||
ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROCEED);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -837,9 +841,9 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
|
|||
assert(tech_pvt != NULL);
|
||||
|
||||
if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (ftdm_channel_call_check_hangup(tech_pvt->ftdmchan)) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
@ -852,7 +856,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
|
|||
switch (msg->message_id) {
|
||||
case SWITCH_MESSAGE_INDICATE_RINGING:
|
||||
{
|
||||
ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS);
|
||||
ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_RINGING);
|
||||
}
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
|
@ -884,9 +888,9 @@ static switch_status_t channel_receive_message_fxo(switch_core_session_t *sessio
|
|||
assert(tech_pvt != NULL);
|
||||
|
||||
if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
@ -935,7 +939,7 @@ static switch_status_t channel_receive_message_fxs(switch_core_session_t *sessio
|
|||
!switch_channel_test_flag(channel, CF_EARLY_MEDIA) &&
|
||||
!switch_channel_test_flag(channel, CF_RING_READY)
|
||||
) {
|
||||
ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_RING);
|
||||
ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_RINGING);
|
||||
switch_channel_mark_ring_ready(channel);
|
||||
}
|
||||
break;
|
||||
|
@ -1046,6 +1050,27 @@ switch_io_routines_t freetdm_io_routines = {
|
|||
/*.receive_message*/ channel_receive_message
|
||||
};
|
||||
|
||||
static const char* channel_get_variable(switch_core_session_t *session, switch_event_t *var_event, const char *variable_name)
|
||||
{
|
||||
const char *variable = NULL;
|
||||
|
||||
if (var_event) {
|
||||
if ((variable = switch_event_get_header(var_event, variable_name))) {
|
||||
return variable;
|
||||
}
|
||||
}
|
||||
if (session) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
if ((variable = switch_channel_get_variable(channel, variable_name))) {
|
||||
return variable;
|
||||
}
|
||||
}
|
||||
if ((variable = switch_core_get_variable(variable_name))) {
|
||||
return variable;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines
|
||||
that allocate memory or you will have 1 channel with memory allocated from another channel's pool!
|
||||
*/
|
||||
|
@ -1223,20 +1248,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
}
|
||||
}
|
||||
|
||||
if (session) {
|
||||
/* take out some other values from the session if they're present */
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
const char *freetdmvar;
|
||||
freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_capability");
|
||||
if (freetdmvar) {
|
||||
caller_data.bearer_capability = (uint8_t)atoi(freetdmvar);
|
||||
}
|
||||
freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_layer1");
|
||||
if (freetdmvar) {
|
||||
caller_data.bearer_layer1 = (uint8_t)atoi(freetdmvar);
|
||||
}
|
||||
}
|
||||
|
||||
if (switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN)) {
|
||||
caller_data.screen = 1;
|
||||
}
|
||||
|
@ -1245,29 +1256,37 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
caller_data.pres = 1;
|
||||
}
|
||||
|
||||
if (!zstr(dest)) {
|
||||
ftdm_set_string(caller_data.dnis.digits, dest);
|
||||
if ((var = channel_get_variable(session, var_event, "freetdm_bearer_capability"))) {
|
||||
caller_data.bearer_capability = (uint8_t)atoi(var);
|
||||
}
|
||||
|
||||
if ((var = switch_event_get_header(var_event, "freetdm_outbound_ton")) || (var = switch_core_get_variable("freetdm_outbound_ton"))) {
|
||||
if (!strcasecmp(var, "national")) {
|
||||
caller_data.dnis.type = FTDM_TON_NATIONAL;
|
||||
} else if (!strcasecmp(var, "international")) {
|
||||
caller_data.dnis.type = FTDM_TON_INTERNATIONAL;
|
||||
} else if (!strcasecmp(var, "local")) {
|
||||
caller_data.dnis.type = FTDM_TON_SUBSCRIBER_NUMBER;
|
||||
} else if (!strcasecmp(var, "unknown")) {
|
||||
caller_data.dnis.type = FTDM_TON_UNKNOWN;
|
||||
}
|
||||
if ((var = channel_get_variable(session, var_event, "freetdm_bearer_layer1"))) {
|
||||
caller_data.bearer_layer1 = (uint8_t)atoi(var);
|
||||
}
|
||||
|
||||
if ((var = channel_get_variable(session, var_event, "freetdm_screening_ind"))) {
|
||||
ftdm_set_screening_ind(var, &caller_data.screen);
|
||||
}
|
||||
|
||||
if ((var = channel_get_variable(session, var_event, "freetdm_presentation_ind"))) {
|
||||
ftdm_set_presentation_ind(var, &caller_data.pres);
|
||||
}
|
||||
|
||||
if ((var = channel_get_variable(session, var_event, "freetdm_outbound_ton"))) {
|
||||
ftdm_set_ton(var, &caller_data.dnis.type);
|
||||
} else {
|
||||
caller_data.dnis.type = outbound_profile->destination_number_ton;
|
||||
}
|
||||
|
||||
if ((var = switch_event_get_header(var_event, "freetdm_custom_call_data")) || (var = switch_core_get_variable("freetdm_custom_call_data"))) {
|
||||
if ((var = channel_get_variable(session, var_event, "freetdm_custom_call_data"))) {
|
||||
ftdm_set_string(caller_data.raw_data, var);
|
||||
caller_data.raw_data_len = (uint32_t)strlen(var);
|
||||
}
|
||||
|
||||
if (!zstr(dest)) {
|
||||
ftdm_set_string(caller_data.dnis.digits, dest);
|
||||
}
|
||||
|
||||
caller_data.dnis.plan = outbound_profile->destination_number_numplan;
|
||||
|
||||
/* blindly copy data from outbound_profile. They will be overwritten
|
||||
|
@ -1690,6 +1709,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
|
||||
default:
|
||||
{
|
||||
|
@ -1744,6 +1764,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
case FTDM_SIGEVENT_STOP:
|
||||
{
|
||||
private_t *tech_pvt = NULL;
|
||||
|
@ -1966,6 +1987,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
|
|||
status = ftdm_channel_from_event(sigmsg, &session);
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
|
||||
/* on DNIS received from the R2 forward side, return status == FTDM_BREAK to stop requesting DNIS */
|
||||
case FTDM_SIGEVENT_COLLECTED_DIGIT:
|
||||
|
@ -2028,6 +2051,14 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
|
|||
}
|
||||
break;
|
||||
|
||||
case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
|
||||
{
|
||||
ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to: %s\n",
|
||||
spanid, chanid, ftdm_signaling_status2str(sigstatus));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled event %d from R2 for channel %d:%d\n",
|
||||
|
@ -2059,10 +2090,16 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
|||
switch(sigmsg->event_id) {
|
||||
case FTDM_SIGEVENT_START:
|
||||
{
|
||||
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;
|
||||
|
||||
case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break;
|
||||
|
||||
case FTDM_SIGEVENT_STOP:
|
||||
case FTDM_SIGEVENT_RESTART:
|
||||
{
|
||||
|
@ -2118,7 +2155,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
|||
spanid, chanid, (uuid) ? uuid : "N/A");
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
|
||||
{
|
||||
ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus;
|
||||
|
@ -2126,6 +2163,10 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
|||
spanid, chanid, ftdm_signaling_status2str(sigstatus));
|
||||
}
|
||||
break;
|
||||
case FTDM_SIGEVENT_PROCEED:
|
||||
case FTDM_SIGEVENT_MSG:
|
||||
/* FS does not have handlers for these messages, so ignore them for now */
|
||||
break;
|
||||
default:
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n",
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openzap", "msvc\openzap.2005.vcproj", "{93B8812C-3EC4-4F78-8970-FFBFC99E167D}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testanalog", "msvc\testanalog\testanalog.2005.vcproj", "{BB833648-BAFF-4BE2-94DB-F8BB043C588C}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testisdn", "msvc\testisdn\testisdn.2005.vcproj", "{6DA6FD42-641D-4147-92F5-3BC4AAA6589B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_openzap", "mod_openzap\mod_openzap.2005.vcproj", "{FE3540C5-3303-46E0-A69E-D92F775687F1}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ozmod_analog", "src\ozmod\ozmod_analog\ozmod_analog.2005.vcproj", "{37C94798-6E33-4B4F-8EE0-C72A7DC91157}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ozmod_analog_em", "src\ozmod\ozmod_analog_em\ozmod_analog_em.2005.vcproj", "{C539D7C8-26A8-4A94-B938-77672165C130}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ozmod_isdn", "src\ozmod\ozmod_isdn\ozmod_isdn.2005.vcproj", "{729344A5-D5E9-434D-8EE8-AF8C6C795D15}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ozmod_wanpipe", "src\ozmod\ozmod_wanpipe\ozmod_wanpipe.2005.vcproj", "{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ozmod_pika", "src\ozmod\ozmod_pika\ozmod_pika.2005.vcproj", "{E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|Win32.Build.0 = Release|Win32
|
||||
{BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|Win32.Build.0 = Release|Win32
|
||||
{6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Release|Win32.Build.0 = Release|Win32
|
||||
{FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|Win32.Build.0 = Release|Win32
|
||||
{37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|Win32.Build.0 = Release|Win32
|
||||
{C539D7C8-26A8-4A94-B938-77672165C130}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{C539D7C8-26A8-4A94-B938-77672165C130}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{C539D7C8-26A8-4A94-B938-77672165C130}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{C539D7C8-26A8-4A94-B938-77672165C130}.Release|Win32.Build.0 = Release|Win32
|
||||
{729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Release|Win32.Build.0 = Release|Win32
|
||||
{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Release|Win32.ActiveCfg = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -36,80 +36,101 @@
|
|||
#include <ctype.h>
|
||||
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_npi(const char *npi_string, uint8_t *target)
|
||||
FT_DECLARE(ftdm_status_t) ftdm_set_npi(const char *string, uint8_t *target)
|
||||
{
|
||||
if (!strcasecmp(npi_string, "isdn") || !strcasecmp(npi_string, "e164")) {
|
||||
*target = FTDM_NPI_ISDN;
|
||||
} else if (!strcasecmp(npi_string, "data")) {
|
||||
*target = FTDM_NPI_DATA;
|
||||
} else if (!strcasecmp(npi_string, "telex")) {
|
||||
*target = FTDM_NPI_TELEX;
|
||||
} else if (!strcasecmp(npi_string, "national")) {
|
||||
*target = FTDM_NPI_NATIONAL;
|
||||
} else if (!strcasecmp(npi_string, "private")) {
|
||||
*target = FTDM_NPI_PRIVATE;
|
||||
} else if (!strcasecmp(npi_string, "reserved")) {
|
||||
*target = FTDM_NPI_RESERVED;
|
||||
} else if (!strcasecmp(npi_string, "unknown")) {
|
||||
*target = FTDM_NPI_UNKNOWN;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid NPI value (%s)\n", npi_string);
|
||||
*target = FTDM_NPI_UNKNOWN;
|
||||
return FTDM_FAIL;
|
||||
uint8_t val;
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
|
||||
val = ftdm_str2ftdm_npi(string);
|
||||
if (val == FTDM_NPI_INVALID) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid NPI string (%s)\n", string);
|
||||
status = FTDM_FAIL;
|
||||
val = FTDM_NPI_UNKNOWN;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
*target = val;
|
||||
return status;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_ton(const char *ton_string, uint8_t *target)
|
||||
FT_DECLARE(ftdm_status_t) ftdm_set_ton(const char *string, uint8_t *target)
|
||||
{
|
||||
if (!strcasecmp(ton_string, "national")) {
|
||||
*target = FTDM_TON_NATIONAL;
|
||||
} else if (!strcasecmp(ton_string, "international")) {
|
||||
*target = FTDM_TON_INTERNATIONAL;
|
||||
} else if (!strcasecmp(ton_string, "local")) {
|
||||
*target = FTDM_TON_SUBSCRIBER_NUMBER;
|
||||
} else if (!strcasecmp(ton_string, "unknown")) {
|
||||
*target = FTDM_TON_UNKNOWN;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid TON value (%s)\n", ton_string);
|
||||
*target = FTDM_TON_UNKNOWN;
|
||||
return FTDM_FAIL;
|
||||
uint8_t val;
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
|
||||
val = ftdm_str2ftdm_ton(string);
|
||||
if (val == FTDM_TON_INVALID) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid TON string (%s)\n", string);
|
||||
status = FTDM_FAIL;
|
||||
val = FTDM_TON_UNKNOWN;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
*target = val;
|
||||
return status;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_capability(const char *bc_string, ftdm_bearer_cap_t *target)
|
||||
FT_DECLARE(ftdm_status_t) ftdm_set_bearer_capability(const char *string, uint8_t *target)
|
||||
{
|
||||
if (!strcasecmp(bc_string, "speech")) {
|
||||
*target = FTDM_BEARER_CAP_SPEECH;
|
||||
} else if (!strcasecmp(bc_string, "unrestricted-digital")) {
|
||||
*target = FTDM_BEARER_CAP_64K_UNRESTRICTED;
|
||||
} else if (!strcasecmp(bc_string, "3.1Khz")) {
|
||||
*target = FTDM_BEARER_CAP_3_1KHZ_AUDIO;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Unsupported Bearer Capability value (%s)\n", bc_string);
|
||||
return FTDM_FAIL;
|
||||
uint8_t val;
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
|
||||
val = ftdm_str2ftdm_bearer_cap(string);
|
||||
if (val == FTDM_NPI_INVALID) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid Bearer-Capability string (%s)\n", string);
|
||||
status = FTDM_FAIL;
|
||||
val = FTDM_BEARER_CAP_SPEECH;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
|
||||
*target = val;
|
||||
return status;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_layer1(const char *bc_string, ftdm_user_layer1_prot_t *target)
|
||||
FT_DECLARE(ftdm_status_t) ftdm_set_bearer_layer1(const char *string, uint8_t *target)
|
||||
{
|
||||
if (!strcasecmp(bc_string, "v110")) {
|
||||
*target = FTDM_USER_LAYER1_PROT_V110;
|
||||
} else if (!strcasecmp(bc_string, "ulaw")) {
|
||||
*target = FTDM_USER_LAYER1_PROT_ULAW;
|
||||
} else if (!strcasecmp(bc_string, "alaw")) {
|
||||
*target =FTDM_USER_LAYER1_PROT_ALAW ;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Unsupported Bearer Layer1 Prot value (%s)\n", bc_string);
|
||||
return FTDM_FAIL;
|
||||
uint8_t val;
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
|
||||
val = ftdm_str2ftdm_usr_layer1_prot(string);
|
||||
if (val == FTDM_USER_LAYER1_PROT_INVALID) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid Bearer Layer 1 Protocol string (%s)\n", string);
|
||||
status = FTDM_FAIL;
|
||||
val = FTDM_USER_LAYER1_PROT_ULAW;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
|
||||
*target = val;
|
||||
return status;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_set_screening_ind(const char *string, uint8_t *target)
|
||||
{
|
||||
uint8_t val;
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_is_number(char *number)
|
||||
val = ftdm_str2ftdm_screening(string);
|
||||
if (val == FTDM_SCREENING_INVALID) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid screening indicator string (%s)\n", string);
|
||||
status = FTDM_FAIL;
|
||||
val = FTDM_SCREENING_NOT_SCREENED;
|
||||
}
|
||||
|
||||
*target = val;
|
||||
return status;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_set_presentation_ind(const char *string, uint8_t *target)
|
||||
{
|
||||
uint8_t val;
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
|
||||
val = ftdm_str2ftdm_presentation(string);
|
||||
if (val == FTDM_PRES_INVALID) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid presentation string (%s)\n", string);
|
||||
status = FTDM_FAIL;
|
||||
val = FTDM_PRES_ALLOWED;
|
||||
}
|
||||
|
||||
*target = val;
|
||||
return status;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number)
|
||||
{
|
||||
if (!number) {
|
||||
return FTDM_FAIL;
|
||||
|
|
|
@ -38,8 +38,6 @@
|
|||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#ifndef WIN32
|
||||
#endif
|
||||
#include "private/ftdm_core.h"
|
||||
#include <stdarg.h>
|
||||
#ifdef WIN32
|
||||
|
@ -56,6 +54,9 @@
|
|||
#define FTDM_READ_TRACE_INDEX 0
|
||||
#define FTDM_WRITE_TRACE_INDEX 1
|
||||
|
||||
ftdm_time_t time_last_throttle_log = 0;
|
||||
ftdm_time_t time_current_throttle_log = 0;
|
||||
|
||||
static int time_is_init = 0;
|
||||
|
||||
static void time_init(void)
|
||||
|
@ -147,6 +148,24 @@ FTDM_STR2ENUM(ftdm_str2ftdm_chan_type, ftdm_chan_type2str, ftdm_chan_type_t, CHA
|
|||
FTDM_ENUM_NAMES(SIGNALING_STATUS_NAMES, SIGSTATUS_STRINGS)
|
||||
FTDM_STR2ENUM(ftdm_str2ftdm_signaling_status, ftdm_signaling_status2str, ftdm_signaling_status_t, SIGNALING_STATUS_NAMES, FTDM_SIG_STATE_INVALID)
|
||||
|
||||
FTDM_ENUM_NAMES(TON_NAMES, TON_STRINGS)
|
||||
FTDM_STR2ENUM(ftdm_str2ftdm_ton, ftdm_ton2str, ftdm_ton_t, TON_NAMES, FTDM_TON_INVALID)
|
||||
|
||||
FTDM_ENUM_NAMES(NPI_NAMES, NPI_STRINGS)
|
||||
FTDM_STR2ENUM(ftdm_str2ftdm_npi, ftdm_npi2str, ftdm_npi_t, NPI_NAMES, FTDM_NPI_INVALID)
|
||||
|
||||
FTDM_ENUM_NAMES(PRESENTATION_NAMES, PRESENTATION_STRINGS)
|
||||
FTDM_STR2ENUM(ftdm_str2ftdm_presentation, ftdm_presentation2str, ftdm_presentation_t, PRESENTATION_NAMES, FTDM_PRES_INVALID)
|
||||
|
||||
FTDM_ENUM_NAMES(SCREENING_NAMES, SCREENING_STRINGS)
|
||||
FTDM_STR2ENUM(ftdm_str2ftdm_screening, ftdm_screening2str, ftdm_screening_t, SCREENING_NAMES, FTDM_SCREENING_INVALID)
|
||||
|
||||
FTDM_ENUM_NAMES(BEARER_CAP_NAMES, BEARER_CAP_STRINGS)
|
||||
FTDM_STR2ENUM(ftdm_str2ftdm_bearer_cap, ftdm_bearer_cap2str, ftdm_bearer_cap_t, BEARER_CAP_NAMES, FTDM_BEARER_CAP_INVALID)
|
||||
|
||||
FTDM_ENUM_NAMES(USER_LAYER1_PROT_NAMES, USER_LAYER1_PROT_STRINGS)
|
||||
FTDM_STR2ENUM(ftdm_str2ftdm_usr_layer1_prot, ftdm_user_layer1_prot2str, ftdm_user_layer1_prot_t, USER_LAYER1_PROT_NAMES, FTDM_USER_LAYER1_PROT_INVALID)
|
||||
|
||||
static ftdm_status_t ftdm_group_add_channels(ftdm_span_t* span, int currindex, const char* name);
|
||||
|
||||
static const char *cut_path(const char *in)
|
||||
|
@ -1745,16 +1764,26 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan)
|
|||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED)) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "Channel is suspended\n");
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Cannot open channel when is suspended\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM) && !ftdm_test_flag(ftdmchan->span, FTDM_SPAN_PWR_SAVING)) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "Channel is alarmed\n");
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Cannot open channel when is alarmed\n");
|
||||
goto done;
|
||||
if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED)) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "Channel is suspended\n");
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Cannot open channel when is suspended\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM) && !ftdm_test_flag(ftdmchan->span, FTDM_SPAN_PWR_SAVING)) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "Channel is alarmed\n");
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Cannot open channel when is alarmed\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (globals.cpu_monitor.alarm &&
|
||||
globals.cpu_monitor.alarm_action_flags & FTDM_CPU_ALARM_ACTION_REJECT) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "CPU usage alarm is on - refusing to open channel\n");
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "CPU usage alarm is on - refusing to open channel\n");
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_SWITCH_CONGESTION;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_READY)) {
|
||||
|
@ -1763,15 +1792,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan)
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (globals.cpu_monitor.alarm &&
|
||||
globals.cpu_monitor.alarm_action_flags & FTDM_CPU_ALARM_ACTION_REJECT) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "CPU usage alarm is on - refusing to open channel\n");
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "CPU usage alarm is on - refusing to open channel\n");
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_SWITCH_CONGESTION;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
status = ftdmchan->fio->open(ftdmchan);
|
||||
if (status == FTDM_SUCCESS) {
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OPEN | FTDM_CHANNEL_INUSE);
|
||||
|
@ -2030,6 +2050,10 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char
|
|||
goto done;
|
||||
}
|
||||
|
||||
#ifndef FREETDM_SKIP_SIG_STATES
|
||||
/* We will fail RFC's if we not skip states, but some modules apart from ftmod_sangoma_isdn
|
||||
* expect the call to always to go PROGRESS and PROGRESS MEDIA state before going to UP, so
|
||||
* remove this only in netborder branch for now while we update the sig modules */
|
||||
|
||||
if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
|
||||
|
@ -2050,7 +2074,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char
|
|||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to UP\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
#endif
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 1);
|
||||
|
||||
done:
|
||||
|
@ -2199,14 +2223,19 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
|
|||
switch (indication) {
|
||||
/* FIXME: ring and busy cannot be used with all signaling stacks
|
||||
* (particularly isdn stacks I think, we should emulate or just move to hangup with busy cause) */
|
||||
case FTDM_CHANNEL_INDICATE_RING:
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RING, 1);
|
||||
case FTDM_CHANNEL_INDICATE_RINGING:
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RINGING, 1);
|
||||
break;
|
||||
|
||||
case FTDM_CHANNEL_INDICATE_BUSY:
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_BUSY, 1);
|
||||
break;
|
||||
|
||||
case FTDM_CHANNEL_INDICATE_PROCEED:
|
||||
if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_PROCEED_STATE)) {
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_RING) {
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROCEED, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_INDICATE_PROGRESS:
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
|
||||
|
@ -2214,7 +2243,6 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
|
|||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA:
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
|
||||
|
@ -2233,7 +2261,6 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
|
|||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "Do not know how to indicate %d\n", indication);
|
||||
status = FTDM_FAIL;
|
||||
|
@ -2386,6 +2413,16 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
|||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "channel done %u:%u\n", ftdmchan->span_id, ftdmchan->chan_id);
|
||||
|
||||
if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
|
||||
ftdm_sigmsg_t sigmsg;
|
||||
memset(&sigmsg, 0, sizeof(sigmsg));
|
||||
sigmsg.span_id = ftdmchan->span_id;
|
||||
sigmsg.chan_id = ftdmchan->chan_id;
|
||||
sigmsg.channel = ftdmchan;
|
||||
sigmsg.event_id = FTDM_SIGEVENT_RELEASED;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigmsg);
|
||||
}
|
||||
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
|
@ -2810,21 +2847,17 @@ done:
|
|||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_wait(ftdm_channel_t *ftdmchan, ftdm_wait_flag_t *flags, int32_t to)
|
||||
{
|
||||
assert(ftdmchan != NULL);
|
||||
assert(ftdmchan->fio != NULL);
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel\n");
|
||||
ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "Null io interface\n");
|
||||
ftdm_assert_return(ftdmchan->fio->wait != NULL, FTDM_NOTIMPL, "wait method not implemented\n");
|
||||
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "channel not open");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (!ftdmchan->fio->wait) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "method not implemented");
|
||||
return FTDM_FAIL;
|
||||
status = ftdmchan->fio->wait(ftdmchan, flags, to);
|
||||
if (status == FTDM_TIMEOUT) {
|
||||
/* make sure the flags are cleared on timeout */
|
||||
*flags = 0;
|
||||
}
|
||||
|
||||
return ftdmchan->fio->wait(ftdmchan, flags, to);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*******************************/
|
||||
|
@ -4809,7 +4842,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
|||
if (sigmsg->channel) {
|
||||
ftdm_mutex_lock(sigmsg->channel->mutex);
|
||||
}
|
||||
|
||||
|
||||
/* some core things to do on special events */
|
||||
switch (sigmsg->event_id) {
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -438,7 +438,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||
{
|
||||
if (state_counter > 5000 || !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT)) {
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_CALLERID_DETECT, NULL);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -492,8 +492,8 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) &&
|
||||
(ftdmchan->last_state == FTDM_CHANNEL_STATE_RING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE
|
||||
|| ftdmchan->last_state >= FTDM_CHANNEL_STATE_IDLE)) {
|
||||
(ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE
|
||||
|| ftdmchan->last_state >= FTDM_CHANNEL_STATE_RING)) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
|
||||
} else {
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING;
|
||||
|
@ -535,7 +535,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||
}
|
||||
}
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
case FTDM_CHANNEL_STATE_IDLE:
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
{
|
||||
ftdm_sleep(interval);
|
||||
continue;
|
||||
|
@ -599,7 +599,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||
ftdm_channel_use(ftdmchan);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_IDLE:
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
{
|
||||
ftdm_channel_use(ftdmchan);
|
||||
sig.event_id = FTDM_SIGEVENT_START;
|
||||
|
@ -669,7 +669,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||
continue;
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
{
|
||||
ftdm_buffer_zero(dt_buffer);
|
||||
teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]);
|
||||
|
@ -732,7 +732,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
|||
|
||||
if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) >= analog_data->max_dialstr))) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Number obtained [%s]\n", dtmf);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
last_digit = 0;
|
||||
collecting = 0;
|
||||
}
|
||||
|
@ -890,7 +890,7 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
|
|||
if (ftdm_test_flag(analog_data, FTDM_ANALOG_CALLERID)) {
|
||||
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID);
|
||||
} else {
|
||||
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_IDLE);
|
||||
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_RING);
|
||||
}
|
||||
event->channel->ring_count = 1;
|
||||
ftdm_mutex_unlock(event->channel->mutex);
|
||||
|
|
|
@ -1,202 +0,0 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="ftmod_analog"
|
||||
ProjectGUID="{37C94798-6E33-4B4F-8EE0-C72A7DC91157}"
|
||||
RootNamespace="ftmod_analog"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</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="VCWebDeploymentTool"
|
||||
/>
|
||||
<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="VCWebDeploymentTool"
|
||||
/>
|
||||
<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>
|
|
@ -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>
|
||||
|
|
|
@ -1,202 +0,0 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="ftmod_analog_em"
|
||||
ProjectGUID="{C539D7C8-26A8-4A94-B938-77672165C130}"
|
||||
RootNamespace="ftmod_analog_em"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</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="VCWebDeploymentTool"
|
||||
/>
|
||||
<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="VCWebDeploymentTool"
|
||||
/>
|
||||
<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>
|
|
@ -462,7 +462,7 @@ static ftdm_state_map_t isdn_state_map = {
|
|||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_RING, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}
|
||||
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
|
@ -479,7 +479,7 @@ static ftdm_state_map_t isdn_state_map = {
|
|||
{
|
||||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
|
||||
FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_UP, FTDM_END},
|
||||
},
|
||||
|
@ -537,6 +537,8 @@ static __inline__ void state_advance(ftdm_channel_t *chan)
|
|||
break;
|
||||
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
/* RINGING is an alias for PROGRESS state in inbound calls ATM */
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
{
|
||||
if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
sig.event_id = FTDM_SIGEVENT_PROGRESS;
|
||||
|
|
|
@ -60,9 +60,9 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="freetdm.lib openr2.lib"
|
||||
AdditionalDependencies="freetdm.lib libopenr2.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""C:\Program Files\openr2\lib";"$(OutDir)""
|
||||
AdditionalLibraryDirectories=""$(OutDir)";"C:\Program Files\openr2\lib""
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -220,6 +220,23 @@ static char *strsep(char **stringp, const char *delim)
|
|||
}
|
||||
#endif /* WIN32 */
|
||||
|
||||
static void ftdm_r2_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status)
|
||||
{
|
||||
ftdm_sigmsg_t sig;
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Signalling link status changed to %s\n", ftdm_signaling_status2str(status));
|
||||
|
||||
memset(&sig, 0, sizeof(sig));
|
||||
sig.chan_id = ftdmchan->chan_id;
|
||||
sig.span_id = ftdmchan->span_id;
|
||||
sig.channel = ftdmchan;
|
||||
sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sig.sigstatus = status;
|
||||
if (ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to change channel status to %s\n", ftdm_signaling_status2str(status));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static ftdm_call_cause_t ftdm_r2_cause_to_ftdm_cause(ftdm_channel_t *fchan, openr2_call_disconnect_cause_t cause)
|
||||
{
|
||||
switch (cause) {
|
||||
|
@ -593,17 +610,14 @@ static void ftdm_r2_on_line_blocked(openr2_chan_t *r2chan)
|
|||
{
|
||||
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Far end blocked in state %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED);
|
||||
ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_SUSPENDED);
|
||||
}
|
||||
|
||||
static void ftdm_r2_on_line_idle(openr2_chan_t *r2chan)
|
||||
{
|
||||
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Far end unblocked in state %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED);
|
||||
|
||||
/* XXX when should we set/unset this flag? XXX */
|
||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SIG_UP);
|
||||
ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP);
|
||||
}
|
||||
|
||||
static void ftdm_r2_write_log(openr2_log_level_t level, const char *file, const char *function, int line, const char *message)
|
||||
|
@ -1130,6 +1144,9 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_r2_configure_span)
|
|||
span->signal_data = r2data;
|
||||
span->outgoing_call = r2_outgoing_call;
|
||||
|
||||
/* use signals queue */
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE);
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
|
||||
fail:
|
||||
|
@ -1439,6 +1456,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
|||
} else if (status != FTDM_TIMEOUT) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "ftdm_span_poll_event returned %d.\n", status);
|
||||
}
|
||||
ftdm_span_trigger_signals(span);
|
||||
ftdm_sleep(20);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ typedef struct ftdm_sangoma_boost_trunkgroup {
|
|||
ftdm_size_t size; /* Number of b-channels in group */
|
||||
unsigned int last_used_index; /* index of last b-channel used */
|
||||
ftdm_channel_t* ftdmchans[MAX_CHANS_PER_TRUNKGROUP];
|
||||
//DAVIDY need to merge congestion timeouts to this struct
|
||||
//TODO need to merge congestion timeouts to this struct
|
||||
} ftdm_sangoma_boost_trunkgroup_t;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -55,7 +55,7 @@ ftdm_mutex_t *g_boost_modules_mutex = NULL;
|
|||
ftdm_hash_t *g_boost_modules_hash = NULL;
|
||||
|
||||
#define MAX_TRUNK_GROUPS 64
|
||||
//DAVIDY need to merge congestion_timeouts with ftdm_sangoma_boost_trunkgroups
|
||||
//TODO need to merge congestion_timeouts with ftdm_sangoma_boost_trunkgroups
|
||||
static time_t congestion_timeouts[MAX_TRUNK_GROUPS];
|
||||
|
||||
static ftdm_sangoma_boost_trunkgroup_t *g_trunkgroups[MAX_TRUNK_GROUPS];
|
||||
|
@ -1557,11 +1557,11 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
|
|||
ftdm_set_string(event.calling_name, ftdmchan->caller_data.cid_name);
|
||||
ftdm_set_string(event.rdnis.digits, ftdmchan->caller_data.rdnis.digits);
|
||||
if (strlen(ftdmchan->caller_data.rdnis.digits)) {
|
||||
event.rdnis.digits_count = (uint8_t)strlen(ftdmchan->caller_data.rdnis.digits)+1;
|
||||
event.rdnis.ton = ftdmchan->caller_data.rdnis.type;
|
||||
event.rdnis.npi = ftdmchan->caller_data.rdnis.plan;
|
||||
event.rdnis.digits_count = (uint8_t)strlen(ftdmchan->caller_data.rdnis.digits)+1;
|
||||
event.rdnis.ton = ftdmchan->caller_data.rdnis.type;
|
||||
event.rdnis.npi = ftdmchan->caller_data.rdnis.plan;
|
||||
}
|
||||
|
||||
|
||||
event.calling.screening_ind = ftdmchan->caller_data.screen;
|
||||
event.calling.presentation_ind = ftdmchan->caller_data.pres;
|
||||
|
||||
|
@ -2582,17 +2582,17 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_boost_configure_span)
|
|||
} else if (!strcasecmp(var, "remote_port")) {
|
||||
remote_port = atoi(val);
|
||||
} else if (!strcasecmp(var, "outbound-called-ton")) {
|
||||
ftdm_span_set_ton(val, &span->default_caller_data.dnis.type);
|
||||
ftdm_set_ton(val, &span->default_caller_data.dnis.type);
|
||||
} else if (!strcasecmp(var, "outbound-called-npi")) {
|
||||
ftdm_span_set_npi(val, &span->default_caller_data.dnis.plan);
|
||||
ftdm_set_npi(val, &span->default_caller_data.dnis.plan);
|
||||
} else if (!strcasecmp(var, "outbound-calling-ton")) {
|
||||
ftdm_span_set_ton(val, &span->default_caller_data.cid_num.type);
|
||||
ftdm_set_ton(val, &span->default_caller_data.cid_num.type);
|
||||
} else if (!strcasecmp(var, "outbound-calling-npi")) {
|
||||
ftdm_span_set_npi(val, &span->default_caller_data.cid_num.plan);
|
||||
ftdm_set_npi(val, &span->default_caller_data.cid_num.plan);
|
||||
} else if (!strcasecmp(var, "outbound-rdnis-ton")) {
|
||||
ftdm_span_set_ton(val, &span->default_caller_data.rdnis.type);
|
||||
ftdm_set_ton(val, &span->default_caller_data.rdnis.type);
|
||||
} else if (!strcasecmp(var, "outbound-rdnis-npi")) {
|
||||
ftdm_span_set_npi(val, &span->default_caller_data.rdnis.plan);
|
||||
ftdm_set_npi(val, &span->default_caller_data.rdnis.plan);
|
||||
} else if (!sigmod) {
|
||||
snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var);
|
||||
FAIL_CONFIG_RETURN(FTDM_FAIL);
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -40,22 +40,24 @@
|
|||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj);
|
||||
|
||||
static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj);
|
||||
static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span);
|
||||
static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span);
|
||||
|
||||
ftdm_channel_t* ftdm_sangoma_isdn_process_event_states(ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event);
|
||||
static void ftdm_sangoma_isdn_advance_chan_states(ftdm_channel_t *ftdmchan);
|
||||
static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span);
|
||||
|
||||
static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event);
|
||||
static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan);
|
||||
static void ftdm_sangoma_isdn_process_stack_event (ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event);
|
||||
static void ftdm_sangoma_isdn_wakeup_phy(ftdm_channel_t *dchan);
|
||||
static void ftdm_sangoma_isdn_dchan_set_queue_size(ftdm_channel_t *ftdmchan);
|
||||
|
||||
static ftdm_io_interface_t g_sngisdn_io_interface;
|
||||
static sng_isdn_event_interface_t g_sngisdn_event_interface;
|
||||
static ftdm_io_interface_t g_sngisdn_io_interface;
|
||||
static sng_isdn_event_interface_t g_sngisdn_event_interface;
|
||||
|
||||
ftdm_sngisdn_data_t g_sngisdn_data;
|
||||
ftdm_sngisdn_data_t g_sngisdn_data;
|
||||
|
||||
ftdm_state_map_t sangoma_isdn_state_map = {
|
||||
{
|
||||
|
@ -113,7 +115,20 @@ ftdm_state_map_t sangoma_isdn_state_map = {
|
|||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_RING, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END}
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_PROCEED, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
|
||||
FTDM_CHANNEL_STATE_UP, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_RINGING, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
|
||||
},
|
||||
{
|
||||
ZSD_INBOUND,
|
||||
|
@ -187,9 +202,17 @@ ftdm_state_map_t sangoma_isdn_state_map = {
|
|||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_DIALING, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS,
|
||||
FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
|
||||
FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP,
|
||||
FTDM_CHANNEL_STATE_DOWN, FTDM_END}
|
||||
},
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
{FTDM_CHANNEL_STATE_PROCEED, FTDM_END},
|
||||
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
|
||||
FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
|
||||
},
|
||||
{
|
||||
ZSD_OUTBOUND,
|
||||
ZSM_UNACCEPTABLE,
|
||||
|
@ -236,39 +259,51 @@ static __inline__ void ftdm_sangoma_isdn_advance_chan_states(ftdm_channel_t *ftd
|
|||
}
|
||||
}
|
||||
|
||||
static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
|
||||
sngisdn_snd_event(signal_data->dchan, event);
|
||||
|
||||
switch (event) {
|
||||
/* Check if the span woke up from power-saving mode */
|
||||
case FTDM_OOB_ALARM_CLEAR:
|
||||
if (FTDM_SPAN_IS_BRI(span)) {
|
||||
ftdm_channel_t *ftdmchan;
|
||||
sngisdn_chan_data_t *sngisdn_info;
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
|
||||
sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data;
|
||||
|
||||
if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) {
|
||||
ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING);
|
||||
|
||||
ftdm_sched_timer(signal_data->sched, "delayed_setup", 1000, sngisdn_delayed_setup, (void*) ftdmchan->call_data, NULL);
|
||||
}
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Ignore other events for now */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span)
|
||||
{
|
||||
ftdm_status_t ret_status;
|
||||
ftdm_channel_t *ftdmchan;
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
ftdm_status_t ret_status;
|
||||
|
||||
ret_status = ftdm_span_poll_event(span, 0, NULL);
|
||||
switch(ret_status) {
|
||||
case FTDM_SUCCESS:
|
||||
{
|
||||
ftdm_event_t *event;
|
||||
while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) {
|
||||
|
||||
if (FTDM_SPAN_IS_BRI(span)) {
|
||||
switch (event->enum_id) {
|
||||
/* Check if the span woke up from power-saving mode */
|
||||
case FTDM_OOB_ALARM_CLEAR:
|
||||
{
|
||||
chaniter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
|
||||
sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
|
||||
|
||||
if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) {
|
||||
ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING);
|
||||
sngisdn_snd_setup((ftdm_channel_t*)ftdmchan);
|
||||
}
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
}
|
||||
}
|
||||
}
|
||||
ftdm_sangoma_isdn_process_phy_events(span, event->enum_id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -280,9 +315,83 @@ static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span)
|
|||
}
|
||||
}
|
||||
|
||||
static void ftdm_sangoma_isdn_dchan_set_queue_size(ftdm_channel_t *dchan)
|
||||
{
|
||||
ftdm_status_t ret_status;
|
||||
uint32_t queue_size;
|
||||
|
||||
queue_size = SNGISDN_DCHAN_QUEUE_LEN;
|
||||
ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_RX_QUEUE_SIZE, &queue_size);
|
||||
ftdm_assert(ret_status == FTDM_SUCCESS, "Failed to set Rx Queue size");
|
||||
|
||||
queue_size = SNGISDN_DCHAN_QUEUE_LEN;
|
||||
ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &queue_size);
|
||||
ftdm_assert(ret_status == FTDM_SUCCESS, "Failed to set Tx Queue size");
|
||||
|
||||
RETVOID;
|
||||
}
|
||||
|
||||
static void ftdm_sangoma_isdn_wakeup_phy(ftdm_channel_t *dchan)
|
||||
{
|
||||
ftdm_status_t ret_status;
|
||||
ftdm_channel_hw_link_status_t status = FTDM_HW_LINK_CONNECTED;
|
||||
ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_LINK_STATUS, &status);
|
||||
if (ret_status != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Failed to wake-up link\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void *ftdm_sangoma_isdn_dchan_run(ftdm_thread_t *me, void *obj)
|
||||
{
|
||||
uint8_t data[1000];
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
ftdm_wait_flag_t wflags = FTDM_READ;
|
||||
ftdm_span_t *span = (ftdm_span_t*) obj;
|
||||
ftdm_channel_t *dchan = ((sngisdn_span_data_t*)span->signal_data)->dchan;
|
||||
ftdm_size_t len = 0;
|
||||
|
||||
ftdm_channel_set_feature(dchan, FTDM_CHANNEL_FEATURE_IO_STATS);
|
||||
ftdm_sangoma_isdn_dchan_set_queue_size(dchan);
|
||||
|
||||
ftdm_assert(dchan, "Span does not have a dchannel");
|
||||
ftdm_channel_open_chan(dchan);
|
||||
|
||||
while (ftdm_running() && !(ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD))) {
|
||||
wflags = FTDM_READ;
|
||||
status = ftdm_channel_wait(dchan, &wflags, 10000);
|
||||
switch(status) {
|
||||
case FTDM_FAIL:
|
||||
ftdm_log_chan_msg(dchan, FTDM_LOG_CRIT, "Failed to wait for d-channel\n");
|
||||
break;
|
||||
case FTDM_TIMEOUT:
|
||||
break;
|
||||
case FTDM_SUCCESS:
|
||||
if ((wflags & FTDM_READ)) {
|
||||
len = 1000;
|
||||
status = ftdm_channel_read(dchan, data, &len);
|
||||
if (status == FTDM_SUCCESS) {
|
||||
sngisdn_snd_data(dchan, data, len);
|
||||
} else {
|
||||
ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Failed to read from channel \n");
|
||||
}
|
||||
#ifndef WIN32 /* It is valid on WIN32 for poll to return without errors, but no flags set */
|
||||
} else {
|
||||
ftdm_log_chan_msg(dchan, FTDM_LOG_CRIT, "Failed to poll for d-channel\n");
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan_msg(dchan, FTDM_LOG_CRIT, "Unhandled IO event\n");
|
||||
}
|
||||
}
|
||||
ftdm_channel_close(&dchan);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
|
||||
{
|
||||
ftdm_interrupt_t *ftdm_sangoma_isdn_int[2];
|
||||
ftdm_interrupt_t *ftdm_sangoma_isdn_int[3];
|
||||
ftdm_status_t ret_status;
|
||||
ftdm_span_t *span = (ftdm_span_t *) obj;
|
||||
ftdm_channel_t *ftdmchan = NULL;
|
||||
|
@ -300,8 +409,13 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
|
|||
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to get a ftdm_interrupt for span = %s!\n", span->name);
|
||||
goto ftdm_sangoma_isdn_run_exit;
|
||||
}
|
||||
|
||||
if (ftdm_queue_get_interrupt(span->pendingsignals, &ftdm_sangoma_isdn_int[1]) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to get a signal interrupt for span = %s!\n", span->name);
|
||||
goto ftdm_sangoma_isdn_run_exit;
|
||||
}
|
||||
|
||||
if (ftdm_queue_get_interrupt(signal_data->event_queue, &ftdm_sangoma_isdn_int[1]) != FTDM_SUCCESS) {
|
||||
if (ftdm_queue_get_interrupt(signal_data->event_queue, &ftdm_sangoma_isdn_int[2]) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to get a event interrupt for span = %s!\n", span->name);
|
||||
goto ftdm_sangoma_isdn_run_exit;
|
||||
}
|
||||
|
@ -310,8 +424,14 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
|
|||
|
||||
/* Check if there are any timers to process */
|
||||
ftdm_sched_run(signal_data->sched);
|
||||
ftdm_span_trigger_signals(span);
|
||||
|
||||
ret_status = ftdm_interrupt_multiple_wait(ftdm_sangoma_isdn_int, 2, sleep);
|
||||
if (ftdm_sched_get_time_to_next_timer(signal_data->sched, &sleep) == FTDM_SUCCESS) {
|
||||
if (sleep < 0 || sleep > SNGISDN_EVENT_POLL_RATE) {
|
||||
sleep = SNGISDN_EVENT_POLL_RATE;
|
||||
}
|
||||
}
|
||||
ret_status = ftdm_interrupt_multiple_wait(ftdm_sangoma_isdn_int, 3, sleep);
|
||||
/* find out why we returned from the interrupt queue */
|
||||
switch (ret_status) {
|
||||
case FTDM_SUCCESS: /* there was a state change on the span */
|
||||
|
@ -327,7 +447,6 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
|
|||
ftdm_sangoma_isdn_process_stack_event(span, sngisdn_event);
|
||||
ftdm_safe_free(sngisdn_event);
|
||||
}
|
||||
ftdm_span_trigger_signals(span);
|
||||
break;
|
||||
case FTDM_TIMEOUT:
|
||||
/* twiddle */
|
||||
|
@ -343,12 +462,6 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
|
|||
|
||||
/* Poll for events, e.g HW DTMF */
|
||||
ftdm_sangoma_isdn_poll_events(span);
|
||||
|
||||
if (ftdm_sched_get_time_to_next_timer(signal_data->sched, &sleep) == FTDM_SUCCESS) {
|
||||
if (sleep < 0 || sleep > SNGISDN_EVENT_POLL_RATE) {
|
||||
sleep = SNGISDN_EVENT_POLL_RATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* clear the IN_THREAD flag so that we know the thread is done */
|
||||
|
@ -512,13 +625,15 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
break;
|
||||
case FTDM_CHANNEL_STATE_GET_CALLERID:
|
||||
{
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED);
|
||||
sngisdn_snd_proceed(ftdmchan);
|
||||
if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) {
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED);
|
||||
sngisdn_snd_proceed(ftdmchan);
|
||||
}
|
||||
/* Wait in this state until we get FACILITY msg */
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RING: /* incoming call request */
|
||||
{
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending incoming call from %s to %s to FTDM core\n", ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.dnis.digits);
|
||||
|
||||
/* we have enough information to inform FTDM of the call*/
|
||||
|
@ -535,14 +650,34 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Requesting Line activation\n");
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_ACTIVATING);
|
||||
sng_isdn_wake_up_phy(ftdmchan->span);
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_ACTIVATING);
|
||||
ftdm_sangoma_isdn_wakeup_phy(ftdmchan);
|
||||
ftdm_sched_timer(signal_data->sched, "timer_t3", signal_data->timer_t3*1000, sngisdn_t3_timeout, (void*) sngisdn_info, NULL);
|
||||
} else {
|
||||
sngisdn_snd_setup(ftdmchan);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
{
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
/*OUTBOUND...so we were told by the line of this so noifiy the user*/
|
||||
sigev.event_id = FTDM_SIGEVENT_PROCEED;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
} else {
|
||||
if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) {
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED);
|
||||
sngisdn_snd_proceed(ftdmchan);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
{
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
|
||||
sngisdn_snd_alert(ftdmchan, prog_ind);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
{
|
||||
/*check if the channel is inbound or outbound*/
|
||||
|
@ -550,9 +685,13 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
/*OUTBOUND...so we were told by the line of this so noifiy the user*/
|
||||
sigev.event_id = FTDM_SIGEVENT_PROGRESS;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
} else if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) {
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED);
|
||||
sngisdn_snd_proceed(ftdmchan);
|
||||
} else {
|
||||
/* If we already sent a PROCEED before, do not send a PROGRESS as there is nothing to indicate to the remote switch */
|
||||
if (ftdmchan->last_state != FTDM_CHANNEL_STATE_PROCEED) {
|
||||
/* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
|
||||
sngisdn_snd_progress(ftdmchan, prog_ind);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -562,7 +701,9 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
} else {
|
||||
sngisdn_snd_progress(ftdmchan);
|
||||
/* Send a progress message, indicating: In-band information/pattern available */
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_IB_AVAIL};
|
||||
sngisdn_snd_progress(ftdmchan, prog_ind);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -633,7 +774,7 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
sngisdn_snd_release(ftdmchan, 0);
|
||||
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
sng_isdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
|
||||
sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
|
||||
}
|
||||
} else {
|
||||
sngisdn_snd_disconnect(ftdmchan);
|
||||
|
@ -658,9 +799,7 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
break;
|
||||
case FTDM_CHANNEL_STATE_DOWN: /* the call is finished and removed */
|
||||
{
|
||||
uint8_t glare = 0;
|
||||
|
||||
glare = sngisdn_test_flag(sngisdn_info, FLAG_GLARE);
|
||||
uint8_t glare = sngisdn_test_flag(sngisdn_info, FLAG_GLARE);
|
||||
/* clear all of the call specific data store in the channel structure */
|
||||
clear_call_data(sngisdn_info);
|
||||
|
||||
|
@ -788,7 +927,7 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_span_sig_status)
|
|||
static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
|
||||
{
|
||||
ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id);
|
||||
if (sng_isdn_stack_start(span) != FTDM_SUCCESS) {
|
||||
if (sngisdn_stack_start(span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -802,6 +941,12 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
|
|||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/*start the dchan monitor thread*/
|
||||
if (ftdm_thread_create_detached(ftdm_sangoma_isdn_dchan_run, span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT,"Failed to start Sangoma ISDN d-channel Monitor Thread!\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG,"Finished starting span %s\n", span->name);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
@ -823,7 +968,7 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span)
|
|||
ftdm_sleep(10);
|
||||
}
|
||||
|
||||
if (sng_isdn_stack_stop(span) != FTDM_SUCCESS) {
|
||||
if (sngisdn_stack_stop(span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to stop span %s\n", span->name);
|
||||
}
|
||||
|
||||
|
@ -875,7 +1020,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
|
|||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (sng_isdn_stack_cfg(span) != FTDM_SUCCESS) {
|
||||
if (sngisdn_stack_cfg(span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Sangoma ISDN Stack configuration failed\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -894,11 +1039,12 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
|
|||
span->state_map = &sangoma_isdn_state_map;
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE);
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE);
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_PROCEED_STATE);
|
||||
|
||||
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP ||
|
||||
span->trunk_type == FTDM_TRUNK_BRI) {
|
||||
|
||||
sng_isdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
|
||||
sngisdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
|
||||
}
|
||||
|
||||
/* Initialize scheduling context */
|
||||
|
@ -917,7 +1063,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init)
|
|||
ftdm_log(FTDM_LOG_INFO, "Loading ftmod_sangoma_isdn...\n");
|
||||
|
||||
memset(&g_sngisdn_data, 0, sizeof(g_sngisdn_data));
|
||||
|
||||
memset(&g_sngisdn_event_interface, 0, sizeof(g_sngisdn_event_interface));
|
||||
/* set callbacks */
|
||||
g_sngisdn_event_interface.cc.sng_con_ind = sngisdn_rcv_con_ind;
|
||||
g_sngisdn_event_interface.cc.sng_con_cfm = sngisdn_rcv_con_cfm;
|
||||
|
@ -946,8 +1092,11 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init)
|
|||
g_sngisdn_event_interface.sta.sng_q921_trc_ind = sngisdn_rcv_q921_trace;
|
||||
g_sngisdn_event_interface.sta.sng_q931_sta_ind = sngisdn_rcv_q931_ind;
|
||||
g_sngisdn_event_interface.sta.sng_q931_trc_ind = sngisdn_rcv_q931_trace;
|
||||
g_sngisdn_event_interface.sta.sng_cc_sta_ind = sngisdn_rcv_cc_ind;
|
||||
g_sngisdn_event_interface.sta.sng_cc_sta_ind = sngisdn_rcv_cc_ind;
|
||||
|
||||
g_sngisdn_event_interface.io.sng_l1_data_req = sngisdn_rcv_l1_data_req;
|
||||
g_sngisdn_event_interface.io.sng_l1_cmd_req = sngisdn_rcv_l1_cmd_req;
|
||||
|
||||
for(i=1;i<=MAX_VARIANTS;i++) {
|
||||
ftdm_mutex_create(&g_sngisdn_data.ccs[i].mutex);
|
||||
}
|
||||
|
@ -1008,11 +1157,11 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
|
|||
goto done;
|
||||
}
|
||||
if (!strcasecmp(trace_opt, "q921")) {
|
||||
sng_isdn_activate_trace(span, SNGISDN_TRACE_Q921);
|
||||
sngisdn_activate_trace(span, SNGISDN_TRACE_Q921);
|
||||
} else if (!strcasecmp(trace_opt, "q931")) {
|
||||
sng_isdn_activate_trace(span, SNGISDN_TRACE_Q931);
|
||||
sngisdn_activate_trace(span, SNGISDN_TRACE_Q931);
|
||||
} else if (!strcasecmp(trace_opt, "disable")) {
|
||||
sng_isdn_activate_trace(span, SNGISDN_TRACE_DISABLE);
|
||||
sngisdn_activate_trace(span, SNGISDN_TRACE_DISABLE);
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR invalid trace option <q921|q931> <span name>\n");
|
||||
}
|
||||
|
|
|
@ -60,9 +60,37 @@
|
|||
#define SNGISDN_EVENT_QUEUE_SIZE 100
|
||||
#define SNGISDN_EVENT_POLL_RATE 100
|
||||
#define SNGISDN_NUM_LOCAL_NUMBERS 8
|
||||
#define SNGISDN_DCHAN_QUEUE_LEN 200
|
||||
|
||||
/* TODO: rename all *_cc_* to *_an_* */
|
||||
|
||||
#define SNGISDN_ENUM_NAMES(_NAME, _STRINGS) static const char * _NAME [] = { _STRINGS , NULL };
|
||||
#define SNGISDN_STR2ENUM_P(_FUNC1, _FUNC2, _TYPE) _TYPE _FUNC1 (const char *name); const char * _FUNC2 (_TYPE type);
|
||||
#define SNGISDN_STR2ENUM(_FUNC1, _FUNC2, _TYPE, _STRINGS, _MAX) \
|
||||
_TYPE _FUNC1 (const char *name) \
|
||||
{ \
|
||||
int i; \
|
||||
_TYPE t = _MAX ; \
|
||||
\
|
||||
for (i = 0; i < _MAX ; i++) { \
|
||||
if (!strcasecmp(name, _STRINGS[i])) { \
|
||||
t = (_TYPE) i; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
return t; \
|
||||
} \
|
||||
const char * _FUNC2 (_TYPE type) \
|
||||
{ \
|
||||
if (type > _MAX) { \
|
||||
type = _MAX; \
|
||||
} \
|
||||
return _STRINGS[(int)type]; \
|
||||
} \
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
FLAG_RESET_RX = (1 << 0),
|
||||
FLAG_RESET_TX = (1 << 1),
|
||||
|
@ -74,7 +102,8 @@ typedef enum {
|
|||
FLAG_DELAYED_REL = (1 << 7),
|
||||
FLAG_SENT_PROCEED = (1 << 8),
|
||||
FLAG_SEND_DISC = (1 << 9),
|
||||
FLAG_ACTIVATING = (1 << 10), /* Used for BRI only, flag is set after we request line CONNECTED */
|
||||
/* Used for BRI only, flag is set after we request line CONNECTED */
|
||||
FLAG_ACTIVATING = (1 << 10),
|
||||
} sngisdn_flag_t;
|
||||
|
||||
|
||||
|
@ -134,6 +163,51 @@ typedef enum {
|
|||
SNGISDN_EVENT_RST_IND,
|
||||
} ftdm_sngisdn_event_id_t;
|
||||
|
||||
typedef enum {
|
||||
/* Call is not end-to-end ISDN */
|
||||
SNGISDN_PROGIND_DESCR_NETE_ISDN,
|
||||
/* Destination address is non-ISDN */
|
||||
SNGISDN_PROGIND_DESCR_DEST_NISDN,
|
||||
/* Origination address is non-ISDN */
|
||||
SNGISDN_PROGIND_DESCR_ORIG_NISDN,
|
||||
/* Call has returned to the ISDN */
|
||||
SNGISDN_PROGIND_DESCR_RET_ISDN,
|
||||
/* Interworking as occured and has resulted in a telecommunication service change */
|
||||
SNGISDN_PROGIND_DESCR_SERV_CHANGE,
|
||||
/* In-band information or an appropriate pattern is now available */
|
||||
SNGISDN_PROGIND_DESCR_IB_AVAIL,
|
||||
/* Invalid */
|
||||
SNGISDN_PROGIND_DESCR_INVALID,
|
||||
} ftdm_sngisdn_progind_descr_t;
|
||||
#define SNGISDN_PROGIND_DESCR_STRINGS "not-end-to-end-isdn", "destination-is-non-isdn", "origination-is-non-isdn", "call-returned-to-isdn", "service-change", "inband-info-available", "invalid"
|
||||
SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_progind_descr, ftdm_sngisdn_progind_descr2str, ftdm_sngisdn_progind_descr_t);
|
||||
|
||||
typedef enum {
|
||||
/* User */
|
||||
SNGISDN_PROGIND_LOC_USER,
|
||||
/* Private network serving the local user */
|
||||
SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR,
|
||||
/* Public network serving the local user */
|
||||
SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR,
|
||||
/* Transit network */
|
||||
SNGISDN_PROGIND_LOC_TRANSIT_NET,
|
||||
/* Public network serving remote user */
|
||||
SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR,
|
||||
/* Private network serving remote user */
|
||||
SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR,
|
||||
/* Network beyond the interworking point */
|
||||
SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW,
|
||||
/* Invalid */
|
||||
SNGISDN_PROGIND_LOC_INVALID,
|
||||
} ftdm_sngisdn_progind_loc_t;
|
||||
#define SNGISDN_PROGIND_LOC_STRINGS "user", "private-net-local-user", "public-net-local-user", "transit-network", "public-net-remote-user", "private-net-remote-user", "beyond-interworking", "invalid"
|
||||
SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t);
|
||||
|
||||
typedef struct ftdm_sngisdn_prog_ind {
|
||||
ftdm_sngisdn_progind_loc_t loc; /* location */
|
||||
ftdm_sngisdn_progind_descr_t descr; /* description */
|
||||
} ftdm_sngisdn_progind_t;
|
||||
|
||||
/* Only timers that can be cancelled are listed here */
|
||||
#define SNGISDN_NUM_TIMERS 1
|
||||
/* Increase NUM_TIMERS as number of ftdm_sngisdn_timer_t increases */
|
||||
|
@ -168,6 +242,7 @@ typedef struct sngisdn_chan_data {
|
|||
/* Span specific data */
|
||||
typedef struct sngisdn_span_data {
|
||||
ftdm_span_t *ftdm_span;
|
||||
ftdm_channel_t *dchan;
|
||||
uint8_t link_id;
|
||||
uint8_t switchtype;
|
||||
uint8_t signalling; /* SNGISDN_SIGNALING_CPE or SNGISDN_SIGNALING_NET */
|
||||
|
@ -179,9 +254,11 @@ typedef struct sngisdn_span_data {
|
|||
uint8_t trace_flags; /* TODO: change to flags, so we can use ftdm_test_flag etc.. */
|
||||
uint8_t overlap_dial;
|
||||
uint8_t setup_arb;
|
||||
uint8_t facility_ie_decode;
|
||||
uint8_t facility;
|
||||
int8_t facility_timeout;
|
||||
uint8_t num_local_numbers;
|
||||
uint8_t ignore_cause_value;
|
||||
uint8_t timer_t3;
|
||||
uint8_t restart_opt;
|
||||
char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS];
|
||||
|
@ -269,60 +346,58 @@ extern ftdm_sngisdn_data_t g_sngisdn_data;
|
|||
ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span);
|
||||
|
||||
/* Support functions */
|
||||
FT_DECLARE(uint32_t) get_unique_suInstId(int16_t cc_id);
|
||||
FT_DECLARE(void) clear_call_data(sngisdn_chan_data_t *sngisdn_info);
|
||||
FT_DECLARE(void) clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info);
|
||||
uint32_t get_unique_suInstId(int16_t cc_id);
|
||||
void clear_call_data(sngisdn_chan_data_t *sngisdn_info);
|
||||
void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info);
|
||||
ftdm_status_t get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data);
|
||||
ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data);
|
||||
|
||||
|
||||
ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail);
|
||||
ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt);
|
||||
|
||||
|
||||
void stack_hdr_init(Header *hdr);
|
||||
void stack_pst_init(Pst *pst);
|
||||
|
||||
FT_DECLARE(ftdm_status_t) get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data);
|
||||
FT_DECLARE(ftdm_status_t) get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data);
|
||||
FT_DECLARE(ftdm_status_t) sng_isdn_set_avail_rate(ftdm_span_t *ftdmspan, sngisdn_avail_t avail);
|
||||
|
||||
FT_DECLARE(ftdm_status_t) cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb);
|
||||
FT_DECLARE(ftdm_status_t) cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb);
|
||||
FT_DECLARE(ftdm_status_t) cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb);
|
||||
FT_DECLARE(ftdm_status_t) cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display);
|
||||
|
||||
FT_DECLARE(ftdm_status_t) cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm);
|
||||
FT_DECLARE(ftdm_status_t) cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
|
||||
FT_DECLARE(ftdm_status_t) cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm);
|
||||
FT_DECLARE(ftdm_status_t) cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan);
|
||||
|
||||
/* Outbound Call Control functions */
|
||||
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_progress(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_alert(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind);
|
||||
void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind);
|
||||
void sngisdn_snd_connect(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare);
|
||||
void sngisdn_snd_reset(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len);
|
||||
void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event);
|
||||
|
||||
/* Inbound Call Control functions */
|
||||
void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt);
|
||||
void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt);
|
||||
void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt);
|
||||
void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
|
||||
void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
|
||||
void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
|
||||
void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
|
||||
void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
|
||||
void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, FacEvnt *facEvnt, uint8_t evntType, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_sta_cfm ( int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
|
||||
void sngisdn_rcv_srv_ind ( int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_srv_cfm ( int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_rst_cfm ( int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
|
||||
void sngisdn_rcv_rst_ind ( int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
|
||||
void sngisdn_rcv_con_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_con_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_cnst_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_disc_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt);
|
||||
void sngisdn_rcv_rel_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt);
|
||||
void sngisdn_rcv_dat_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt);
|
||||
void sngisdn_rcv_sshl_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
|
||||
void sngisdn_rcv_sshl_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
|
||||
void sngisdn_rcv_rmrt_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
|
||||
void sngisdn_rcv_rmrt_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
|
||||
void sngisdn_rcv_flc_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
|
||||
void sngisdn_rcv_fac_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, FacEvnt *facEvnt, uint8_t evntType, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_sta_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
|
||||
void sngisdn_rcv_srv_ind(int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_srv_cfm(int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_rst_cfm(int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
|
||||
void sngisdn_rcv_rst_ind(int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
|
||||
int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame);
|
||||
int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd);
|
||||
|
||||
|
||||
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event);
|
||||
|
@ -360,6 +435,26 @@ void sngisdn_rcv_cc_ind(CcMngmt *status);
|
|||
void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...);
|
||||
void sngisdn_rcv_sng_assert(char *message);
|
||||
|
||||
ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb);
|
||||
ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb);
|
||||
ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb);
|
||||
ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *display);
|
||||
ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr);
|
||||
ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad);
|
||||
ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd);
|
||||
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_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb);
|
||||
ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb);
|
||||
ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb);
|
||||
ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt);
|
||||
ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad);
|
||||
ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind);
|
||||
ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr);
|
||||
ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t *data_len);
|
||||
|
||||
|
||||
uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability);
|
||||
uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_prot);
|
||||
ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_user(uint8_t bearer_capability);
|
||||
|
@ -386,6 +481,7 @@ static __inline__ void sngisdn_set_flag(sngisdn_chan_data_t *sngisdn_info, sngis
|
|||
|
||||
void handle_sng_log(uint8_t level, char *fmt,...);
|
||||
void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status);
|
||||
void sngisdn_delayed_setup(void* p_sngisdn_info);
|
||||
void sngisdn_delayed_release(void* p_sngisdn_info);
|
||||
void sngisdn_delayed_connect(void* p_sngisdn_info);
|
||||
void sngisdn_delayed_disconnect(void* p_sngisdn_info);
|
||||
|
@ -393,10 +489,10 @@ void sngisdn_facility_timeout(void* p_sngisdn_info);
|
|||
void sngisdn_t3_timeout(void* p_sngisdn_info);
|
||||
|
||||
/* Stack management functions */
|
||||
ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_wake_up_phy(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_stack_start(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span);
|
||||
|
||||
void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span);
|
||||
void sngisdn_print_spans(ftdm_stream_handle_t *stream);
|
||||
|
|
|
@ -34,13 +34,24 @@
|
|||
|
||||
#include "ftmod_sangoma_isdn.h"
|
||||
|
||||
ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span);
|
||||
ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span);
|
||||
ftdm_status_t add_local_number(const char* val, ftdm_span_t *span);
|
||||
static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span);
|
||||
static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span);
|
||||
static ftdm_status_t add_local_number(const char* val, ftdm_span_t *span);
|
||||
static ftdm_status_t parse_yesno(const char* var, const char* val, uint8_t *target);
|
||||
|
||||
extern ftdm_sngisdn_data_t g_sngisdn_data;
|
||||
|
||||
ftdm_status_t add_local_number(const char* val, ftdm_span_t *span)
|
||||
static ftdm_status_t parse_yesno(const char* var, const char* val, uint8_t *target)
|
||||
{
|
||||
if (ftdm_true(val)) {
|
||||
*target = SNGISDN_OPT_TRUE;
|
||||
} else {
|
||||
*target = SNGISDN_OPT_FALSE;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static ftdm_status_t add_local_number(const char* val, ftdm_span_t *span)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
|
||||
|
||||
|
@ -53,12 +64,14 @@ ftdm_status_t add_local_number(const char* val, ftdm_span_t *span)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
|
||||
static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
sngisdn_dchan_data_t *dchan_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
|
||||
|
||||
switch(span->trunk_type) {
|
||||
case FTDM_TRUNK_T1:
|
||||
if (!strcasecmp(switch_name, "ni2") ||
|
||||
|
@ -124,9 +137,9 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
|
|||
/* add this span to its ent_cc */
|
||||
signal_data->cc_id = i;
|
||||
|
||||
/* create a new dchan */ /* for NFAS - no-dchan on b-channels only links */
|
||||
/* create a new dchan */ /* for NFAS - no-dchan on b-channels-only links */
|
||||
g_sngisdn_data.num_dchan++;
|
||||
signal_data->dchan_id = g_sngisdn_data.num_dchan;
|
||||
signal_data->dchan_id = g_sngisdn_data.num_dchan;
|
||||
|
||||
dchan_data = &g_sngisdn_data.dchans[signal_data->dchan_id];
|
||||
dchan_data->num_spans++;
|
||||
|
@ -138,20 +151,27 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
|
|||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%s: cc_id:%d dchan_id:%d span_id:%d\n", span->name, signal_data->cc_id, signal_data->dchan_id, signal_data->span_id);
|
||||
|
||||
/* Add the channels to the span */
|
||||
for (i=1;i<=span->chan_count;i++) {
|
||||
unsigned chan_id;
|
||||
ftdm_channel_t *ftdmchan = span->channels[i];
|
||||
/* NFAS is not supported on E1, so span_id will always be 1 for E1 so this will work for E1 as well */
|
||||
chan_id = ((signal_data->span_id-1)*NUM_T1_CHANNELS_PER_SPAN)+ftdmchan->physical_chan_id;
|
||||
dchan_data->channels[chan_id] = (sngisdn_chan_data_t*)ftdmchan->call_data;
|
||||
dchan_data->num_chans++;
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
int32_t chan_id;
|
||||
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
|
||||
if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) {
|
||||
/* set the d-channel */
|
||||
signal_data->dchan = ftdmchan;
|
||||
} else {
|
||||
/* Add the channels to the span */
|
||||
/* NFAS is not supported on E1, so span_id will always be 1 for E1 so this will work for E1 as well */
|
||||
chan_id = ((signal_data->span_id-1)*NUM_T1_CHANNELS_PER_SPAN)+ftdmchan->physical_chan_id;
|
||||
dchan_data->channels[chan_id] = (sngisdn_chan_data_t*)ftdmchan->call_data;
|
||||
dchan_data->num_chans++;
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_iterator_free(chaniter);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span)
|
||||
static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
|
||||
if (!strcasecmp(signalling, "net") ||
|
||||
|
@ -181,6 +201,8 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
signal_data->min_digits = 8;
|
||||
signal_data->overlap_dial = SNGISDN_OPT_DEFAULT;
|
||||
signal_data->setup_arb = SNGISDN_OPT_DEFAULT;
|
||||
signal_data->facility_ie_decode = SNGISDN_OPT_DEFAULT;
|
||||
signal_data->ignore_cause_value = SNGISDN_OPT_DEFAULT;
|
||||
signal_data->timer_t3 = 8;
|
||||
signal_data->restart_opt = SNGISDN_OPT_DEFAULT;
|
||||
|
||||
|
@ -193,20 +215,19 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
if (span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
|
||||
ftdm_span_set_npi("unknown", &span->default_caller_data.dnis.plan);
|
||||
ftdm_span_set_ton("unknown", &span->default_caller_data.dnis.type);
|
||||
ftdm_span_set_npi("unknown", &span->default_caller_data.cid_num.plan);
|
||||
ftdm_span_set_ton("unknown", &span->default_caller_data.cid_num.type);
|
||||
ftdm_span_set_npi("unknown", &span->default_caller_data.rdnis.plan);
|
||||
ftdm_span_set_ton("unknown", &span->default_caller_data.rdnis.type);
|
||||
ftdm_set_npi("unknown", &span->default_caller_data.dnis.plan);
|
||||
ftdm_set_ton("unknown", &span->default_caller_data.dnis.type);
|
||||
ftdm_set_npi("unknown", &span->default_caller_data.cid_num.plan);
|
||||
ftdm_set_ton("unknown", &span->default_caller_data.cid_num.type);
|
||||
ftdm_set_npi("unknown", &span->default_caller_data.rdnis.plan);
|
||||
ftdm_set_ton("unknown", &span->default_caller_data.rdnis.type);
|
||||
} else {
|
||||
ftdm_span_set_npi("e164", &span->default_caller_data.dnis.plan);
|
||||
ftdm_span_set_ton("national", &span->default_caller_data.dnis.type);
|
||||
ftdm_span_set_npi("e164", &span->default_caller_data.cid_num.plan);
|
||||
ftdm_span_set_ton("national", &span->default_caller_data.cid_num.type);
|
||||
ftdm_span_set_npi("e164", &span->default_caller_data.rdnis.plan);
|
||||
ftdm_span_set_ton("national", &span->default_caller_data.rdnis.type);
|
||||
ftdm_set_npi("isdn", &span->default_caller_data.dnis.plan);
|
||||
ftdm_set_ton("national", &span->default_caller_data.dnis.type);
|
||||
ftdm_set_npi("isdn", &span->default_caller_data.cid_num.plan);
|
||||
ftdm_set_ton("national", &span->default_caller_data.cid_num.type);
|
||||
ftdm_set_npi("isdn", &span->default_caller_data.rdnis.plan);
|
||||
ftdm_set_ton("national", &span->default_caller_data.rdnis.type);
|
||||
}
|
||||
|
||||
for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) {
|
||||
|
@ -238,49 +259,30 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val);
|
||||
}
|
||||
} else if (!strcasecmp(var, "setup arbitration")) {
|
||||
if (!strcasecmp(val, "yes")) {
|
||||
signal_data->setup_arb = SNGISDN_OPT_TRUE;
|
||||
} else if (!strcasecmp(val, "no")) {
|
||||
signal_data->setup_arb = SNGISDN_OPT_FALSE;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val);
|
||||
}
|
||||
} else if (!strcasecmp(var, "setup-arbitration")) {
|
||||
parse_yesno(var, val, &signal_data->setup_arb);
|
||||
} else if (!strcasecmp(var, "facility")) {
|
||||
if (!strcasecmp(val, "yes")) {
|
||||
signal_data->facility = SNGISDN_OPT_TRUE;
|
||||
} else if (!strcasecmp(val, "no")) {
|
||||
signal_data->facility = SNGISDN_OPT_FALSE;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val);
|
||||
}
|
||||
parse_yesno(var, val, &signal_data->facility);
|
||||
} else if (!strcasecmp(var, "min_digits")) {
|
||||
signal_data->min_digits = atoi(val);
|
||||
} else if (!strcasecmp(var, "outbound-called-ton")) {
|
||||
ftdm_span_set_ton(val, &span->default_caller_data.dnis.type);
|
||||
ftdm_set_ton(val, &span->default_caller_data.dnis.type);
|
||||
} else if (!strcasecmp(var, "outbound-called-npi")) {
|
||||
ftdm_span_set_npi(val, &span->default_caller_data.dnis.plan);
|
||||
ftdm_set_npi(val, &span->default_caller_data.dnis.plan);
|
||||
} else if (!strcasecmp(var, "outbound-calling-ton")) {
|
||||
ftdm_span_set_ton(val, &span->default_caller_data.cid_num.type);
|
||||
ftdm_set_ton(val, &span->default_caller_data.cid_num.type);
|
||||
} else if (!strcasecmp(var, "outbound-calling-npi")) {
|
||||
ftdm_span_set_npi(val, &span->default_caller_data.cid_num.plan);
|
||||
ftdm_set_npi(val, &span->default_caller_data.cid_num.plan);
|
||||
} else if (!strcasecmp(var, "outbound-rdnis-ton")) {
|
||||
ftdm_span_set_ton(val, &span->default_caller_data.rdnis.type);
|
||||
ftdm_set_ton(val, &span->default_caller_data.rdnis.type);
|
||||
} else if (!strcasecmp(var, "outbound-rdnis-npi")) {
|
||||
ftdm_span_set_npi(val, &span->default_caller_data.rdnis.plan);
|
||||
ftdm_set_npi(val, &span->default_caller_data.rdnis.plan);
|
||||
} else if (!strcasecmp(var, "outbound-bearer_cap")) {
|
||||
ftdm_span_set_bearer_capability(val, &span->default_caller_data.bearer_capability);
|
||||
ftdm_set_bearer_capability(val, (uint8_t*)&span->default_caller_data.bearer_capability);
|
||||
} else if (!strcasecmp(var, "outbound-bearer_layer1")) {
|
||||
ftdm_span_set_bearer_layer1(val, &span->default_caller_data.bearer_layer1);
|
||||
ftdm_set_bearer_layer1(val, (uint8_t*)&span->default_caller_data.bearer_layer1);
|
||||
} else if (!strcasecmp(var, "channel-restart-on-link-up")) {
|
||||
if (!strcasecmp(val, "yes")) {
|
||||
signal_data->restart_opt = SNGISDN_OPT_TRUE;
|
||||
} else if (!strcasecmp(val, "no")) {
|
||||
signal_data->restart_opt = SNGISDN_OPT_FALSE;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val);
|
||||
}
|
||||
|
||||
parse_yesno(var, val, &signal_data->restart_opt);
|
||||
} else if (!strcasecmp(var, "local-number")) {
|
||||
if (add_local_number(val, span) != FTDM_SUCCESS) {
|
||||
return FTDM_FAIL;
|
||||
|
@ -290,6 +292,10 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
if (signal_data->facility_timeout < 0) {
|
||||
signal_data->facility_timeout = 0;
|
||||
}
|
||||
} else if (!strcasecmp(var, "facility-ie-decode")) {
|
||||
parse_yesno(var, val, &signal_data->facility_ie_decode);
|
||||
} else if (!strcasecmp(var, "ignore-cause-value")) {
|
||||
parse_yesno(var, val, &signal_data->ignore_cause_value);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var);
|
||||
}
|
||||
|
|
|
@ -38,52 +38,52 @@ extern ftdm_sngisdn_data_t g_sngisdn_data;
|
|||
|
||||
uint8_t sng_isdn_stack_switchtype(sngisdn_switchtype_t switchtype);
|
||||
|
||||
ftdm_status_t sng_isdn_cfg_phy(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_cfg_q921(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_cfg_q931(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_cfg_cc(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_cfg_phy(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_cfg_q921(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_cfg_q931(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_cfg_cc(ftdm_span_t *span);
|
||||
|
||||
ftdm_status_t sng_isdn_stack_cfg_phy_gen(void);
|
||||
ftdm_status_t sng_isdn_stack_cfg_q921_gen(void);
|
||||
ftdm_status_t sng_isdn_stack_cfg_q931_gen(void);
|
||||
ftdm_status_t sng_isdn_stack_cfg_cc_gen(void);
|
||||
ftdm_status_t sngisdn_stack_cfg_phy_gen(void);
|
||||
ftdm_status_t sngisdn_stack_cfg_q921_gen(void);
|
||||
ftdm_status_t sngisdn_stack_cfg_q931_gen(void);
|
||||
ftdm_status_t sngisdn_stack_cfg_cc_gen(void);
|
||||
|
||||
|
||||
ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management);
|
||||
ftdm_status_t sng_isdn_stack_cfg_q931_tsap(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management);
|
||||
ftdm_status_t sngisdn_stack_cfg_q931_tsap(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span);
|
||||
|
||||
ftdm_status_t sng_isdn_stack_cfg_cc_sap(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_stack_cfg_cc_sap(ftdm_span_t *span);
|
||||
|
||||
ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
|
||||
ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
|
||||
|
||||
if (!g_sngisdn_data.gen_config_done) {
|
||||
g_sngisdn_data.gen_config_done = 1;
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Starting general stack configuration\n");
|
||||
if(sng_isdn_stack_cfg_phy_gen()!= FTDM_SUCCESS) {
|
||||
if(sngisdn_stack_cfg_phy_gen()!= FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed general physical configuration\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "General stack physical done\n");
|
||||
|
||||
if(sng_isdn_stack_cfg_q921_gen()!= FTDM_SUCCESS) {
|
||||
if(sngisdn_stack_cfg_q921_gen()!= FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed general q921 configuration\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "General stack q921 done\n");
|
||||
|
||||
if(sng_isdn_stack_cfg_q931_gen()!= FTDM_SUCCESS) {
|
||||
if(sngisdn_stack_cfg_q931_gen()!= FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed general q921 configuration\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "General stack q931 done\n");
|
||||
|
||||
if(sng_isdn_stack_cfg_cc_gen()!= FTDM_SUCCESS) {
|
||||
if(sngisdn_stack_cfg_cc_gen()!= FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed general CC configuration\n");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -92,26 +92,26 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
|
|||
}
|
||||
|
||||
/* TODO: for NFAS, should only call these function for spans with d-chans */
|
||||
if (sng_isdn_stack_cfg_phy_psap(span) != FTDM_SUCCESS) {
|
||||
if (sngisdn_stack_cfg_phy_psap(span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s:phy_psap configuration failed\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%s:phy_psap configuration done\n", span->name);
|
||||
|
||||
if (sng_isdn_stack_cfg_q921_msap(span) != FTDM_SUCCESS) {
|
||||
if (sngisdn_stack_cfg_q921_msap(span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s:q921_msap configuration failed\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%s:q921_msap configuration done\n", span->name);
|
||||
|
||||
if (sng_isdn_stack_cfg_q921_dlsap(span, 0) != FTDM_SUCCESS) {
|
||||
if (sngisdn_stack_cfg_q921_dlsap(span, 0) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s:q921_dlsap configuration failed\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%s:q921_dlsap configuration done\n", span->name);
|
||||
|
||||
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
if (sng_isdn_stack_cfg_q921_dlsap(span, 1) != FTDM_SUCCESS) {
|
||||
if (sngisdn_stack_cfg_q921_dlsap(span, 1) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s:q921_dlsap management configuration failed\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -119,13 +119,13 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
|
|||
}
|
||||
|
||||
|
||||
if (sng_isdn_stack_cfg_q931_dlsap(span) != FTDM_SUCCESS) {
|
||||
if (sngisdn_stack_cfg_q931_dlsap(span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s:q931_dlsap configuration failed\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%s:q931_dlsap configuration done\n", span->name);
|
||||
|
||||
if (sng_isdn_stack_cfg_q931_lce(span) != FTDM_SUCCESS) {
|
||||
if (sngisdn_stack_cfg_q931_lce(span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s:q931_lce configuration failed\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -134,13 +134,13 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
|
|||
if (!g_sngisdn_data.ccs[signal_data->cc_id].config_done) {
|
||||
g_sngisdn_data.ccs[signal_data->cc_id].config_done = 1;
|
||||
/* if BRI, need to configure dlsap_mgmt */
|
||||
if (sng_isdn_stack_cfg_q931_tsap(span) != FTDM_SUCCESS) {
|
||||
if (sngisdn_stack_cfg_q931_tsap(span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s:q931_tsap configuration failed\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%s:q931_tsap configuration done\n", span->name);
|
||||
|
||||
if (sng_isdn_stack_cfg_cc_sap(span) != FTDM_SUCCESS) {
|
||||
if (sngisdn_stack_cfg_cc_sap(span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s:cc_sap configuration failed\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -153,37 +153,37 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span)
|
|||
|
||||
|
||||
|
||||
ftdm_status_t sng_isdn_stack_cfg_phy_gen(void)
|
||||
ftdm_status_t sngisdn_stack_cfg_phy_gen(void)
|
||||
{
|
||||
/*local variables*/
|
||||
L1Mngmt cfg; /*configuration structure*/
|
||||
Pst pst; /*post structure*/
|
||||
L1Mngmt cfg; /*configuration structure*/
|
||||
Pst pst; /*post structure*/
|
||||
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTL1;
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTL1;
|
||||
|
||||
/*clear the configuration structure*/
|
||||
/*clear the configuration structure*/
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
|
||||
/*fill in the specific fields of the header*/
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTL1;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STGEN;
|
||||
/*fill in the specific fields of the header*/
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTL1;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STGEN;
|
||||
|
||||
stack_pst_init(&cfg.t.cfg.s.l1Gen.sm );
|
||||
cfg.t.cfg.s.l1Gen.sm.srcEnt = ENTL1;
|
||||
cfg.t.cfg.s.l1Gen.sm.dstEnt = ENTSM;
|
||||
stack_pst_init(&cfg.t.cfg.s.l1Gen.sm );
|
||||
cfg.t.cfg.s.l1Gen.sm.srcEnt = ENTL1;
|
||||
cfg.t.cfg.s.l1Gen.sm.dstEnt = ENTSM;
|
||||
|
||||
cfg.t.cfg.s.l1Gen.nmbLnks = MAX_L1_LINKS+1;
|
||||
cfg.t.cfg.s.l1Gen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */
|
||||
cfg.t.cfg.s.l1Gen.poolTrLower = POOL_LW_TR; /* lower pool threshold */
|
||||
cfg.t.cfg.s.l1Gen.nmbLnks = MAX_L1_LINKS;
|
||||
cfg.t.cfg.s.l1Gen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */
|
||||
cfg.t.cfg.s.l1Gen.poolTrLower = POOL_LW_TR; /* lower pool threshold */
|
||||
|
||||
if (sng_isdn_phy_config(&pst, &cfg)) {
|
||||
return FTDM_FAIL;
|
||||
|
@ -191,55 +191,40 @@ ftdm_status_t sng_isdn_stack_cfg_phy_gen(void)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span)
|
||||
{
|
||||
ftdm_iterator_t *chaniter;
|
||||
ftdm_iterator_t *curr;
|
||||
L1Mngmt cfg;
|
||||
Pst pst;
|
||||
ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span)
|
||||
{
|
||||
L1Mngmt cfg;
|
||||
Pst pst;
|
||||
|
||||
int32_t d_channel_fd = -1;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
|
||||
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTL1;
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTL1;
|
||||
|
||||
/*clear the configuration structure*/
|
||||
/*clear the configuration structure*/
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
|
||||
/*fill in the specific fields of the header*/
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTL1;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STPSAP;
|
||||
/*fill in the specific fields of the header*/
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTL1;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STPSAP;
|
||||
|
||||
cfg.hdr.elmId.elmntInst1 = signal_data->link_id;
|
||||
|
||||
|
||||
/* Find the d-channel */
|
||||
chaniter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
|
||||
if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) {
|
||||
d_channel_fd = (int32_t)ftdmchan->sockfd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
|
||||
if(d_channel_fd < 0) {
|
||||
if (!signal_data->dchan) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s:No d-channels specified\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
cfg.t.cfg.s.l1PSAP.sockfd = d_channel_fd;
|
||||
|
||||
|
||||
cfg.t.cfg.s.l1PSAP.sockfd = (int32_t)signal_data->dchan->sockfd;
|
||||
|
||||
switch(span->trunk_type) {
|
||||
case FTDM_TRUNK_E1:
|
||||
cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_PRI;
|
||||
|
@ -255,8 +240,8 @@ ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span)
|
|||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported trunk type %d\n", span->name, span->trunk_type);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
cfg.t.cfg.s.l1PSAP.spId = signal_data->link_id;
|
||||
}
|
||||
cfg.t.cfg.s.l1PSAP.spId = signal_data->link_id;
|
||||
|
||||
if (sng_isdn_phy_config(&pst, &cfg)) {
|
||||
return FTDM_FAIL;
|
||||
|
@ -265,28 +250,28 @@ ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span)
|
|||
}
|
||||
|
||||
|
||||
ftdm_status_t sng_isdn_stack_cfg_q921_gen(void)
|
||||
ftdm_status_t sngisdn_stack_cfg_q921_gen(void)
|
||||
{
|
||||
BdMngmt cfg;
|
||||
Pst pst;
|
||||
Pst pst;
|
||||
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTLD;
|
||||
pst.dstEnt = ENTLD;
|
||||
|
||||
/*clear the configuration structure*/
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
/*clear the configuration structure*/
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTLD;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STGEN;
|
||||
/* fill in the Gen Conf structures internal pst struct */
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
|
||||
stack_pst_init(&cfg.t.cfg.s.bdGen.sm);
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTLD;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STGEN;
|
||||
/* fill in the Gen Conf structures internal pst struct */
|
||||
|
||||
stack_pst_init(&cfg.t.cfg.s.bdGen.sm);
|
||||
|
||||
cfg.t.cfg.s.bdGen.sm.dstEnt = ENTSM; /* entity */
|
||||
|
||||
|
@ -299,8 +284,8 @@ ftdm_status_t sng_isdn_stack_cfg_q921_gen(void)
|
|||
#ifdef LAPD_3_4
|
||||
cfg.t.cfg.s.bdGen.timeRes = 100; /* timer resolution = 1 sec */
|
||||
#endif
|
||||
cfg.t.cfg.s.bdGen.poolTrUpper = 2; /* upper pool threshold */
|
||||
cfg.t.cfg.s.bdGen.poolTrLower = 1; /* lower pool threshold */
|
||||
cfg.t.cfg.s.bdGen.poolTrUpper = 2; /* upper pool threshold */
|
||||
cfg.t.cfg.s.bdGen.poolTrLower = 1; /* lower pool threshold */
|
||||
|
||||
if (sng_isdn_q921_config(&pst, &cfg)) {
|
||||
return FTDM_FAIL;
|
||||
|
@ -308,30 +293,30 @@ ftdm_status_t sng_isdn_stack_cfg_q921_gen(void)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
|
||||
ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span)
|
||||
{
|
||||
BdMngmt cfg;
|
||||
Pst pst;
|
||||
Pst pst;
|
||||
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
|
||||
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTLD;
|
||||
pst.dstEnt = ENTLD;
|
||||
|
||||
/*clear the configuration structure*/
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
/*clear the configuration structure*/
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTLD;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STMSAP;
|
||||
cfg.hdr.entId.ent = ENTLD;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STMSAP;
|
||||
|
||||
cfg.t.cfg.s.bdMSAP.lnkNmb = signal_data->link_id;
|
||||
|
||||
|
||||
cfg.t.cfg.s.bdMSAP.maxOutsFrms = 24; /* MAC window */
|
||||
cfg.t.cfg.s.bdMSAP.tQUpperTrs = 32; /* Tx Queue Upper Threshold */
|
||||
cfg.t.cfg.s.bdMSAP.tQLowerTrs = 24; /* Tx Queue Lower Threshold */
|
||||
|
@ -343,7 +328,7 @@ ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
|
|||
cfg.t.cfg.s.bdMSAP.route = RTESPEC; /* Route */
|
||||
cfg.t.cfg.s.bdMSAP.dstProcId = SFndProcId(); /* destination proc id */
|
||||
cfg.t.cfg.s.bdMSAP.dstEnt = ENTL1; /* entity */
|
||||
cfg.t.cfg.s.bdMSAP.dstInst = S_INST; /* instance */
|
||||
cfg.t.cfg.s.bdMSAP.dstInst = S_INST; /* instance */
|
||||
cfg.t.cfg.s.bdMSAP.t201Tmr = 1; /* T201 - should be equal to t200Tmr */
|
||||
cfg.t.cfg.s.bdMSAP.t202Tmr = 2; /* T202 */
|
||||
cfg.t.cfg.s.bdMSAP.bndRetryCnt = 2; /* bind retry counter */
|
||||
|
@ -392,7 +377,7 @@ ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
|
|||
if (signal_data->setup_arb == SNGISDN_OPT_TRUE) {
|
||||
cfg.t.cfg.s.bdMSAP.setUpArb = ACTIVE;
|
||||
} else if (signal_data->setup_arb == SNGISDN_OPT_FALSE) {
|
||||
cfg.t.cfg.s.bdMSAP.setUpArb = PASSIVE;
|
||||
cfg.t.cfg.s.bdMSAP.setUpArb = PASSIVE;
|
||||
}
|
||||
|
||||
if (sng_isdn_q921_config(&pst, &cfg)) {
|
||||
|
@ -401,27 +386,27 @@ ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management)
|
||||
ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management)
|
||||
{
|
||||
BdMngmt cfg;
|
||||
Pst pst;
|
||||
Pst pst;
|
||||
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTLD;
|
||||
pst.dstEnt = ENTLD;
|
||||
|
||||
/*clear the configuration structure*/
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
/*clear the configuration structure*/
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
|
||||
/*fill in the specific fields of the header*/
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTLD;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STDLSAP;
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTLD;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STDLSAP;
|
||||
|
||||
cfg.t.cfg.s.bdDLSAP.lnkNmb = signal_data->link_id;
|
||||
|
||||
|
@ -433,10 +418,10 @@ ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t managemen
|
|||
} else {
|
||||
cfg.t.cfg.s.bdDLSAP.k = 7; /* k */
|
||||
}
|
||||
|
||||
|
||||
cfg.t.cfg.s.bdDLSAP.n200 = 3; /* n200 */
|
||||
cfg.t.cfg.s.bdDLSAP.congTmr = 300; /* congestion timer */
|
||||
cfg.t.cfg.s.bdDLSAP.t200Tmr = 1; /* t1 changed from 25 */
|
||||
cfg.t.cfg.s.bdDLSAP.t200Tmr = 1; /* t1 changed from 25 */
|
||||
cfg.t.cfg.s.bdDLSAP.t203Tmr = 10; /* t3 changed from 50 */
|
||||
cfg.t.cfg.s.bdDLSAP.mod = 128; /* modulo */
|
||||
cfg.t.cfg.s.bdDLSAP.selector = 0; /* Selector 0 */
|
||||
|
@ -483,31 +468,31 @@ ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t managemen
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_stack_cfg_q931_gen(void)
|
||||
ftdm_status_t sngisdn_stack_cfg_q931_gen(void)
|
||||
{
|
||||
InMngmt cfg;
|
||||
Pst pst;
|
||||
Pst pst;
|
||||
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTIN;
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTIN;
|
||||
|
||||
/*clear the configuration structure*/
|
||||
/*clear the configuration structure*/
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
|
||||
/*fill in the specific fields of the header*/
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTIN;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STGEN;
|
||||
/*fill in the specific fields of the header*/
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTIN;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STGEN;
|
||||
|
||||
/* fill in the Gen Conf structures internal pst struct */
|
||||
stack_pst_init(&cfg.t.cfg.s.inGen.sm);
|
||||
/* fill in the Gen Conf structures internal pst struct */
|
||||
stack_pst_init(&cfg.t.cfg.s.inGen.sm);
|
||||
|
||||
cfg.t.cfg.s.inGen.nmbSaps = MAX_VARIANTS+1; /* Total number of variants supported */
|
||||
|
||||
|
@ -538,29 +523,29 @@ ftdm_status_t sng_isdn_stack_cfg_q931_gen(void)
|
|||
}
|
||||
|
||||
/* Link between CC and q931 */
|
||||
ftdm_status_t sng_isdn_stack_cfg_q931_tsap(ftdm_span_t *span)
|
||||
ftdm_status_t sngisdn_stack_cfg_q931_tsap(ftdm_span_t *span)
|
||||
{
|
||||
InMngmt cfg;
|
||||
Pst pst;
|
||||
Pst pst;
|
||||
unsigned i;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTIN;
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTIN;
|
||||
|
||||
/*clear the configuration structure*/
|
||||
/*clear the configuration structure*/
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
|
||||
/*fill in the specific fields of the header*/
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTIN;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STTSAP;
|
||||
/*fill in the specific fields of the header*/
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTIN;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STTSAP;
|
||||
|
||||
cfg.t.cfg.s.inTSAP.sapId = signal_data->cc_id;
|
||||
|
||||
|
@ -601,34 +586,34 @@ ftdm_status_t sng_isdn_stack_cfg_q931_tsap(ftdm_span_t *span)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
|
||||
ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
|
||||
{
|
||||
InMngmt cfg;
|
||||
Pst pst;
|
||||
Pst pst;
|
||||
|
||||
unsigned i;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTIN;
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTIN;
|
||||
|
||||
/*clear the configuration structure*/
|
||||
/*clear the configuration structure*/
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
|
||||
/*fill in the specific fields of the header*/
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTIN;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STDLSAP;
|
||||
|
||||
/*fill in the specific fields of the header*/
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTIN;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STDLSAP;
|
||||
|
||||
cfg.hdr.response.selector=0;
|
||||
|
||||
|
||||
|
||||
cfg.t.cfg.s.inDLSAP.sapId = signal_data->link_id;
|
||||
cfg.t.cfg.s.inDLSAP.spId = signal_data->link_id;
|
||||
cfg.t.cfg.s.inDLSAP.swtch = sng_isdn_stack_switchtype(signal_data->switchtype);
|
||||
|
@ -674,7 +659,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
|
|||
cfg.t.cfg.s.inDLSAP.ctldInt[1] = 1;
|
||||
}
|
||||
|
||||
cfg.t.cfg.s.inDLSAP.numRstInd = 255;
|
||||
cfg.t.cfg.s.inDLSAP.numRstInd = 255;
|
||||
cfg.t.cfg.s.inDLSAP.relOpt = TRUE;
|
||||
#ifdef ISDN_SRV
|
||||
cfg.t.cfg.s.inDLSAP.bcas = FALSE;
|
||||
|
@ -860,39 +845,39 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span)
|
||||
ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span)
|
||||
{
|
||||
InMngmt cfg;
|
||||
Pst pst;
|
||||
Pst pst;
|
||||
uint8_t i;
|
||||
uint8_t numCes=1;
|
||||
uint8_t numCes=1;
|
||||
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
|
||||
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP && signal_data->signalling == SNGISDN_SIGNALING_NET) {
|
||||
numCes = 8;
|
||||
}
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTIN;
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTIN;
|
||||
|
||||
/*clear the configuration structure*/
|
||||
/*clear the configuration structure*/
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
/*fill in some general sections of the header*/
|
||||
stack_hdr_init(&cfg.hdr);
|
||||
|
||||
/*fill in the specific fields of the header*/
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTIN;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STDLC;
|
||||
/*fill in the specific fields of the header*/
|
||||
cfg.hdr.msgType = TCFG;
|
||||
cfg.hdr.entId.ent = ENTIN;
|
||||
cfg.hdr.entId.inst = S_INST;
|
||||
cfg.hdr.elmId.elmnt = STDLC;
|
||||
|
||||
cfg.hdr.response.selector=0;
|
||||
|
||||
cfg.t.cfg.s.inLCe.sapId = signal_data->link_id;
|
||||
|
||||
|
||||
|
||||
cfg.t.cfg.s.inLCe.lnkUpDwnInd = TRUE;
|
||||
cfg.t.cfg.s.inLCe.tCon.enb = TRUE;
|
||||
|
@ -901,7 +886,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span)
|
|||
cfg.t.cfg.s.inLCe.tDisc.val = 35;
|
||||
cfg.t.cfg.s.inLCe.t314.enb = FALSE; /* if segmentation enabled, set to TRUE */
|
||||
cfg.t.cfg.s.inLCe.t314.val = 35;
|
||||
|
||||
|
||||
cfg.t.cfg.s.inLCe.t332i.enb = FALSE; /* set to TRUE for NFAS */
|
||||
|
||||
#ifdef NFAS
|
||||
|
@ -921,7 +906,6 @@ ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span)
|
|||
cfg.t.cfg.s.inLCe.tRstAck.enb = TRUE;
|
||||
cfg.t.cfg.s.inLCe.tRstAck.val = 10;
|
||||
|
||||
|
||||
cfg.t.cfg.s.inLCe.usid = 0;
|
||||
cfg.t.cfg.s.inLCe.tid = 0;
|
||||
|
||||
|
@ -936,7 +920,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span)
|
|||
}
|
||||
|
||||
|
||||
ftdm_status_t sng_isdn_stack_cfg_cc_gen(void)
|
||||
ftdm_status_t sngisdn_stack_cfg_cc_gen(void)
|
||||
{
|
||||
CcMngmt cfg;
|
||||
Pst pst;
|
||||
|
@ -975,7 +959,7 @@ ftdm_status_t sng_isdn_stack_cfg_cc_gen(void)
|
|||
}
|
||||
|
||||
|
||||
ftdm_status_t sng_isdn_stack_cfg_cc_sap(ftdm_span_t *span)
|
||||
ftdm_status_t sngisdn_stack_cfg_cc_sap(ftdm_span_t *span)
|
||||
{
|
||||
CcMngmt cfg;
|
||||
Pst pst;
|
||||
|
@ -1007,11 +991,11 @@ ftdm_status_t sng_isdn_stack_cfg_cc_sap(ftdm_span_t *span)
|
|||
cfg.t.cfg.s.ccISAP.pst.dstInst = S_INST;
|
||||
cfg.t.cfg.s.ccISAP.pst.dstProcId = SFndProcId();
|
||||
|
||||
cfg.t.cfg.s.ccISAP.pst.prior = PRIOR0;
|
||||
cfg.t.cfg.s.ccISAP.pst.route = RTESPEC;
|
||||
cfg.t.cfg.s.ccISAP.pst.region = S_REG;
|
||||
cfg.t.cfg.s.ccISAP.pst.pool = S_POOL;
|
||||
cfg.t.cfg.s.ccISAP.pst.selector = 0;
|
||||
cfg.t.cfg.s.ccISAP.pst.prior = PRIOR0;
|
||||
cfg.t.cfg.s.ccISAP.pst.route = RTESPEC;
|
||||
cfg.t.cfg.s.ccISAP.pst.region = S_REG;
|
||||
cfg.t.cfg.s.ccISAP.pst.pool = S_POOL;
|
||||
cfg.t.cfg.s.ccISAP.pst.selector = 0;
|
||||
|
||||
cfg.t.cfg.s.ccISAP.suId = signal_data->cc_id;
|
||||
cfg.t.cfg.s.ccISAP.spId = signal_data->cc_id;
|
||||
|
@ -1029,19 +1013,19 @@ ftdm_status_t sng_isdn_stack_cfg_cc_sap(ftdm_span_t *span)
|
|||
void stack_pst_init(Pst *pst)
|
||||
{
|
||||
memset(pst, 0, sizeof(Pst));
|
||||
/*fill in the post structure*/
|
||||
pst->dstProcId = SFndProcId();
|
||||
pst->dstInst = S_INST;
|
||||
/*fill in the post structure*/
|
||||
pst->dstProcId = SFndProcId();
|
||||
pst->dstInst = S_INST;
|
||||
|
||||
pst->srcProcId = SFndProcId();
|
||||
pst->srcEnt = ENTSM;
|
||||
pst->srcInst = S_INST;
|
||||
pst->srcProcId = SFndProcId();
|
||||
pst->srcEnt = ENTSM;
|
||||
pst->srcInst = S_INST;
|
||||
|
||||
pst->prior = PRIOR0;
|
||||
pst->route = RTESPEC;
|
||||
pst->region = S_REG;
|
||||
pst->pool = S_POOL;
|
||||
pst->selector = 0;
|
||||
pst->prior = PRIOR0;
|
||||
pst->route = RTESPEC;
|
||||
pst->region = S_REG;
|
||||
pst->pool = S_POOL;
|
||||
pst->selector = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1050,21 +1034,21 @@ void stack_pst_init(Pst *pst)
|
|||
void stack_hdr_init(Header *hdr)
|
||||
{
|
||||
hdr->msgType = 0;
|
||||
hdr->msgLen = 0;
|
||||
hdr->entId.ent = 0;
|
||||
hdr->entId.inst = 0;
|
||||
hdr->elmId.elmnt = 0;
|
||||
hdr->elmId.elmntInst1 = 0;
|
||||
hdr->elmId.elmntInst2 = 0;
|
||||
hdr->elmId.elmntInst3 = 0;
|
||||
hdr->seqNmb = 0;
|
||||
hdr->version = 0;
|
||||
hdr->response.prior = PRIOR0;
|
||||
hdr->response.route = RTESPEC;
|
||||
hdr->response.mem.region = S_REG;
|
||||
hdr->response.mem.pool = S_POOL;
|
||||
hdr->transId = 0;
|
||||
hdr->response.selector = 0;
|
||||
hdr->msgLen = 0;
|
||||
hdr->entId.ent = 0;
|
||||
hdr->entId.inst = 0;
|
||||
hdr->elmId.elmnt = 0;
|
||||
hdr->elmId.elmntInst1 = 0;
|
||||
hdr->elmId.elmntInst2 = 0;
|
||||
hdr->elmId.elmntInst3 = 0;
|
||||
hdr->seqNmb = 0;
|
||||
hdr->version = 0;
|
||||
hdr->response.prior = PRIOR0;
|
||||
hdr->response.route = RTESPEC;
|
||||
hdr->response.mem.region = S_REG;
|
||||
hdr->response.mem.pool = S_POOL;
|
||||
hdr->transId = 0;
|
||||
hdr->response.selector = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,27 +37,26 @@
|
|||
|
||||
void stack_resp_hdr_init(Header *hdr);
|
||||
|
||||
ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_activate_phy(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_deactivate_phy(ftdm_span_t *span);
|
||||
|
||||
ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt);
|
||||
ftdm_status_t sngisdn_activate_cc(ftdm_span_t *span);
|
||||
|
||||
ftdm_status_t sng_isdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction);
|
||||
ftdm_status_t sng_isdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction);
|
||||
ftdm_status_t sngisdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction);
|
||||
ftdm_status_t sngisdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction);
|
||||
|
||||
|
||||
extern ftdm_sngisdn_data_t g_sngisdn_data;
|
||||
|
||||
ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span);
|
||||
|
||||
|
||||
ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span)
|
||||
ftdm_status_t sngisdn_stack_start(ftdm_span_t *span)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
|
||||
|
||||
|
||||
if (sng_isdn_cntrl_q921(span, ABND_ENA, NOTUSED) != FTDM_SUCCESS) {
|
||||
if (sngisdn_cntrl_q921(span, ABND_ENA, NOTUSED) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q921\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -72,7 +71,7 @@ ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span)
|
|||
ftdm_log(FTDM_LOG_DEBUG, "%s:Stack q921 activated\n", span->name);
|
||||
if (!g_sngisdn_data.ccs[signal_data->cc_id].activation_done) {
|
||||
g_sngisdn_data.ccs[signal_data->cc_id].activation_done = 1;
|
||||
if (sng_isdn_activate_cc(span) != FTDM_SUCCESS) {
|
||||
if (sngisdn_activate_cc(span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack CC\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -80,7 +79,7 @@ ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span)
|
|||
}
|
||||
|
||||
|
||||
if (sng_isdn_cntrl_q931(span, ABND_ENA, SAELMNT) != FTDM_SUCCESS) {
|
||||
if (sngisdn_cntrl_q931(span, ABND_ENA, SAELMNT) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q931\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -90,20 +89,20 @@ ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span)
|
||||
ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span)
|
||||
{
|
||||
/* Stop L1 first, so we do not receive any more frames */
|
||||
if (sng_isdn_deactivate_phy(span) != FTDM_SUCCESS) {
|
||||
if (sngisdn_deactivate_phy(span) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack phy\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (sng_isdn_cntrl_q931(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
|
||||
if (sngisdn_cntrl_q931(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q931\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (sng_isdn_cntrl_q921(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
|
||||
if (sngisdn_cntrl_q921(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q921\n", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -113,41 +112,7 @@ ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span)
|
|||
}
|
||||
|
||||
|
||||
ftdm_status_t sng_isdn_wake_up_phy(ftdm_span_t *span)
|
||||
{
|
||||
L1Mngmt cntrl;
|
||||
Pst pst;
|
||||
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
|
||||
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTL1;
|
||||
|
||||
/* initalize the control structure */
|
||||
memset(&cntrl, 0, sizeof(cntrl));
|
||||
|
||||
/* initalize the control header */
|
||||
stack_hdr_init(&cntrl.hdr);
|
||||
|
||||
cntrl.hdr.msgType = TCNTRL; /* configuration */
|
||||
cntrl.hdr.entId.ent = ENTL1; /* entity */
|
||||
cntrl.hdr.entId.inst = S_INST; /* instance */
|
||||
cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */
|
||||
|
||||
cntrl.t.cntrl.action = AENA;
|
||||
cntrl.t.cntrl.subAction = SAELMNT;
|
||||
cntrl.t.cntrl.sapId = signal_data->link_id;
|
||||
|
||||
if (sng_isdn_phy_cntrl(&pst, &cntrl)) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span)
|
||||
ftdm_status_t sngisdn_activate_phy(ftdm_span_t *span)
|
||||
{
|
||||
|
||||
/* There is no need to start phy, as it will Q921 will send a activate request to phy when it starts */
|
||||
|
@ -155,7 +120,7 @@ ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span)
|
||||
ftdm_status_t sngisdn_deactivate_phy(ftdm_span_t *span)
|
||||
{
|
||||
L1Mngmt cntrl;
|
||||
Pst pst;
|
||||
|
@ -189,8 +154,41 @@ ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span)
|
||||
{
|
||||
L1Mngmt cntrl;
|
||||
Pst pst;
|
||||
|
||||
ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span)
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
|
||||
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTL1;
|
||||
|
||||
/* initalize the control structure */
|
||||
memset(&cntrl, 0, sizeof(cntrl));
|
||||
|
||||
/* initalize the control header */
|
||||
stack_hdr_init(&cntrl.hdr);
|
||||
|
||||
cntrl.hdr.msgType = TCNTRL; /* configuration */
|
||||
cntrl.hdr.entId.ent = ENTL1; /* entity */
|
||||
cntrl.hdr.entId.inst = S_INST; /* instance */
|
||||
cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */
|
||||
|
||||
cntrl.t.cntrl.action = AENA;
|
||||
cntrl.t.cntrl.subAction = SAELMNT;
|
||||
cntrl.t.cntrl.sapId = signal_data->link_id;
|
||||
|
||||
if (sng_isdn_phy_cntrl(&pst, &cntrl)) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sngisdn_activate_cc(ftdm_span_t *span)
|
||||
{
|
||||
CcMngmt cntrl;
|
||||
Pst pst;
|
||||
|
@ -224,7 +222,7 @@ ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt)
|
||||
ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
|
||||
switch (trace_opt) {
|
||||
|
@ -233,7 +231,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
|
|||
ftdm_log(FTDM_LOG_INFO, "s%d Disabling q921 trace\n", signal_data->link_id);
|
||||
sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q921);
|
||||
|
||||
if (sng_isdn_cntrl_q921(span, ADISIMM, SATRC) != FTDM_SUCCESS) {
|
||||
if (sngisdn_cntrl_q921(span, ADISIMM, SATRC) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "s%d Failed to disable q921 trace\n");
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +239,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
|
|||
ftdm_log(FTDM_LOG_INFO, "s%d Disabling q931 trace\n", signal_data->link_id);
|
||||
sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q931);
|
||||
|
||||
if (sng_isdn_cntrl_q931(span, ADISIMM, SATRC) != FTDM_SUCCESS) {
|
||||
if (sngisdn_cntrl_q931(span, ADISIMM, SATRC) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "s%d Failed to disable q931 trace\n");
|
||||
}
|
||||
}
|
||||
|
@ -251,7 +249,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
|
|||
ftdm_log(FTDM_LOG_INFO, "s%d Enabling q921 trace\n", signal_data->link_id);
|
||||
sngisdn_set_trace_flag(signal_data, SNGISDN_TRACE_Q921);
|
||||
|
||||
if (sng_isdn_cntrl_q921(span, AENA, SATRC) != FTDM_SUCCESS) {
|
||||
if (sngisdn_cntrl_q921(span, AENA, SATRC) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "s%d Failed to enable q921 trace\n");
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +259,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
|
|||
ftdm_log(FTDM_LOG_INFO, "s%d Enabling q931 trace\n", signal_data->link_id);
|
||||
sngisdn_set_trace_flag(signal_data, SNGISDN_TRACE_Q931);
|
||||
|
||||
if (sng_isdn_cntrl_q931(span, AENA, SATRC) != FTDM_SUCCESS) {
|
||||
if (sngisdn_cntrl_q931(span, AENA, SATRC) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "s%d Failed to enable q931 trace\n");
|
||||
}
|
||||
}
|
||||
|
@ -271,7 +269,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
|
|||
}
|
||||
|
||||
|
||||
ftdm_status_t sng_isdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction)
|
||||
ftdm_status_t sngisdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction)
|
||||
{
|
||||
InMngmt cntrl;
|
||||
Pst pst;
|
||||
|
@ -310,7 +308,7 @@ ftdm_status_t sng_isdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t sub
|
|||
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction)
|
||||
ftdm_status_t sngisdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction)
|
||||
{
|
||||
BdMngmt cntrl;
|
||||
Pst pst;
|
||||
|
|
|
@ -127,10 +127,16 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1");
|
||||
#endif
|
||||
/* Fill in call information */
|
||||
cpy_calling_num_from_stack(&ftdmchan->caller_data, &conEvnt->cgPtyNmb);
|
||||
cpy_called_num_from_stack(&ftdmchan->caller_data, &conEvnt->cdPtyNmb);
|
||||
cpy_calling_name_from_stack(&ftdmchan->caller_data, &conEvnt->display);
|
||||
cpy_redir_num_from_stack(&ftdmchan->caller_data, &conEvnt->redirNmb);
|
||||
get_calling_num(ftdmchan, &conEvnt->cgPtyNmb);
|
||||
get_called_num(ftdmchan, &conEvnt->cdPtyNmb);
|
||||
get_redir_num(ftdmchan, &conEvnt->redirNmb);
|
||||
get_calling_subaddr(ftdmchan, &conEvnt->cgPtySad);
|
||||
|
||||
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);
|
||||
|
||||
if (conEvnt->bearCap[0].eh.pres) {
|
||||
|
@ -138,37 +144,43 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
ftdmchan->caller_data.bearer_capability = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].infoTranCap.val);
|
||||
}
|
||||
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_NI2) {
|
||||
if (conEvnt->shift11.eh.pres && conEvnt->ni2OctStr.eh.pres) {
|
||||
if (conEvnt->ni2OctStr.str.len == 4 && conEvnt->ni2OctStr.str.val[0] == 0x37) {
|
||||
snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", conEvnt->ni2OctStr.str.val[3]);
|
||||
}
|
||||
|
||||
if (conEvnt->shift11.eh.pres && conEvnt->ni2OctStr.eh.pres) {
|
||||
if (conEvnt->ni2OctStr.str.len == 4 && conEvnt->ni2OctStr.str.val[0] == 0x37) {
|
||||
snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", conEvnt->ni2OctStr.str.val[3]);
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
}
|
||||
|
||||
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]);
|
||||
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];
|
||||
|
||||
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;
|
||||
} else if (ret_val == 0) {
|
||||
strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -243,11 +255,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
uint8_t ces = sngisdn_event->ces;
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt;
|
||||
|
||||
/* Function does not require any info from conStEvnt struct for now */
|
||||
/* CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; */
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
|
||||
|
||||
|
@ -269,9 +279,11 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
|
@ -335,9 +347,13 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
suId, suInstId, spInstId, ces);
|
||||
|
||||
switch(evntType) {
|
||||
case MI_CALLPROC:
|
||||
case MI_PROGRESS:
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_NI2 &&
|
||||
cnStEvnt->causeDgn[0].eh.pres && cnStEvnt->causeDgn[0].causeVal.pres) {
|
||||
case MI_ALERTING:
|
||||
get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd);
|
||||
|
||||
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 */
|
||||
|
@ -362,22 +378,20 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
goto sngisdn_process_cnst_ind_end;
|
||||
}
|
||||
}
|
||||
/* fall-through */
|
||||
case MI_ALERTING:
|
||||
case MI_CALLPROC:
|
||||
|
||||
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
if (evntType == MI_PROGRESS ||
|
||||
(cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL)) {
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
} else if (evntType == MI_CALLPROC) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED);
|
||||
} else {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
if (evntType == MI_PROGRESS ||
|
||||
(cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL)) {
|
||||
if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
}
|
||||
break;
|
||||
|
@ -406,7 +420,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
ftdm_size_t min_digits = ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->min_digits;
|
||||
ftdm_size_t num_digits;
|
||||
|
||||
cpy_called_num_from_stack(&ftdmchan->caller_data, &cnStEvnt->cdPtyNmb);
|
||||
get_called_num(ftdmchan, &cnStEvnt->cdPtyNmb);
|
||||
num_digits = strlen(ftdmchan->caller_data.dnis.digits);
|
||||
|
||||
if (cnStEvnt->sndCmplt.eh.pres || num_digits >= min_digits) {
|
||||
|
@ -417,6 +431,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
|
@ -446,6 +461,7 @@ 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;
|
||||
|
||||
|
@ -454,12 +470,20 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
|
||||
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
|
||||
switch (ftdmchan->state) {
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
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 */
|
||||
}
|
||||
}
|
||||
if (discEvnt->causeDgn[0].eh.pres && discEvnt->causeDgn[0].causeVal.pres) {
|
||||
ftdmchan->caller_data.hangup_cause = discEvnt->causeDgn[0].causeVal.val;
|
||||
} else {
|
||||
|
@ -503,6 +527,7 @@ 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;
|
||||
|
||||
|
@ -535,9 +560,10 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
/* Remote side rejected our SETUP message on outbound call */
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
sng_isdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
|
||||
sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
|
||||
}
|
||||
/* fall-through */
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
|
@ -547,6 +573,15 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
not changed while we were waiting for ftdmchan->mutex by comparing suInstId's */
|
||||
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 */
|
||||
}
|
||||
}
|
||||
|
||||
if (relEvnt->causeDgn[0].eh.pres && relEvnt->causeDgn[0].causeVal.pres) {
|
||||
ftdmchan->caller_data.hangup_cause = relEvnt->causeDgn[0].causeVal.val;
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "cause:%d\n", ftdmchan->caller_data.hangup_cause);
|
||||
|
@ -725,15 +760,16 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_GET_CALLERID:
|
||||
/* Update the caller ID Name */
|
||||
|
||||
if (facEvnt->facElmt.facStr.pres) {
|
||||
char retrieved_str[255];
|
||||
|
||||
|
||||
/* 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 (sng_isdn_retrieve_facility_caller_name(&facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len, retrieved_str) == 0) {
|
||||
strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
|
||||
} else {
|
||||
|
@ -751,6 +787,25 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
/* We received the caller ID Name in FACILITY, but its too late, facility-timeout already occurred */
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "FACILITY received, but we already proceeded with call\n");
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
{
|
||||
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 */
|
||||
}
|
||||
}
|
||||
memset(&sigev, 0, sizeof(sigev));
|
||||
sigev.chan_id = ftdmchan->chan_id;
|
||||
sigev.span_id = ftdmchan->span_id;
|
||||
sigev.channel = ftdmchan;
|
||||
|
||||
sigev.event_id = FTDM_SIGEVENT_MSG;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* We do not support other FACILITY types for now, so do nothing */
|
||||
break;
|
||||
|
@ -865,6 +920,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T302 Timer expired, proceeding with call\n");
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Remote switch expecting OVERLAP receive, but we are already PROCEEDING\n");
|
||||
|
@ -882,6 +938,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
|
|||
break;
|
||||
case 3:
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
/* T310 timer has expired */
|
||||
ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val;
|
||||
|
|
|
@ -34,18 +34,12 @@
|
|||
|
||||
#include "ftmod_sangoma_isdn.h"
|
||||
|
||||
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_progress(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_connect(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare);
|
||||
|
||||
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ConEvnt conEvnt;
|
||||
ConEvnt conEvnt;
|
||||
sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
|
||||
|
||||
ftdm_assert((!sngisdn_info->suInstId && !sngisdn_info->spInstId), "Trying to call out, but call data was not cleared\n");
|
||||
|
||||
|
@ -123,14 +117,6 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
|||
conEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
conEvnt.progInd.eh.pres = PRSNT_NODEF;
|
||||
conEvnt.progInd.location.pres = PRSNT_NODEF;
|
||||
conEvnt.progInd.location.val = IN_LOC_USER;
|
||||
conEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
|
||||
conEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
|
||||
conEvnt.progInd.progDesc.pres = PRSNT_NODEF;
|
||||
conEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN; /* Not end-to-end ISDN */
|
||||
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
|
||||
conEvnt.sndCmplt.eh.pres = PRSNT_NODEF;
|
||||
}
|
||||
|
@ -140,10 +126,13 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Outgoing call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
|
||||
|
||||
cpy_called_num_from_user(&conEvnt.cdPtyNmb, &ftdmchan->caller_data);
|
||||
cpy_calling_num_from_user(&conEvnt.cgPtyNmb, &ftdmchan->caller_data);
|
||||
cpy_redir_num_from_user(&conEvnt.redirNmb, &ftdmchan->caller_data);
|
||||
cpy_calling_name_from_user(&conEvnt, ftdmchan);
|
||||
set_called_num(ftdmchan, &conEvnt.cdPtyNmb);
|
||||
set_calling_num(ftdmchan, &conEvnt.cgPtyNmb);
|
||||
set_calling_subaddr(ftdmchan, &conEvnt.cgPtySad);
|
||||
set_redir_num(ftdmchan, &conEvnt.redirNmb);
|
||||
set_calling_name(ftdmchan, &conEvnt);
|
||||
set_facility_ie(ftdmchan, &conEvnt.facilityStr);
|
||||
set_prog_ind_ie(ftdmchan, &conEvnt.progInd, prog_ind);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP (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);
|
||||
|
||||
|
@ -330,14 +319,14 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan)
|
|||
return;
|
||||
}
|
||||
|
||||
void sngisdn_snd_progress(ftdm_channel_t *ftdmchan)
|
||||
void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind)
|
||||
{
|
||||
CnStEvnt cnStEvnt;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending PROGRESS, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
|
@ -351,14 +340,7 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
cnStEvnt.progInd.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.location.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.location.val = IN_LOC_USER;
|
||||
cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
|
||||
cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.progDesc.val = IN_PD_IBAVAIL;
|
||||
set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS (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);
|
||||
if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, signal_data->dchan_id, sngisdn_info->ces)) {
|
||||
|
@ -367,14 +349,14 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan)
|
|||
return;
|
||||
}
|
||||
|
||||
void sngisdn_snd_alert(ftdm_channel_t *ftdmchan)
|
||||
void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind)
|
||||
{
|
||||
CnStEvnt cnStEvnt;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending ALERT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
|
@ -383,13 +365,7 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan)
|
|||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
cnStEvnt.progInd.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.location.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.location.val = IN_LOC_USER;
|
||||
cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
|
||||
cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN;
|
||||
set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending ALERT (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);
|
||||
|
||||
|
@ -401,10 +377,10 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan)
|
|||
|
||||
void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
CnStEvnt cnStEvnt;
|
||||
|
||||
CnStEvnt cnStEvnt;
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
|
||||
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending CONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
|
@ -415,7 +391,6 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
|
|||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
|
||||
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
|
||||
|
@ -447,14 +422,8 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
|
|||
cnStEvnt.chanId.chanNmbSlotMap.len = 1;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
cnStEvnt.progInd.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.location.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.location.val = IN_LOC_USER;
|
||||
cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
|
||||
cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN; /* Not end-to-end ISDN */
|
||||
|
||||
set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT (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);
|
||||
if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) {
|
||||
|
@ -463,6 +432,32 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
|
|||
return;
|
||||
}
|
||||
|
||||
void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
FacEvnt facEvnt;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending FACILITY, but no call data, ignoring (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&facEvnt, 0, sizeof(facEvnt));
|
||||
|
||||
set_facility_ie_str(ftdmchan, &facEvnt.facElmt.facStr.val[2], (ftdm_size_t*)&facEvnt.facElmt.facStr.len);
|
||||
|
||||
facEvnt.facElmt.facStr.val[0] = 0x1C;
|
||||
facEvnt.facElmt.facStr.val[1] = facEvnt.facElmt.facStr.len;
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending FACILITY (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);
|
||||
|
||||
if (sng_isdn_facility_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &facEvnt, MI_FACIL, signal_data->dchan_id, sngisdn_info->ces)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused FACILITY request\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
|
@ -517,7 +512,7 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
|
|||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending DISCONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
|
||||
|
@ -538,6 +533,8 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
|
|||
discEvnt.causeDgn[0].recommend.pres = NOTPRSNT;
|
||||
discEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT;
|
||||
|
||||
set_facility_ie(ftdmchan, &discEvnt.facilityStr);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
if (sng_isdn_disc_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &discEvnt)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused DISCONNECT request\n");
|
||||
|
@ -582,6 +579,8 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
|
|||
spInstId = sngisdn_info->spInstId;
|
||||
}
|
||||
|
||||
set_facility_ie(ftdmchan, &relEvnt.facilityStr);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RELEASE/RELEASE COMPLETE (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, suInstId, spInstId);
|
||||
|
||||
if (glare) {
|
||||
|
@ -597,6 +596,74 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
|
|||
}
|
||||
|
||||
|
||||
/* We received an incoming frame on the d-channel, send data to the stack */
|
||||
void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)
|
||||
{
|
||||
sng_l1_frame_t l1_frame;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data;
|
||||
|
||||
memset(&l1_frame, 0, sizeof(l1_frame));
|
||||
l1_frame.len = len;
|
||||
|
||||
memcpy(&l1_frame.data, data, len);
|
||||
|
||||
if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_CRC)) {
|
||||
l1_frame.flags |= SNG_L1FRAME_ERROR_CRC;
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_FRAME)) {
|
||||
l1_frame.flags |= SNG_L1FRAME_ERROR_FRAME;
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_ABORT)) {
|
||||
l1_frame.flags |= SNG_L1FRAME_ERROR_ABORT;
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_FIFO)) {
|
||||
l1_frame.flags |= SNG_L1FRAME_ERROR_FIFO;
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_DMA)) {
|
||||
l1_frame.flags |= SNG_L1FRAME_ERROR_DMA;
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)) {
|
||||
/* Should we trigger congestion here? */
|
||||
l1_frame.flags |= SNG_L1FRAME_QUEUE_THRES;
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL)) {
|
||||
/* Should we trigger congestion here? */
|
||||
l1_frame.flags |= SNG_L1FRAME_QUEUE_FULL;
|
||||
}
|
||||
|
||||
sng_isdn_data_ind(signal_data->link_id, &l1_frame);
|
||||
}
|
||||
|
||||
void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event)
|
||||
{
|
||||
sng_l1_event_t l1_event;
|
||||
sngisdn_span_data_t *signal_data = NULL;
|
||||
memset(&l1_event, 0, sizeof(l1_event));
|
||||
|
||||
|
||||
signal_data = (sngisdn_span_data_t*) dchan->span->signal_data;
|
||||
switch(event) {
|
||||
case FTDM_OOB_ALARM_CLEAR:
|
||||
l1_event.type = SNG_L1EVENT_ALARM_OFF;
|
||||
sng_isdn_event_ind(signal_data->link_id, &l1_event);
|
||||
break;
|
||||
case FTDM_OOB_ALARM_TRAP:
|
||||
l1_event.type = SNG_L1EVENT_ALARM_ON;
|
||||
sng_isdn_event_ind(signal_data->link_id, &l1_event);
|
||||
break;
|
||||
default:
|
||||
/* We do not care about the other OOB events for now */
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
|
|
|
@ -732,7 +732,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
|
|||
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
|
||||
|
||||
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP);
|
||||
sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
|
||||
sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n",
|
||||
status->t.usta.suId,
|
||||
|
@ -741,7 +741,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
|
|||
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
|
||||
|
||||
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN);
|
||||
sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
|
||||
sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -862,6 +862,82 @@ end_of_trace:
|
|||
return;
|
||||
}
|
||||
|
||||
/* The stacks is wants to transmit a frame */
|
||||
int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame)
|
||||
{
|
||||
ftdm_status_t status;
|
||||
ftdm_wait_flag_t flags = FTDM_WRITE;
|
||||
sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId];
|
||||
ftdm_size_t length = l1_frame->len;
|
||||
|
||||
ftdm_assert(signal_data, "Received Data request on unconfigured span\n");
|
||||
|
||||
do {
|
||||
flags = FTDM_WRITE;
|
||||
status = signal_data->dchan->fio->wait(signal_data->dchan, &flags, 1000);
|
||||
if (status != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_WARNING, "transmit timed-out\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if ((flags & FTDM_WRITE)) {
|
||||
status = signal_data->dchan->fio->write(signal_data->dchan, l1_frame->data, (ftdm_size_t*)&length);
|
||||
if (status != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_CRIT, "Failed to transmit frame\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
/* On WIN32, it is possible for poll to return without FTDM_WRITE flag set, so we try to retransmit */
|
||||
#ifndef WIN32
|
||||
} else {
|
||||
ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_WARNING, "Failed to poll for d-channel\n");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
} while(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd)
|
||||
{
|
||||
sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId];
|
||||
ftdm_assert(signal_data, "Received Data request on unconfigured span\n");
|
||||
|
||||
switch(l1_cmd->type) {
|
||||
case SNG_L1CMD_SET_LINK_STATUS:
|
||||
{
|
||||
ftdm_channel_hw_link_status_t status = FTDM_HW_LINK_CONNECTED;
|
||||
ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_SET_LINK_STATUS, &status);
|
||||
}
|
||||
break;
|
||||
case SNG_L1CMD_GET_LINK_STATUS:
|
||||
{
|
||||
ftdm_channel_hw_link_status_t status = 0;
|
||||
ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_GET_LINK_STATUS, &status);
|
||||
if (status == FTDM_HW_LINK_CONNECTED) {
|
||||
l1_cmd->cmd.status = 1;
|
||||
} else if (status == FTDM_HW_LINK_DISCONNECTED) {
|
||||
l1_cmd->cmd.status = 0;
|
||||
} else {
|
||||
ftdm_log_chan(signal_data->dchan, FTDM_LOG_CRIT, "Invalid link status reported %d\n", status);
|
||||
l1_cmd->cmd.status = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SNG_L1CMD_FLUSH_STATS:
|
||||
ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_FLUSH_IOSTATS, NULL);
|
||||
break;
|
||||
case SNG_L1CMD_FLUSH_BUFFERS:
|
||||
ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_FLUSH_BUFFERS, NULL);
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(signal_data->dchan, FTDM_LOG_CRIT, "Unsupported channel command:%d\n", l1_cmd->type);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_sng_assert(char *message)
|
||||
{
|
||||
ftdm_assert(0, message);
|
||||
|
|
|
@ -33,13 +33,22 @@
|
|||
*/
|
||||
|
||||
#include "ftmod_sangoma_isdn.h"
|
||||
#define SNGISDN_Q931_FACILITY_IE_ID 0x1C
|
||||
|
||||
/* ftmod_sangoma_isdn specific enum look-up functions */
|
||||
|
||||
SNGISDN_ENUM_NAMES(SNGISDN_PROGIND_DESCR_NAMES, SNGISDN_PROGIND_DESCR_STRINGS)
|
||||
SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_descr, ftdm_sngisdn_progind_descr2str, ftdm_sngisdn_progind_descr_t, SNGISDN_PROGIND_DESCR_NAMES, SNGISDN_PROGIND_DESCR_INVALID)
|
||||
|
||||
SNGISDN_ENUM_NAMES(SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_STRINGS)
|
||||
SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t, SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_INVALID)
|
||||
|
||||
ftdm_status_t sngisdn_check_free_ids(void);
|
||||
|
||||
extern ftdm_sngisdn_data_t g_sngisdn_data;
|
||||
void get_memory_info(void);
|
||||
|
||||
FT_DECLARE(void) clear_call_data(sngisdn_chan_data_t *sngisdn_info)
|
||||
void clear_call_data(sngisdn_chan_data_t *sngisdn_info)
|
||||
{
|
||||
uint32_t cc_id = ((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->cc_id;
|
||||
|
||||
|
@ -56,7 +65,7 @@ FT_DECLARE(void) clear_call_data(sngisdn_chan_data_t *sngisdn_info)
|
|||
return;
|
||||
}
|
||||
|
||||
FT_DECLARE(void) clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
|
||||
void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
|
||||
{
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Clearing glare data (suId:%d suInstId:%u spInstId:%u actv-suInstId:%u actv-spInstId:%u)\n",
|
||||
sngisdn_info->glare.suId,
|
||||
|
@ -81,7 +90,7 @@ FT_DECLARE(void) clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
|
|||
}
|
||||
|
||||
|
||||
FT_DECLARE(uint32_t) get_unique_suInstId(int16_t cc_id)
|
||||
uint32_t get_unique_suInstId(int16_t cc_id)
|
||||
{
|
||||
uint32_t suInstId;
|
||||
ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n");
|
||||
|
@ -103,7 +112,7 @@ FT_DECLARE(uint32_t) get_unique_suInstId(int16_t cc_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data)
|
||||
ftdm_status_t get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data)
|
||||
{
|
||||
ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n");
|
||||
ftdm_assert_return(g_sngisdn_data.ccs[cc_id].activation_done, FTDM_FAIL, "Trying to find call on unconfigured CC\n");
|
||||
|
@ -115,7 +124,7 @@ FT_DECLARE(ftdm_status_t) get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suIns
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data)
|
||||
ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data)
|
||||
{
|
||||
ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n");
|
||||
ftdm_assert_return(g_sngisdn_data.ccs[cc_id].activation_done, FTDM_FAIL, "Trying to find call on unconfigured CC\n");
|
||||
|
@ -127,9 +136,8 @@ FT_DECLARE(ftdm_status_t) get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spIns
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
|
||||
ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
|
||||
{
|
||||
|
||||
if (span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
|
@ -147,77 +155,84 @@ ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb)
|
||||
ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
|
||||
{
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
if (cgPtyNmb->eh.pres != PRSNT_NODEF) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (cgPtyNmb->screenInd.pres == PRSNT_NODEF) {
|
||||
ftdm->screen = cgPtyNmb->screenInd.val;
|
||||
caller_data->screen = cgPtyNmb->screenInd.val;
|
||||
}
|
||||
|
||||
if (cgPtyNmb->presInd0.pres == PRSNT_NODEF) {
|
||||
ftdm->pres = cgPtyNmb->presInd0.val;
|
||||
caller_data->pres = cgPtyNmb->presInd0.val;
|
||||
}
|
||||
|
||||
if (cgPtyNmb->nmbPlanId.pres == PRSNT_NODEF) {
|
||||
ftdm->cid_num.plan = cgPtyNmb->nmbPlanId.val;
|
||||
caller_data->cid_num.plan = cgPtyNmb->nmbPlanId.val;
|
||||
}
|
||||
|
||||
if (cgPtyNmb->typeNmb1.pres == PRSNT_NODEF) {
|
||||
ftdm->cid_num.type = cgPtyNmb->typeNmb1.val;
|
||||
caller_data->cid_num.type = cgPtyNmb->typeNmb1.val;
|
||||
}
|
||||
|
||||
if (cgPtyNmb->nmbDigits.pres == PRSNT_NODEF) {
|
||||
ftdm_copy_string(ftdm->cid_num.digits, (const char*)cgPtyNmb->nmbDigits.val, cgPtyNmb->nmbDigits.len+1);
|
||||
ftdm_copy_string(caller_data->cid_num.digits, (const char*)cgPtyNmb->nmbDigits.val, cgPtyNmb->nmbDigits.len+1);
|
||||
}
|
||||
memcpy(&caller_data->ani, &caller_data->cid_num, sizeof(caller_data->ani));
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb)
|
||||
ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb)
|
||||
{
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
if (cdPtyNmb->eh.pres != PRSNT_NODEF) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (cdPtyNmb->nmbPlanId.pres == PRSNT_NODEF) {
|
||||
ftdm->dnis.plan = cdPtyNmb->nmbPlanId.val;
|
||||
caller_data->dnis.plan = cdPtyNmb->nmbPlanId.val;
|
||||
}
|
||||
|
||||
if (cdPtyNmb->typeNmb0.pres == PRSNT_NODEF) {
|
||||
ftdm->dnis.type = cdPtyNmb->typeNmb0.val;
|
||||
caller_data->dnis.type = cdPtyNmb->typeNmb0.val;
|
||||
}
|
||||
|
||||
if (cdPtyNmb->nmbDigits.pres == PRSNT_NODEF) {
|
||||
unsigned i = strlen(ftdm->dnis.digits);
|
||||
/* In overlap receive mode, append the new digits to the existing dnis */
|
||||
unsigned i = strlen(caller_data->dnis.digits);
|
||||
|
||||
ftdm_copy_string(&ftdm->dnis.digits[i], (const char*)cdPtyNmb->nmbDigits.val, cdPtyNmb->nmbDigits.len+1);
|
||||
ftdm_copy_string(&caller_data->dnis.digits[i], (const char*)cdPtyNmb->nmbDigits.val, cdPtyNmb->nmbDigits.len+1);
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb)
|
||||
ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb)
|
||||
{
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
if (redirNmb->eh.pres != PRSNT_NODEF) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (redirNmb->nmbPlanId.pres == PRSNT_NODEF) {
|
||||
ftdm->rdnis.plan = redirNmb->nmbPlanId.val;
|
||||
caller_data->rdnis.plan = redirNmb->nmbPlanId.val;
|
||||
}
|
||||
|
||||
if (redirNmb->typeNmb.pres == PRSNT_NODEF) {
|
||||
ftdm->rdnis.type = redirNmb->typeNmb.val;
|
||||
caller_data->rdnis.type = redirNmb->typeNmb.val;
|
||||
}
|
||||
|
||||
if (redirNmb->nmbDigits.pres == PRSNT_NODEF) {
|
||||
ftdm_copy_string(ftdm->rdnis.digits, (const char*)redirNmb->nmbDigits.val, redirNmb->nmbDigits.len+1);
|
||||
ftdm_copy_string(caller_data->rdnis.digits, (const char*)redirNmb->nmbDigits.val, redirNmb->nmbDigits.len+1);
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display)
|
||||
ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *display)
|
||||
{
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
if (display->eh.pres != PRSNT_NODEF) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -225,71 +240,209 @@ FT_DECLARE(ftdm_status_t) cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm,
|
|||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdm_copy_string(ftdm->cid_name, (const char*)display->dispInfo.val, display->dispInfo.len+1);
|
||||
ftdm_copy_string(caller_data->cid_name, (const char*)display->dispInfo.val, display->dispInfo.len+1);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm)
|
||||
ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr)
|
||||
{
|
||||
uint8_t len = strlen(ftdm->cid_num.digits);
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
if (usrUsr->eh.pres != PRSNT_NODEF) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (usrUsr->protocolDisc.val != PD_IA5) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (usrUsr->usrInfo.pres != PRSNT_NODEF) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdm_copy_string(caller_data->cid_name, (const char*)usrUsr->usrInfo.val, usrUsr->usrInfo.len+1);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
|
||||
{
|
||||
char subaddress[100];
|
||||
|
||||
if (cgPtySad->eh.pres != PRSNT_NODEF) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
memset(subaddress, 0, sizeof(subaddress));
|
||||
if(cgPtySad->sadInfo.len >= sizeof(subaddress)) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Calling Party Subaddress exceeds local size limit (len:%d max:%d)\n", cgPtySad->sadInfo.len, sizeof(subaddress));
|
||||
cgPtySad->sadInfo.len = sizeof(subaddress)-1;
|
||||
}
|
||||
|
||||
memcpy(subaddress, (char*)cgPtySad->sadInfo.val, cgPtySad->sadInfo.len);
|
||||
subaddress[cgPtySad->sadInfo.len] = '\0';
|
||||
ftdm_channel_add_var(ftdmchan, "isdn.calling_subaddr", subaddress);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr)
|
||||
{
|
||||
if (!facilityStr->eh.pres) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
return get_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, facilityStr->facilityStr.len);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
memcpy(&caller_data->raw_data[2], data, data_len);
|
||||
caller_data->raw_data_len = data_len+2;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd)
|
||||
{
|
||||
uint8_t val;
|
||||
if (!progInd->eh.pres) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (progInd->progDesc.pres) {
|
||||
switch (progInd->progDesc.val) {
|
||||
case IN_PD_NOTETEISDN:
|
||||
val = SNGISDN_PROGIND_DESCR_NETE_ISDN;
|
||||
break;
|
||||
case IN_PD_DSTNOTISDN:
|
||||
val = SNGISDN_PROGIND_DESCR_DEST_NISDN;
|
||||
break;
|
||||
case IN_PD_ORGNOTISDN:
|
||||
val = SNGISDN_PROGIND_DESCR_ORIG_NISDN;
|
||||
break;
|
||||
case IN_PD_CALLRET:
|
||||
val = SNGISDN_PROGIND_DESCR_RET_ISDN;
|
||||
break;
|
||||
case IN_PD_DELRESP:
|
||||
val = SNGISDN_PROGIND_DESCR_SERV_CHANGE;
|
||||
break;
|
||||
case IN_PD_IBAVAIL:
|
||||
val = SNGISDN_PROGIND_DESCR_IB_AVAIL;
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unknown Progress Indicator Description (%d)\n", progInd->progDesc.val);
|
||||
val = SNGISDN_PROGIND_DESCR_INVALID;
|
||||
break;
|
||||
}
|
||||
ftdm_channel_add_var(ftdmchan, "isdn.prog_ind.descr", ftdm_sngisdn_progind_descr2str(val));
|
||||
}
|
||||
|
||||
if (progInd->location.pres) {
|
||||
switch (progInd->location.val) {
|
||||
case IN_LOC_USER:
|
||||
val = SNGISDN_PROGIND_LOC_USER;
|
||||
break;
|
||||
case IN_LOC_PRIVNETLU:
|
||||
val = SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR;
|
||||
break;
|
||||
case IN_LOC_PUBNETLU:
|
||||
val = SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR;
|
||||
break;
|
||||
case IN_LOC_TRANNET:
|
||||
val = SNGISDN_PROGIND_LOC_TRANSIT_NET;
|
||||
break;
|
||||
case IN_LOC_PUBNETRU:
|
||||
val = SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR;
|
||||
break;
|
||||
case IN_LOC_PRIVNETRU:
|
||||
val = SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR;
|
||||
break;
|
||||
case IN_LOC_NETINTER:
|
||||
val = SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW;
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unknown Progress Indicator Location (%d)", progInd->location.val);
|
||||
val = SNGISDN_PROGIND_LOC_INVALID;
|
||||
break;
|
||||
}
|
||||
ftdm_channel_add_var(ftdmchan, "isdn.prog_ind.loc", ftdm_sngisdn_progind_loc2str(val));
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
|
||||
{
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
uint8_t len = strlen(caller_data->cid_num.digits);
|
||||
if (!len) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
cgPtyNmb->eh.pres = PRSNT_NODEF;
|
||||
|
||||
cgPtyNmb->screenInd.pres = PRSNT_NODEF;
|
||||
cgPtyNmb->screenInd.val = ftdm->screen;
|
||||
cgPtyNmb->screenInd.val = caller_data->screen;
|
||||
|
||||
cgPtyNmb->presInd0.pres = PRSNT_NODEF;
|
||||
cgPtyNmb->presInd0.val = ftdm->pres;
|
||||
|
||||
cgPtyNmb->presInd0.val = caller_data->pres;
|
||||
|
||||
cgPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
|
||||
cgPtyNmb->nmbPlanId.val = ftdm->cid_num.plan;
|
||||
cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan;
|
||||
|
||||
cgPtyNmb->typeNmb1.pres = PRSNT_NODEF;
|
||||
cgPtyNmb->typeNmb1.val = ftdm->cid_num.type;
|
||||
cgPtyNmb->typeNmb1.val = caller_data->cid_num.type;
|
||||
|
||||
cgPtyNmb->nmbDigits.pres = PRSNT_NODEF;
|
||||
cgPtyNmb->nmbDigits.len = len;
|
||||
|
||||
memcpy(cgPtyNmb->nmbDigits.val, ftdm->cid_num.digits, len);
|
||||
memcpy(cgPtyNmb->nmbDigits.val, caller_data->cid_num.digits, len);
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm)
|
||||
ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb)
|
||||
{
|
||||
uint8_t len = strlen(ftdm->dnis.digits);
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
uint8_t len = strlen(caller_data->dnis.digits);
|
||||
|
||||
if (!len) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
cdPtyNmb->eh.pres = PRSNT_NODEF;
|
||||
|
||||
cdPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
|
||||
if (ftdm->dnis.plan == FTDM_NPI_INVALID) {
|
||||
if (caller_data->dnis.plan == FTDM_NPI_INVALID) {
|
||||
cdPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
|
||||
} else {
|
||||
cdPtyNmb->nmbPlanId.val = ftdm->dnis.plan;
|
||||
cdPtyNmb->nmbPlanId.val = caller_data->dnis.plan;
|
||||
}
|
||||
|
||||
cdPtyNmb->typeNmb0.pres = PRSNT_NODEF;
|
||||
if (ftdm->dnis.type == FTDM_TON_INVALID) {
|
||||
if (caller_data->dnis.type == FTDM_TON_INVALID) {
|
||||
cdPtyNmb->typeNmb0.val = FTDM_TON_UNKNOWN;
|
||||
} else {
|
||||
cdPtyNmb->typeNmb0.val = ftdm->dnis.type;
|
||||
cdPtyNmb->typeNmb0.val = caller_data->dnis.type;
|
||||
}
|
||||
|
||||
cdPtyNmb->nmbDigits.pres = PRSNT_NODEF;
|
||||
cdPtyNmb->nmbDigits.len = len;
|
||||
|
||||
|
||||
memcpy(cdPtyNmb->nmbDigits.val, ftdm->dnis.digits, len);
|
||||
memcpy(cdPtyNmb->nmbDigits.val, caller_data->dnis.digits, len);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm)
|
||||
ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb)
|
||||
{
|
||||
uint8_t len = strlen(ftdm->rdnis.digits);
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
uint8_t len = strlen(caller_data->rdnis.digits);
|
||||
if (!len) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
@ -297,36 +450,36 @@ FT_DECLARE(ftdm_status_t) cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_calle
|
|||
redirNmb->eh.pres = PRSNT_NODEF;
|
||||
|
||||
redirNmb->nmbPlanId.pres = PRSNT_NODEF;
|
||||
if (ftdm->rdnis.plan == FTDM_NPI_INVALID) {
|
||||
if (caller_data->rdnis.plan == FTDM_NPI_INVALID) {
|
||||
redirNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
|
||||
} else {
|
||||
redirNmb->nmbPlanId.val = ftdm->rdnis.plan;
|
||||
redirNmb->nmbPlanId.val = caller_data->rdnis.plan;
|
||||
}
|
||||
|
||||
redirNmb->typeNmb.pres = PRSNT_NODEF;
|
||||
if (ftdm->rdnis.type == FTDM_TON_INVALID) {
|
||||
if (caller_data->rdnis.type == FTDM_TON_INVALID) {
|
||||
redirNmb->typeNmb.val = FTDM_TON_UNKNOWN;
|
||||
} else {
|
||||
redirNmb->typeNmb.val = ftdm->rdnis.type;
|
||||
redirNmb->typeNmb.val = caller_data->rdnis.type;
|
||||
}
|
||||
|
||||
redirNmb->nmbDigits.pres = PRSNT_NODEF;
|
||||
redirNmb->nmbDigits.len = len;
|
||||
|
||||
memcpy(redirNmb->nmbDigits.val, ftdm->rdnis.digits, len);
|
||||
memcpy(redirNmb->nmbDigits.val, caller_data->rdnis.digits, len);
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
FT_DECLARE(ftdm_status_t) cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan)
|
||||
ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt)
|
||||
{
|
||||
uint8_t len;
|
||||
ftdm_caller_data_t *ftdm = &ftdmchan->caller_data;
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
/* sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; */
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
len = strlen(ftdm->cid_name);
|
||||
len = strlen(caller_data->cid_name);
|
||||
if (!len) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
@ -341,7 +494,7 @@ FT_DECLARE(ftdm_status_t) cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_chan
|
|||
conEvnt->usrUsr.usrInfo.len = len;
|
||||
/* in sangoma_brid we used to send usr-usr info as <cid_name>!<calling_number>,
|
||||
change to previous style if current one does not work */
|
||||
memcpy(conEvnt->usrUsr.usrInfo.val, ftdm->cid_name, len);
|
||||
memcpy(conEvnt->usrUsr.usrInfo.val, caller_data->cid_name, len);
|
||||
} else {
|
||||
switch (signal_data->switchtype) {
|
||||
case SNGISDN_SWITCH_NI2:
|
||||
|
@ -359,7 +512,7 @@ FT_DECLARE(ftdm_status_t) cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_chan
|
|||
conEvnt->display.eh.pres = PRSNT_NODEF;
|
||||
conEvnt->display.dispInfo.pres = PRSNT_NODEF;
|
||||
conEvnt->display.dispInfo.len = len;
|
||||
memcpy(conEvnt->display.dispInfo.val, ftdm->cid_name, len);
|
||||
memcpy(conEvnt->display.dispInfo.val, caller_data->cid_name, len);
|
||||
break;
|
||||
case SNGISDN_SWITCH_QSIG:
|
||||
/* It seems like QSIG does not support Caller ID Name */
|
||||
|
@ -372,6 +525,139 @@ FT_DECLARE(ftdm_status_t) cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_chan
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
|
||||
{
|
||||
const char* clg_subaddr = NULL;
|
||||
clg_subaddr = ftdm_channel_get_var(ftdmchan, "isdn.calling_subaddr");
|
||||
if ((clg_subaddr != NULL) && (*clg_subaddr)) {
|
||||
unsigned len = strlen (clg_subaddr);
|
||||
cgPtySad->eh.pres = PRSNT_NODEF;
|
||||
cgPtySad->typeSad.pres = 1;
|
||||
cgPtySad->typeSad.val = 0; /* NSAP */
|
||||
cgPtySad->oddEvenInd.pres = 1;
|
||||
cgPtySad->oddEvenInd.val = 0;
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Calling Party Subaddress:%s\n", clg_subaddr);
|
||||
cgPtySad->sadInfo.pres = 1;
|
||||
cgPtySad->sadInfo.len = len;
|
||||
memcpy(cgPtySad->sadInfo.val, clg_subaddr, len);
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr)
|
||||
{
|
||||
ftdm_status_t status;
|
||||
status = set_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, (ftdm_size_t*)&facilityStr->facilityStr.len);
|
||||
if (status == FTDM_SUCCESS) {
|
||||
facilityStr->eh.pres = PRSNT_NODEF;
|
||||
facilityStr->facilityStr.pres = PRSNT_NODEF;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
ftdm_status_t set_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 (caller_data->raw_data_len > 0 && caller_data->raw_data[0] == SNGISDN_Q931_FACILITY_IE_ID) {
|
||||
|
||||
*data_len = caller_data->raw_data[1];
|
||||
memcpy(data, &caller_data->raw_data[2], *data_len);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind)
|
||||
{
|
||||
const char *str = NULL;
|
||||
int descr = prog_ind.descr;
|
||||
int loc = prog_ind.loc;
|
||||
|
||||
str = ftdm_channel_get_var(ftdmchan, "isdn.prog_ind.descr");
|
||||
if (str && *str) {
|
||||
/* User wants to override progress indicator */
|
||||
descr = ftdm_str2ftdm_sngisdn_progind_descr(str);
|
||||
}
|
||||
|
||||
if (descr == SNGISDN_PROGIND_DESCR_INVALID) {
|
||||
/* User does not want to send progress indicator */
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
str = ftdm_channel_get_var(ftdmchan, "isdn.prog_ind.loc");
|
||||
if (str && *str) {
|
||||
loc = ftdm_str2ftdm_sngisdn_progind_loc(str);
|
||||
}
|
||||
if (loc == SNGISDN_PROGIND_LOC_INVALID) {
|
||||
loc = SNGISDN_PROGIND_LOC_USER;
|
||||
}
|
||||
|
||||
progInd->eh.pres = PRSNT_NODEF;
|
||||
progInd->codeStand0.pres = PRSNT_NODEF;
|
||||
progInd->codeStand0.val = IN_CSTD_CCITT;
|
||||
|
||||
progInd->progDesc.pres = PRSNT_NODEF;
|
||||
switch(descr) {
|
||||
case SNGISDN_PROGIND_DESCR_NETE_ISDN:
|
||||
progInd->progDesc.val = IN_PD_NOTETEISDN;
|
||||
break;
|
||||
case SNGISDN_PROGIND_DESCR_DEST_NISDN:
|
||||
progInd->progDesc.val = IN_PD_DSTNOTISDN;
|
||||
break;
|
||||
case SNGISDN_PROGIND_DESCR_ORIG_NISDN:
|
||||
progInd->progDesc.val = IN_PD_ORGNOTISDN;
|
||||
break;
|
||||
case SNGISDN_PROGIND_DESCR_RET_ISDN:
|
||||
progInd->progDesc.val = IN_PD_CALLRET;
|
||||
break;
|
||||
case SNGISDN_PROGIND_DESCR_SERV_CHANGE:
|
||||
/* Trillium defines do not match ITU-T Q931 Progress descriptions,
|
||||
indicate a delayed response for now */
|
||||
progInd->progDesc.val = IN_PD_DELRESP;
|
||||
break;
|
||||
case SNGISDN_PROGIND_DESCR_IB_AVAIL:
|
||||
progInd->progDesc.val = IN_PD_IBAVAIL;
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid prog_ind description:%d\n", descr);
|
||||
progInd->progDesc.val = IN_PD_NOTETEISDN;
|
||||
break;
|
||||
}
|
||||
|
||||
progInd->location.pres = PRSNT_NODEF;
|
||||
switch (loc) {
|
||||
case SNGISDN_PROGIND_LOC_USER:
|
||||
progInd->location.val = IN_LOC_USER;
|
||||
break;
|
||||
case SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR:
|
||||
progInd->location.val = IN_LOC_PRIVNETLU;
|
||||
break;
|
||||
case SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR:
|
||||
progInd->location.val = IN_LOC_PUBNETLU;
|
||||
break;
|
||||
case SNGISDN_PROGIND_LOC_TRANSIT_NET:
|
||||
progInd->location.val = IN_LOC_TRANNET;
|
||||
break;
|
||||
case SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR:
|
||||
progInd->location.val = IN_LOC_PUBNETRU;
|
||||
break;
|
||||
case SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR:
|
||||
progInd->location.val = IN_LOC_PRIVNETRU;
|
||||
break;
|
||||
case SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW:
|
||||
progInd->location.val = IN_LOC_NETINTER;
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid prog_ind location:%d\n", loc);
|
||||
progInd->location.val = IN_PD_NOTETEISDN;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void sngisdn_t3_timeout(void* p_sngisdn_info)
|
||||
{
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
|
||||
|
@ -394,6 +680,17 @@ void sngisdn_t3_timeout(void* p_sngisdn_info)
|
|||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
}
|
||||
|
||||
void sngisdn_delayed_setup(void* p_sngisdn_info)
|
||||
{
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
sngisdn_snd_setup(ftdmchan);
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_delayed_release(void* p_sngisdn_info)
|
||||
{
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
|
||||
|
@ -517,13 +814,12 @@ uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability)
|
|||
switch(bearer_capability) {
|
||||
case FTDM_BEARER_CAP_SPEECH:
|
||||
return IN_ITC_SPEECH;
|
||||
|
||||
case FTDM_BEARER_CAP_64K_UNRESTRICTED:
|
||||
return IN_ITC_UNRDIG;
|
||||
|
||||
case FTDM_BEARER_CAP_3_1KHZ_AUDIO:
|
||||
return IN_ITC_A31KHZ;
|
||||
|
||||
case FTDM_BEARER_CAP_INVALID:
|
||||
return IN_ITC_SPEECH;
|
||||
/* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
|
||||
}
|
||||
return FTDM_BEARER_CAP_SPEECH;
|
||||
|
@ -534,13 +830,12 @@ uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_pr
|
|||
switch(layer1_prot) {
|
||||
case FTDM_USER_LAYER1_PROT_V110:
|
||||
return IN_UIL1_CCITTV110;
|
||||
|
||||
case FTDM_USER_LAYER1_PROT_ULAW:
|
||||
return IN_UIL1_G711ULAW;
|
||||
|
||||
case FTDM_USER_LAYER1_PROT_ALAW:
|
||||
return IN_UIL1_G711ALAW;
|
||||
|
||||
case FTDM_USER_LAYER1_PROT_INVALID:
|
||||
return IN_UIL1_G711ULAW;
|
||||
/* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
|
||||
}
|
||||
return IN_UIL1_G711ULAW;
|
||||
|
|
|
@ -613,6 +613,21 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
|
|||
return 0;
|
||||
break;
|
||||
case PROT_Q931_IE_CALLED_PARTY_SUBADDRESS:
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t currentOct, j=0;
|
||||
char calling_subaddr_string[82];
|
||||
memset(calling_subaddr_string, 0, sizeof(calling_subaddr_string));
|
||||
type = get_bits(OCTET(3),5,7);
|
||||
currentOct = 3;
|
||||
while(currentOct++ <= len+1) {
|
||||
calling_subaddr_string[j++]=ia5[get_bits(OCTET(currentOct),1,4)][get_bits(OCTET(currentOct),5,8)];
|
||||
}
|
||||
calling_subaddr_string[j++]='\0';
|
||||
*str_len += sprintf(&str[*str_len], "%s (l:%d) type:%s(%d) \n",
|
||||
calling_subaddr_string, (j-1), get_code_2_str(type, dcodQ931TypeOfSubaddressTable), type);
|
||||
}
|
||||
break;
|
||||
case PROT_Q931_IE_REDIRECTION_NUMBER:
|
||||
case PROT_Q931_IE_NOTIFICATION_IND:
|
||||
case PROT_Q931_IE_DATE_TIME:
|
||||
|
|
|
@ -544,5 +544,11 @@ struct code2str dcodQ931GenDigitsTypeTable[] = {
|
|||
{-1, "Invalid"},
|
||||
};
|
||||
|
||||
struct code2str dcodQ931TypeOfSubaddressTable[] = {
|
||||
{ 0x00, "NSAP"},
|
||||
{ 0x02, "User-specified"},
|
||||
{ -1, "Invalid"},
|
||||
};
|
||||
|
||||
#endif /* __FTMOD_SANGOMA_ISDN_TRACE_H__ */
|
||||
|
||||
|
|
|
@ -115,12 +115,16 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event);
|
|||
static __inline__ int tdmv_api_wait_socket(ftdm_channel_t *ftdmchan, int timeout, int *flags)
|
||||
{
|
||||
|
||||
#ifdef LIBSANGOMA_VERSION
|
||||
#ifdef LIBSANGOMA_VERSION
|
||||
int err;
|
||||
uint32_t inflags = *flags;
|
||||
uint32_t outflags = 0;
|
||||
sangoma_wait_obj_t *sangoma_wait_obj = ftdmchan->io_data;
|
||||
|
||||
if (timeout == -1) {
|
||||
timeout = SANGOMA_WAIT_INFINITE;
|
||||
}
|
||||
|
||||
err = sangoma_waitfor(sangoma_wait_obj, inflags, &outflags, timeout);
|
||||
*flags = 0;
|
||||
if (err == SANG_STATUS_SUCCESS) {
|
||||
|
@ -169,7 +173,7 @@ static __inline__ sng_fd_t tdmv_api_open_span_chan(int span, int chan)
|
|||
static __inline__ sng_fd_t __tdmv_api_open_span_chan(int span, int chan)
|
||||
{
|
||||
return __sangoma_open_tdmapi_span_chan(span, chan);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static ftdm_io_interface_t wanpipe_interface;
|
||||
|
@ -333,8 +337,8 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start
|
|||
ftdm_log(FTDM_LOG_ERROR, "Failed to enable RBS/CAS events in device %d:%d fd:%d\n", chan->span_id, chan->chan_id, sockfd);
|
||||
continue;
|
||||
}
|
||||
/* probably done by the driver but lets write defensive code this time */
|
||||
sangoma_flush_bufs(chan->sockfd, &tdm_api);
|
||||
sangoma_flush_event_bufs(chan->sockfd, &tdm_api);
|
||||
#else
|
||||
/*
|
||||
* With wanpipe 3.4.4.2 I get failure even though the events are enabled, /var/log/messages said:
|
||||
|
@ -513,10 +517,10 @@ static FIO_OPEN_FUNCTION(wanpipe_open)
|
|||
wanpipe_tdm_api_t tdm_api;
|
||||
|
||||
memset(&tdm_api,0,sizeof(tdm_api));
|
||||
|
||||
sangoma_tdm_flush_bufs(ftdmchan->sockfd, &tdm_api);
|
||||
#ifdef LIBSANGOMA_VERSION
|
||||
sangoma_flush_event_bufs(ftdmchan->sockfd, &tdm_api);
|
||||
#endif
|
||||
sangoma_flush_stats(ftdmchan->sockfd, &tdm_api);
|
||||
memset(&ftdmchan->iostats, 0, sizeof(ftdmchan->iostats));
|
||||
|
||||
if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921 || ftdmchan->type == FTDM_CHAN_TYPE_DQ931) {
|
||||
ftdmchan->native_codec = ftdmchan->effective_codec = FTDM_CODEC_NONE;
|
||||
|
@ -745,6 +749,29 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_COMMAND_FLUSH_BUFFERS:
|
||||
{
|
||||
err = sangoma_flush_bufs(ftdmchan->sockfd, &tdm_api);
|
||||
}
|
||||
break;
|
||||
case FTDM_COMMAND_FLUSH_IOSTATS:
|
||||
{
|
||||
err = sangoma_flush_stats(ftdmchan->sockfd, &tdm_api);
|
||||
memset(&ftdmchan->iostats, 0, sizeof(ftdmchan->iostats));
|
||||
}
|
||||
break;
|
||||
case FTDM_COMMAND_SET_RX_QUEUE_SIZE:
|
||||
{
|
||||
uint32_t queue_size = FTDM_COMMAND_OBJ_INT;
|
||||
err = sangoma_set_rx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size);
|
||||
}
|
||||
break;
|
||||
case FTDM_COMMAND_SET_TX_QUEUE_SIZE:
|
||||
{
|
||||
uint32_t queue_size = FTDM_COMMAND_OBJ_INT;
|
||||
err = sangoma_set_tx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
@ -758,6 +785,106 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static void wanpipe_write_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_tx_hdr_t *tx_stats)
|
||||
{
|
||||
ftdmchan->iostats.tx.errors = tx_stats->wp_api_tx_hdr_errors;
|
||||
ftdmchan->iostats.tx.queue_size = tx_stats->wp_api_tx_hdr_max_queue_length;
|
||||
ftdmchan->iostats.tx.queue_len = tx_stats->wp_api_tx_hdr_number_of_frames_in_queue;
|
||||
|
||||
/* 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);
|
||||
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",
|
||||
ftdmchan->iostats.tx.queue_len, ftdmchan->iostats.tx.queue_size);
|
||||
ftdm_clear_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
|
||||
}
|
||||
|
||||
if (ftdmchan->iostats.tx.idle_packets < tx_stats->wp_api_tx_hdr_number_of_frames_in_queue) {
|
||||
ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets;
|
||||
/* HDLC channels do not always transmit, so its ok for drivers to fill with idle */
|
||||
if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx idle: %d\n", ftdmchan->iostats.tx.idle_packets);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ftdmchan->iostats.tx.packets) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "First packet write stats: Tx queue len: %d, Tx queue size: %d, Tx idle: %d\n",
|
||||
ftdmchan->iostats.tx.queue_len,
|
||||
ftdmchan->iostats.tx.queue_size,
|
||||
ftdmchan->iostats.tx.idle_packets);
|
||||
}
|
||||
|
||||
ftdmchan->iostats.tx.packets++;
|
||||
}
|
||||
|
||||
static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx_stats)
|
||||
{
|
||||
ftdmchan->iostats.rx.errors = rx_stats->wp_api_rx_hdr_errors;
|
||||
ftdmchan->iostats.rx.queue_size = rx_stats->wp_api_rx_hdr_max_queue_length;
|
||||
ftdmchan->iostats.rx.queue_len = rx_stats->wp_api_rx_hdr_number_of_frames_in_queue;
|
||||
|
||||
if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_ABORT_ERROR_BIT))) {
|
||||
ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_ABORT);
|
||||
} else {
|
||||
ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_DMA_ERROR_BIT))) {
|
||||
ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_DMA);
|
||||
} else {
|
||||
ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_DMA);
|
||||
}
|
||||
|
||||
if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_FIFO_ERROR_BIT))) {
|
||||
ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FIFO);
|
||||
} else {
|
||||
ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FIFO);
|
||||
}
|
||||
|
||||
if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_CRC_ERROR_BIT))) {
|
||||
ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_CRC);
|
||||
} else {
|
||||
ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_CRC);
|
||||
}
|
||||
|
||||
if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_FRAME_ERROR_BIT))) {
|
||||
ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FRAME);
|
||||
} else {
|
||||
ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FRAME);
|
||||
}
|
||||
|
||||
if (ftdmchan->iostats.rx.queue_len >= (0.8 * ftdmchan->iostats.rx.queue_size)) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Rx Queue length exceeded 80% threshold (%d/%d)\n",
|
||||
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);
|
||||
}
|
||||
|
||||
if (ftdmchan->iostats.rx.queue_len >= ftdmchan->iostats.rx.queue_size) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Rx Queue Full (%d/%d)\n",
|
||||
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
|
||||
ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
|
||||
} else if (ftdm_test_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL)){
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Rx Queue no longer full (%d/%d)\n",
|
||||
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
|
||||
ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
|
||||
}
|
||||
|
||||
if (!ftdmchan->iostats.rx.packets) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "First packet read stats: Rx queue len: %d, Rx queue size: %d\n",
|
||||
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
|
||||
}
|
||||
|
||||
ftdmchan->iostats.rx.packets++;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reads data from a Wanpipe channel
|
||||
* \param ftdmchan Channel to read from
|
||||
|
@ -786,9 +913,11 @@ static FIO_READ_FUNCTION(wanpipe_read)
|
|||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno));
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read from sangoma device: %s (%d)\n", strerror(errno), rx_len);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS)) {
|
||||
wanpipe_read_stats(ftdmchan, &hdrframe);
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -814,6 +943,9 @@ static FIO_WRITE_FUNCTION(wanpipe_write)
|
|||
/* should we be checking if bsent == *datalen here? */
|
||||
if (bsent > 0) {
|
||||
*datalen = bsent;
|
||||
if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS)) {
|
||||
wanpipe_write_stats(ftdmchan, &hdrframe);
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,196 +0,0 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="ftmod_wanpipe"
|
||||
ProjectGUID="{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}"
|
||||
RootNamespace="ftmod_wanpipe"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../src/include;../../../src/isdn/include;../../../wanpipe/include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="freetdm.lib libsangoma.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""$(OutDir)";../../../wanpipe/api/lib/x86"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
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|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../src/include;../../../src/isdn/include;../../../wanpipe/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="freetdm.lib libsangoma.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=""$(OutDir)";../../../wanpipe/api/lib/x86"
|
||||
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>
|
||||
</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_wanpipe.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -1,351 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* wanpipe_tdm_api_iface.h
|
||||
*
|
||||
* WANPIPE(tm) AFT TE1 Hardware Support
|
||||
*
|
||||
* Authors: Nenad Corbic <ncorbic@sangoma.com>
|
||||
*
|
||||
* Copyright (c) 2007 - 08, Sangoma Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
* ============================================================================
|
||||
* Oct 04, 2005 Nenad Corbic Initial version.
|
||||
*
|
||||
* Jul 25, 2006 David Rokhvarg <davidr@sangoma.com> Ported to Windows.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __WANPIPE_TDM_API_IFACE_H_
|
||||
#define __WANPIPE_TDM_API_IFACE_H_
|
||||
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
typedef HANDLE sng_fd_t;
|
||||
#else
|
||||
typedef int sng_fd_t;
|
||||
#endif
|
||||
|
||||
/* Indicate to library that new features exist */
|
||||
#define WP_TDM_FEATURE_DTMF_EVENTS 1
|
||||
#define WP_TDM_FEATURE_FE_ALARM 1
|
||||
#define WP_TDM_FEATURE_EVENTS 1
|
||||
#define WP_TDM_FEATURE_LINK_STATUS 1
|
||||
|
||||
enum wanpipe_tdm_api_cmds {
|
||||
|
||||
SIOC_WP_TDM_GET_USR_MTU_MRU, /* 0x00 */
|
||||
|
||||
SIOC_WP_TDM_SET_USR_PERIOD, /* 0x01 */
|
||||
SIOC_WP_TDM_GET_USR_PERIOD, /* 0x02 */
|
||||
|
||||
SIOC_WP_TDM_SET_HW_MTU_MRU, /* 0x03 */
|
||||
SIOC_WP_TDM_GET_HW_MTU_MRU, /* 0x04 */
|
||||
|
||||
SIOC_WP_TDM_SET_CODEC, /* 0x05 */
|
||||
SIOC_WP_TDM_GET_CODEC, /* 0x06 */
|
||||
|
||||
SIOC_WP_TDM_SET_POWER_LEVEL, /* 0x07 */
|
||||
SIOC_WP_TDM_GET_POWER_LEVEL, /* 0x08 */
|
||||
|
||||
SIOC_WP_TDM_TOGGLE_RX, /* 0x09 */
|
||||
SIOC_WP_TDM_TOGGLE_TX, /* 0x0A */
|
||||
|
||||
SIOC_WP_TDM_GET_HW_CODING, /* 0x0B */
|
||||
SIOC_WP_TDM_SET_HW_CODING, /* 0x0C */
|
||||
|
||||
SIOC_WP_TDM_GET_FULL_CFG, /* 0x0D */
|
||||
|
||||
SIOC_WP_TDM_SET_EC_TAP, /* 0x0E */
|
||||
SIOC_WP_TDM_GET_EC_TAP, /* 0x0F */
|
||||
|
||||
SIOC_WP_TDM_ENABLE_RBS_EVENTS, /* 0x10 */
|
||||
SIOC_WP_TDM_DISABLE_RBS_EVENTS, /* 0x11 */
|
||||
SIOC_WP_TDM_WRITE_RBS_BITS, /* 0x12 */
|
||||
|
||||
SIOC_WP_TDM_GET_STATS, /* 0x13 */
|
||||
SIOC_WP_TDM_FLUSH_BUFFERS, /* 0x14 */
|
||||
|
||||
SIOC_WP_TDM_READ_EVENT, /* 0x15 */
|
||||
|
||||
SIOC_WP_TDM_SET_EVENT, /* 0x16 */
|
||||
|
||||
SIOC_WP_TDM_SET_RX_GAINS, /* 0x17 */
|
||||
SIOC_WP_TDM_SET_TX_GAINS, /* 0x18 */
|
||||
SIOC_WP_TDM_CLEAR_RX_GAINS, /* 0x19 */
|
||||
SIOC_WP_TDM_CLEAR_TX_GAINS, /* 0x1A */
|
||||
|
||||
SIOC_WP_TDM_GET_FE_ALARMS, /* 0x1B */
|
||||
|
||||
SIOC_WP_TDM_ENABLE_HWEC, /* 0x1C */
|
||||
SIOC_WP_TDM_DISABLE_HWEC, /* 0x1D */
|
||||
|
||||
SIOC_WP_TDM_SET_FE_STATUS, /* 0x1E */
|
||||
SIOC_WP_TDM_GET_FE_STATUS, /* 0x1F */
|
||||
|
||||
SIOC_WP_TDM_GET_HW_DTMF, /* 0x20 */
|
||||
|
||||
SIOC_WP_TDM_NOTSUPP /* */
|
||||
|
||||
};
|
||||
|
||||
#define SIOC_WP_TDM_GET_LINK_STATUS SIOC_WP_TDM_GET_FE_STATUS
|
||||
|
||||
enum wanpipe_tdm_api_events {
|
||||
WP_TDMAPI_EVENT_NONE,
|
||||
WP_TDMAPI_EVENT_RBS,
|
||||
WP_TDMAPI_EVENT_ALARM,
|
||||
WP_TDMAPI_EVENT_DTMF,
|
||||
WP_TDMAPI_EVENT_RM_DTMF,
|
||||
WP_TDMAPI_EVENT_RXHOOK,
|
||||
WP_TDMAPI_EVENT_RING,
|
||||
WP_TDMAPI_EVENT_RING_DETECT,
|
||||
WP_TDMAPI_EVENT_RING_TRIP_DETECT,
|
||||
WP_TDMAPI_EVENT_TONE,
|
||||
WP_TDMAPI_EVENT_TXSIG_KEWL,
|
||||
WP_TDMAPI_EVENT_TXSIG_START,
|
||||
WP_TDMAPI_EVENT_TXSIG_OFFHOOK,
|
||||
WP_TDMAPI_EVENT_TXSIG_ONHOOK,
|
||||
WP_TDMAPI_EVENT_ONHOOKTRANSFER,
|
||||
WP_TDMAPI_EVENT_SETPOLARITY,
|
||||
WP_TDMAPI_EVENT_BRI_CHAN_LOOPBACK,
|
||||
WP_TDMAPI_EVENT_LINK_STATUS
|
||||
};
|
||||
|
||||
#define WP_TDMAPI_EVENT_FE_ALARM WP_TDMAPI_EVENT_ALARM
|
||||
|
||||
|
||||
#define WP_TDMAPI_EVENT_ENABLE 0x01
|
||||
#define WP_TDMAPI_EVENT_DISABLE 0x02
|
||||
#define WP_TDMAPI_EVENT_MODE_DECODE(mode) \
|
||||
((mode) == WP_TDMAPI_EVENT_ENABLE) ? "Enable" : \
|
||||
((mode) == WP_TDMAPI_EVENT_DISABLE) ? "Disable" : \
|
||||
"(Unknown mode)"
|
||||
|
||||
#define WPTDM_A_BIT WAN_RBS_SIG_A
|
||||
#define WPTDM_B_BIT WAN_RBS_SIG_B
|
||||
#define WPTDM_C_BIT WAN_RBS_SIG_C
|
||||
#define WPTDM_D_BIT WAN_RBS_SIG_D
|
||||
|
||||
#define WP_TDMAPI_EVENT_RXHOOK_OFF 0x01
|
||||
#define WP_TDMAPI_EVENT_RXHOOK_ON 0x02
|
||||
#define WP_TDMAPI_EVENT_RXHOOK_DECODE(state) \
|
||||
((state) == WP_TDMAPI_EVENT_RXHOOK_OFF) ? "Off-hook" : \
|
||||
((state) == WP_TDMAPI_EVENT_RXHOOK_ON) ? "On-hook" : \
|
||||
"(Unknown state)"
|
||||
|
||||
#define WP_TDMAPI_EVENT_RING_PRESENT 0x01
|
||||
#define WP_TDMAPI_EVENT_RING_STOP 0x02
|
||||
#define WP_TDMAPI_EVENT_RING_DECODE(state) \
|
||||
((state) == WP_TDMAPI_EVENT_RING_PRESENT) ? "Ring Present" : \
|
||||
((state) == WP_TDMAPI_EVENT_RING_STOP) ? "Ring Stop" : \
|
||||
"(Unknown state)"
|
||||
|
||||
#define WP_TDMAPI_EVENT_RING_TRIP_PRESENT 0x01
|
||||
#define WP_TDMAPI_EVENT_RING_TRIP_STOP 0x02
|
||||
#define WP_TDMAPI_EVENT_RING_TRIP_DECODE(state) \
|
||||
((state) == WP_TDMAPI_EVENT_RING_TRIP_PRESENT) ? "Ring Present" : \
|
||||
((state) == WP_TDMAPI_EVENT_RING_TRIP_STOP) ? "Ring Stop" : \
|
||||
"(Unknown state)"
|
||||
/*Link Status */
|
||||
#define WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED 0x01
|
||||
#define WP_TDMAPI_EVENT_LINK_STATUS_DISCONNECTED 0x02
|
||||
#define WP_TDMAPI_EVENT_LINK_STATUS_DECODE(status) \
|
||||
((status) == WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED) ? "Connected" : \
|
||||
((status) == WP_TDMAPI_EVENT_LINK_STATUS_DISCONNECTED) ? "Disconnected" : \
|
||||
"Unknown"
|
||||
#define WP_TDMAPI_EVENT_TONE_DIAL 0x01
|
||||
#define WP_TDMAPI_EVENT_TONE_BUSY 0x02
|
||||
#define WP_TDMAPI_EVENT_TONE_RING 0x03
|
||||
#define WP_TDMAPI_EVENT_TONE_CONGESTION 0x04
|
||||
|
||||
/* BRI channels list */
|
||||
#define WAN_BRI_BCHAN1 0x01
|
||||
#define WAN_BRI_BCHAN2 0x02
|
||||
#define WAN_BRI_DCHAN 0x03
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
u_int8_t type;
|
||||
u_int8_t mode;
|
||||
u_int32_t time_stamp;
|
||||
u_int8_t channel;
|
||||
u_int32_t chan_map;
|
||||
u_int8_t span;
|
||||
union {
|
||||
struct {
|
||||
u_int8_t alarm;
|
||||
} te1_alarm;
|
||||
struct {
|
||||
u_int8_t rbs_bits;
|
||||
} te1_rbs;
|
||||
struct {
|
||||
u_int8_t state;
|
||||
u_int8_t sig;
|
||||
} rm_hook;
|
||||
struct {
|
||||
u_int8_t state;
|
||||
} rm_ring;
|
||||
struct {
|
||||
u_int8_t type;
|
||||
} rm_tone;
|
||||
struct {
|
||||
u_int8_t digit; /* DTMF: digit */
|
||||
u_int8_t port; /* DTMF: SOUT/ROUT */
|
||||
u_int8_t type; /* DTMF: PRESET/STOP */
|
||||
} dtmf;
|
||||
struct {
|
||||
u_int16_t polarity;
|
||||
u_int16_t ohttimer;
|
||||
} rm_common;
|
||||
struct{
|
||||
u_int16_t status;
|
||||
} linkstatus;
|
||||
} wp_tdm_api_event_u;
|
||||
#define wp_tdm_api_event_type type
|
||||
#define wp_tdm_api_event_mode mode
|
||||
#define wp_tdm_api_event_alarm wp_tdm_api_event_u.te1_alarm.alarm
|
||||
#define wp_tdm_api_event_alarm wp_tdm_api_event_u.te1_alarm.alarm
|
||||
#define wp_tdm_api_event_rbs_bits wp_tdm_api_event_u.te1_rbs.rbs_bits
|
||||
#define wp_tdm_api_event_hook_state wp_tdm_api_event_u.rm_hook.state
|
||||
#define wp_tdm_api_event_hook_sig wp_tdm_api_event_u.rm_hook.sig
|
||||
#define wp_tdm_api_event_ring_state wp_tdm_api_event_u.rm_ring.state
|
||||
#define wp_tdm_api_event_tone_type wp_tdm_api_event_u.rm_tone.type
|
||||
#define wp_tdm_api_event_dtmf_digit wp_tdm_api_event_u.dtmf.digit
|
||||
#define wp_tdm_api_event_dtmf_type wp_tdm_api_event_u.dtmf.type
|
||||
#define wp_tdm_api_event_dtmf_port wp_tdm_api_event_u.dtmf.port
|
||||
#define wp_tdm_api_event_ohttimer wp_tdm_api_event_u.rm_common.ohttimer
|
||||
#define wp_tdm_api_event_polarity wp_tdm_api_event_u.rm_common.polarity
|
||||
#define wp_tdm_api_event_link_status wp_tdm_api_event_u.linkstatus.status
|
||||
} wp_tdm_api_event_t;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
unsigned char reserved[16];
|
||||
}wp_rx_hdr_u;
|
||||
} wp_tdm_api_rx_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
wp_tdm_api_rx_hdr_t hdr;
|
||||
unsigned char data[1];
|
||||
} wp_tdm_api_rx_element_t;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
unsigned char _rbs_rx_bits;
|
||||
unsigned int _time_stamp;
|
||||
}wp_tx;
|
||||
unsigned char reserved[16];
|
||||
}wp_tx_hdr_u;
|
||||
#define wp_api_time_stamp wp_tx_hdr_u.wp_tx._time_stamp
|
||||
} wp_tdm_api_tx_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
wp_tdm_api_tx_hdr_t hdr;
|
||||
unsigned char data[1];
|
||||
} wp_tdm_api_tx_element_t;
|
||||
|
||||
|
||||
|
||||
typedef struct wp_tdm_chan_stats
|
||||
{
|
||||
unsigned int rx_packets; /* total packets received */
|
||||
unsigned int tx_packets; /* total packets transmitted */
|
||||
unsigned int rx_bytes; /* total bytes received */
|
||||
unsigned int tx_bytes; /* total bytes transmitted */
|
||||
unsigned int rx_errors; /* bad packets received */
|
||||
unsigned int tx_errors; /* packet transmit problems */
|
||||
unsigned int rx_dropped; /* no space in linux buffers */
|
||||
unsigned int tx_dropped; /* no space available in linux */
|
||||
unsigned int multicast; /* multicast packets received */
|
||||
#if !defined(__WINDOWS__)
|
||||
unsigned int collisions;
|
||||
#endif
|
||||
/* detailed rx_errors: */
|
||||
unsigned int rx_length_errors;
|
||||
unsigned int rx_over_errors; /* receiver ring buff overflow */
|
||||
unsigned int rx_crc_errors; /* recved pkt with crc error */
|
||||
unsigned int rx_frame_errors; /* recv'd frame alignment error */
|
||||
#if !defined(__WINDOWS__)
|
||||
unsigned int rx_fifo_errors; /* recv'r fifo overrun */
|
||||
#endif
|
||||
unsigned int rx_missed_errors; /* receiver missed packet */
|
||||
|
||||
/* detailed tx_errors */
|
||||
#if !defined(__WINDOWS__)
|
||||
unsigned int tx_aborted_errors;
|
||||
unsigned int tx_carrier_errors;
|
||||
#endif
|
||||
unsigned int tx_fifo_errors;
|
||||
unsigned int tx_heartbeat_errors;
|
||||
unsigned int tx_window_errors;
|
||||
|
||||
}wp_tdm_chan_stats_t;
|
||||
|
||||
|
||||
|
||||
typedef struct wanpipe_tdm_api_cmd{
|
||||
unsigned int cmd;
|
||||
unsigned int hw_tdm_coding; /* Set/Get HW TDM coding: uLaw muLaw */
|
||||
unsigned int hw_mtu_mru; /* Set/Get HW TDM MTU/MRU */
|
||||
unsigned int usr_period; /* Set/Get User Period in ms */
|
||||
unsigned int tdm_codec; /* Set/Get TDM Codec: SLinear */
|
||||
unsigned int power_level; /* Set/Get Power level treshold */
|
||||
unsigned int rx_disable; /* Enable/Disable Rx */
|
||||
unsigned int tx_disable; /* Enable/Disable Tx */
|
||||
unsigned int usr_mtu_mru; /* Set/Get User TDM MTU/MRU */
|
||||
unsigned int ec_tap; /* Echo Cancellation Tap */
|
||||
unsigned int rbs_poll; /* Enable/Disable RBS Polling */
|
||||
unsigned int rbs_rx_bits; /* Rx RBS Bits */
|
||||
unsigned int rbs_tx_bits; /* Tx RBS Bits */
|
||||
unsigned int hdlc; /* HDLC based device */
|
||||
unsigned int idle_flag; /* IDLE flag to Tx */
|
||||
unsigned int fe_alarms; /* FE Alarms detected */
|
||||
wp_tdm_chan_stats_t stats; /* TDM Statistics */
|
||||
/* Do NOT add anything above this! Important for binary backward compatibility. */
|
||||
wp_tdm_api_event_t event; /* TDM Event */
|
||||
unsigned int data_len;
|
||||
void *data;
|
||||
unsigned char fe_status; /* FE status - Connected or Disconnected */
|
||||
unsigned int hw_dtmf; /* HW DTMF enabled */
|
||||
}wanpipe_tdm_api_cmd_t;
|
||||
|
||||
typedef struct wanpipe_tdm_api_event{
|
||||
int (*wp_rbs_event)(sng_fd_t fd, unsigned char rbs_bits);
|
||||
int (*wp_dtmf_event)(sng_fd_t fd, unsigned char dtmf, unsigned char type, unsigned char port);
|
||||
int (*wp_rxhook_event)(sng_fd_t fd, unsigned char hook_state);
|
||||
int (*wp_ring_detect_event)(sng_fd_t fd, unsigned char ring_state);
|
||||
int (*wp_ring_trip_detect_event)(sng_fd_t fd, unsigned char ring_state);
|
||||
int (*wp_fe_alarm_event)(sng_fd_t fd, unsigned char fe_alarm_event);
|
||||
int (*wp_link_status_event)(sng_fd_t fd, unsigned char link_status_event);
|
||||
}wanpipe_tdm_api_event_t;
|
||||
|
||||
typedef struct wanpipe_tdm_api{
|
||||
wanpipe_tdm_api_cmd_t wp_tdm_cmd;
|
||||
wanpipe_tdm_api_event_t wp_tdm_event;
|
||||
}wanpipe_tdm_api_t;
|
||||
|
||||
|
||||
#endif
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
|
||||
#include "ftdm_declare.h"
|
||||
#include "ftdm_call_utils.h"
|
||||
|
||||
/*! \brief Max number of channels per physical span */
|
||||
#define FTDM_MAX_CHANNELS_PHYSICAL_SPAN 32
|
||||
|
@ -62,23 +63,6 @@
|
|||
|
||||
#define FTDM_INVALID_INT_PARM 0xFF
|
||||
|
||||
/*! \brief FreeTDM APIs possible return codes */
|
||||
typedef enum {
|
||||
FTDM_SUCCESS, /*!< Success */
|
||||
FTDM_FAIL, /*!< Failure, generic error return code, use ftdm_channel_get_last_error or ftdm_span_get_last_error for details */
|
||||
FTDM_MEMERR, /*!< Memory error, most likely allocation failure */
|
||||
FTDM_TIMEOUT, /*!< Operation timed out (ie: polling on a device)*/
|
||||
FTDM_NOTIMPL, /*!< Operation not implemented */
|
||||
FTDM_BREAK, /*!< Request the caller to perform a break (context-dependant, ie: stop getting DNIS/ANI) */
|
||||
FTDM_EINVAL /*!< Invalid argument */
|
||||
} ftdm_status_t;
|
||||
|
||||
/*! \brief FreeTDM bool type. */
|
||||
typedef enum {
|
||||
FTDM_FALSE,
|
||||
FTDM_TRUE
|
||||
} ftdm_bool_t;
|
||||
|
||||
/*! \brief Thread/Mutex OS abstraction API. */
|
||||
#include "ftdm_os.h"
|
||||
|
||||
|
@ -220,8 +204,10 @@ typedef enum {
|
|||
FTDM_TON_SUBSCRIBER_NUMBER,
|
||||
FTDM_TON_ABBREVIATED_NUMBER,
|
||||
FTDM_TON_RESERVED,
|
||||
FTDM_TON_INVALID = 255
|
||||
FTDM_TON_INVALID
|
||||
} ftdm_ton_t;
|
||||
#define TON_STRINGS "unknown", "international", "national", "network-specific", "subscriber-number", "abbreviated-number", "reserved", "invalid"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_ton, ftdm_ton2str, ftdm_ton_t)
|
||||
|
||||
/*! Numbering Plan Identification (NPI) */
|
||||
typedef enum {
|
||||
|
@ -232,8 +218,52 @@ typedef enum {
|
|||
FTDM_NPI_NATIONAL = 8,
|
||||
FTDM_NPI_PRIVATE = 9,
|
||||
FTDM_NPI_RESERVED = 10,
|
||||
FTDM_NPI_INVALID = 255
|
||||
FTDM_NPI_INVALID
|
||||
} ftdm_npi_t;
|
||||
#define NPI_STRINGS "unknown", "ISDN", "data", "telex", "national", "private", "reserved", "invalid"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_npi, ftdm_npi2str, ftdm_npi_t)
|
||||
|
||||
/*! Presentation Ind */
|
||||
typedef enum {
|
||||
FTDM_PRES_ALLOWED,
|
||||
FTDM_PRES_RESTRICTED,
|
||||
FTDM_PRES_NOT_AVAILABLE,
|
||||
FTDM_PRES_RESERVED,
|
||||
FTDM_PRES_INVALID
|
||||
} ftdm_presentation_t;
|
||||
#define PRESENTATION_STRINGS "presentation-allowed", "presentation-restricted", "number-not-available", "reserved", "Invalid"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_presentation, ftdm_presentation2str, ftdm_presentation_t)
|
||||
|
||||
/*! Screening Ind */
|
||||
typedef enum {
|
||||
FTDM_SCREENING_NOT_SCREENED,
|
||||
FTDM_SCREENING_VERIFIED_PASSED,
|
||||
FTDM_SCREENING_VERIFIED_FAILED,
|
||||
FTDM_SCREENING_NETWORK_PROVIDED,
|
||||
FTDM_SCREENING_INVALID
|
||||
} ftdm_screening_t;
|
||||
#define SCREENING_STRINGS "user-provided-not-screened", "user-provided-verified-and-passed", "user-provided-verified-and-failed", "network-provided", "invalid"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_screening, ftdm_screening2str, ftdm_screening_t)
|
||||
|
||||
/*! \brief bearer capability */
|
||||
typedef enum {
|
||||
FTDM_BEARER_CAP_SPEECH = 0x00,
|
||||
FTDM_BEARER_CAP_64K_UNRESTRICTED = 0x02,
|
||||
FTDM_BEARER_CAP_3_1KHZ_AUDIO = 0x03,
|
||||
FTDM_BEARER_CAP_INVALID
|
||||
} ftdm_bearer_cap_t;
|
||||
#define BEARER_CAP_STRINGS "speech", "unrestricted-digital-information", "3.1-Khz-audio", "invalid"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_bearer_cap, ftdm_bearer_cap2str, ftdm_bearer_cap_t)
|
||||
|
||||
/*! \brief user information layer 1 protocol */
|
||||
typedef enum {
|
||||
FTDM_USER_LAYER1_PROT_V110 = 0x01,
|
||||
FTDM_USER_LAYER1_PROT_ULAW = 0x02,
|
||||
FTDM_USER_LAYER1_PROT_ALAW = 0x03,
|
||||
FTDM_USER_LAYER1_PROT_INVALID
|
||||
} ftdm_user_layer1_prot_t;
|
||||
#define USER_LAYER1_PROT_STRINGS "V.110", "u-law", "a-law", "Invalid"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_usr_layer1_prot, ftdm_user_layer1_prot2str, ftdm_user_layer1_prot_t)
|
||||
|
||||
/*! \brief Number abstraction */
|
||||
typedef struct {
|
||||
|
@ -242,20 +272,6 @@ typedef struct {
|
|||
uint8_t plan;
|
||||
} ftdm_number_t;
|
||||
|
||||
/*! \brief bearer capability */
|
||||
typedef enum {
|
||||
FTDM_BEARER_CAP_SPEECH = 0x00,
|
||||
FTDM_BEARER_CAP_64K_UNRESTRICTED = 0x02,
|
||||
FTDM_BEARER_CAP_3_1KHZ_AUDIO = 0x03
|
||||
} ftdm_bearer_cap_t;
|
||||
|
||||
/*! \brief user information layer 1 protocol */
|
||||
typedef enum {
|
||||
FTDM_USER_LAYER1_PROT_V110 = 0x01,
|
||||
FTDM_USER_LAYER1_PROT_ULAW = 0x02,
|
||||
FTDM_USER_LAYER1_PROT_ALAW = 0x03,
|
||||
} ftdm_user_layer1_prot_t;
|
||||
|
||||
/*! \brief Caller information */
|
||||
typedef struct ftdm_caller_data {
|
||||
char cid_date[8]; /*!< Caller ID date */
|
||||
|
@ -285,10 +301,12 @@ typedef enum {
|
|||
|
||||
/*! \brief Signaling messages sent by the stacks */
|
||||
typedef enum {
|
||||
FTDM_SIGEVENT_START, /*!< Incoming call (ie: incoming SETUP msg or Ring) */
|
||||
FTDM_SIGEVENT_START,/*!< Incoming call (ie: incoming SETUP msg or Ring) */
|
||||
FTDM_SIGEVENT_STOP, /*!< Hangup */
|
||||
FTDM_SIGEVENT_RELEASED, /*!< Channel is completely released and available */
|
||||
FTDM_SIGEVENT_UP, /*!< Outgoing call has been answered */
|
||||
FTDM_SIGEVENT_FLASH, /*< Flash event (typically on-hook/off-hook for analog devices) */
|
||||
FTDM_SIGEVENT_FLASH, /*!< Flash event (typically on-hook/off-hook for analog devices) */
|
||||
FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got a response */
|
||||
FTDM_SIGEVENT_PROGRESS, /*!< Outgoing call is making progress */
|
||||
FTDM_SIGEVENT_PROGRESS_MEDIA, /*!< Outgoing call is making progress and there is media available */
|
||||
FTDM_SIGEVENT_ALARM_TRAP, /*!< Hardware alarm ON */
|
||||
|
@ -298,11 +316,12 @@ typedef enum {
|
|||
FTDM_SIGEVENT_RESTART, /*!< Restart has been requested. Typically you hangup your call resources here */
|
||||
FTDM_SIGEVENT_SIGSTATUS_CHANGED, /*!< Signaling protocol status changed (ie: D-chan up), see new status in raw_data ftdm_sigmsg_t member */
|
||||
FTDM_SIGEVENT_COLLISION, /*!< Outgoing call was dropped because an incoming call arrived at the same time */
|
||||
FTDM_SIGEVENT_MSG, /*!< We received an in-call msg */
|
||||
FTDM_SIGEVENT_INVALID
|
||||
} ftdm_signal_event_t;
|
||||
#define SIGNAL_STRINGS "START", "STOP", "UP", "FLASH", "PROGRESS", \
|
||||
#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "PROGRESS", \
|
||||
"PROGRESS_MEDIA", "ALARM_TRAP", "ALARM_CLEAR", \
|
||||
"COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "INVALID"
|
||||
"COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "MSG", "INVALID"
|
||||
|
||||
/*! \brief Move from string to ftdm_signal_event_t and viceversa */
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_signal_event, ftdm_signal_event2str, ftdm_signal_event_t)
|
||||
|
@ -430,12 +449,15 @@ typedef enum {
|
|||
FTDM_COMMAND_FLUSH_TX_BUFFERS,
|
||||
FTDM_COMMAND_FLUSH_RX_BUFFERS,
|
||||
FTDM_COMMAND_FLUSH_BUFFERS,
|
||||
FTDM_COMMAND_FLUSH_IOSTATS,
|
||||
FTDM_COMMAND_SET_PRE_BUFFER_SIZE,
|
||||
FTDM_COMMAND_SET_LINK_STATUS,
|
||||
FTDM_COMMAND_GET_LINK_STATUS,
|
||||
FTDM_COMMAND_ENABLE_LOOP,
|
||||
FTDM_COMMAND_DISABLE_LOOP,
|
||||
FTDM_COMMAND_COUNT
|
||||
FTDM_COMMAND_COUNT,
|
||||
FTDM_COMMAND_SET_RX_QUEUE_SIZE,
|
||||
FTDM_COMMAND_SET_TX_QUEUE_SIZE,
|
||||
} ftdm_command_t;
|
||||
|
||||
/*! \brief Custom memory handler hooks. Not recommended to use unless you need memory allocation customizations */
|
||||
|
@ -577,7 +599,7 @@ typedef enum {
|
|||
* This is used during incoming calls when you want to request the signaling stack
|
||||
* to notify about indications occurring locally */
|
||||
typedef enum {
|
||||
FTDM_CHANNEL_INDICATE_RING,
|
||||
FTDM_CHANNEL_INDICATE_RINGING,
|
||||
FTDM_CHANNEL_INDICATE_PROCEED,
|
||||
FTDM_CHANNEL_INDICATE_PROGRESS,
|
||||
FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA,
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Sangoma Technologies
|
||||
* David Yat Sin <dyatsin@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __FTDM_CALL_UTILS_H__
|
||||
#define __FTDM_CALL_UTILS_H__
|
||||
|
||||
/*!
|
||||
* \brief Set the Numbering Plan Identification from a string
|
||||
*
|
||||
* \param npi_string string value
|
||||
* \param target the target to set value to
|
||||
*
|
||||
* \retval FTDM_SUCCESS success
|
||||
* \retval FTDM_FAIL failure
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_set_npi(const char *npi_string, uint8_t *target);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Set the Type of number from a string
|
||||
*
|
||||
* \param ton_string string value
|
||||
* \param target the target to set value to
|
||||
*
|
||||
* \retval FTDM_SUCCESS success
|
||||
* \retval FTDM_FAIL failure
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_set_ton(const char *ton_string, uint8_t *target);
|
||||
|
||||
/*!
|
||||
* \brief Set the Bearer Capability from a string
|
||||
*
|
||||
* \param bc_string string value
|
||||
* \param target the target to set value to
|
||||
*
|
||||
* \retval FTDM_SUCCESS success
|
||||
* \retval FTDM_FAIL failure
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_set_bearer_capability(const char *bc_string, uint8_t *target);
|
||||
|
||||
/*!
|
||||
* \brief Set the Bearer Capability - Layer 1 from a string
|
||||
*
|
||||
* \param bc_string string value
|
||||
* \param target the target to set value to
|
||||
*
|
||||
* \retval FTDM_SUCCESS success
|
||||
* \retval FTDM_FAIL failure
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_set_bearer_layer1(const char *bc_string, uint8_t *target);
|
||||
|
||||
/*!
|
||||
* \brief Set the Screening Ind from a string
|
||||
*
|
||||
* \param screen_string string value
|
||||
* \param target the target to set value to
|
||||
*
|
||||
* \retval FTDM_SUCCESS success
|
||||
* \retval FTDM_FAIL failure
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_set_screening_ind(const char *string, uint8_t *target);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Set the Presentation Ind from an enum
|
||||
*
|
||||
* \param screen_string string value
|
||||
* \param target the target to set value to
|
||||
*
|
||||
* \retval FTDM_SUCCESS success
|
||||
* \retval FTDM_FAIL failure
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_set_presentation_ind(const char *string, uint8_t *target);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Checks whether a string contains only numbers
|
||||
*
|
||||
* \param number string value
|
||||
*
|
||||
* \retval FTDM_SUCCESS success
|
||||
* \retval FTDM_FAIL failure
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number);
|
||||
|
||||
#endif /* __FTDM_CALL_UTILS_H__ */
|
||||
|
|
@ -171,6 +171,23 @@ typedef int ftdm_socket_t;
|
|||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
/*! \brief FreeTDM APIs possible return codes */
|
||||
typedef enum {
|
||||
FTDM_SUCCESS, /*!< Success */
|
||||
FTDM_FAIL, /*!< Failure, generic error return code, use ftdm_channel_get_last_error or ftdm_span_get_last_error for details */
|
||||
FTDM_MEMERR, /*!< Memory error, most likely allocation failure */
|
||||
FTDM_TIMEOUT, /*!< Operation timed out (ie: polling on a device)*/
|
||||
FTDM_NOTIMPL, /*!< Operation not implemented */
|
||||
FTDM_BREAK, /*!< Request the caller to perform a break (context-dependant, ie: stop getting DNIS/ANI) */
|
||||
FTDM_EINVAL /*!< Invalid argument */
|
||||
} ftdm_status_t;
|
||||
|
||||
/*! \brief FreeTDM bool type. */
|
||||
typedef enum {
|
||||
FTDM_FALSE,
|
||||
FTDM_TRUE
|
||||
} ftdm_bool_t;
|
||||
|
||||
/*!
|
||||
* \brief FreeTDM channel.
|
||||
* This is the basic data structure used to place calls and I/O operations
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Sangoma Technologies
|
||||
* David Yat Sin <dyatsin@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __FTDM_CALL_UTILS_H__
|
||||
#define __FTDM_CALL_UTILS_H__
|
||||
|
||||
#include "freetdm.h"
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_npi(const char *npi_string, uint8_t *target);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_ton(const char *ton_string, uint8_t *target);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_capability(const char *bc_string, ftdm_bearer_cap_t *target);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_layer1(const char *bc_string, ftdm_user_layer1_prot_t *target);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_is_number(char *number);
|
||||
|
||||
#endif /* __FTDM_CALL_UTILS_H__ */
|
||||
|
|
@ -222,8 +222,7 @@ extern "C" {
|
|||
|
||||
#define ftdm_is_dtmf(key) ((key > 47 && key < 58) || (key > 64 && key < 69) || (key > 96 && key < 101) || key == 35 || key == 42 || key == 87 || key == 119)
|
||||
|
||||
#define FTDM_SPAN_IS_BRI(x) ((x)->trunk_type == FTDM_TRUNK_BRI || (x)->trunk_type == FTDM_TRUNK_BRI_PTMP)
|
||||
|
||||
#define FTDM_SPAN_IS_BRI(x) ((x)->trunk_type == FTDM_TRUNK_BRI || (x)->trunk_type == FTDM_TRUNK_BRI_PTMP)
|
||||
/*!
|
||||
\brief Copy flags from one arbitrary object to another
|
||||
\command dest the object to copy the flags to
|
||||
|
@ -358,6 +357,7 @@ typedef struct {
|
|||
} ftdm_dtmf_debug_t;
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
const char *file;
|
||||
const char *func;
|
||||
|
@ -367,6 +367,35 @@ typedef struct {
|
|||
ftdm_time_t time;
|
||||
} ftdm_channel_history_entry_t;
|
||||
|
||||
typedef enum {
|
||||
FTDM_IOSTATS_ERROR_CRC = (1 << 0),
|
||||
FTDM_IOSTATS_ERROR_FRAME = (1 << 1),
|
||||
FTDM_IOSTATS_ERROR_ABORT = (1 << 2),
|
||||
FTDM_IOSTATS_ERROR_FIFO = (1 << 3),
|
||||
FTDM_IOSTATS_ERROR_DMA = (1 << 4),
|
||||
FTDM_IOSTATS_ERROR_QUEUE_THRES = (1 << 5), /* Queue reached high threshold */
|
||||
FTDM_IOSTATS_ERROR_QUEUE_FULL = (1 << 6), /* Queue is full */
|
||||
} ftdm_iostats_error_type_t;
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
uint32_t errors;
|
||||
uint16_t flags;
|
||||
uint8_t queue_size; /* max queue size configured */
|
||||
uint8_t queue_len; /* Current number of elements in queue */
|
||||
uint64_t packets;
|
||||
} rx;
|
||||
|
||||
struct {
|
||||
uint32_t errors;
|
||||
uint16_t flags;
|
||||
uint8_t idle_packets;
|
||||
uint8_t queue_size; /* max queue size configured */
|
||||
uint8_t queue_len; /* Current number of elements in queue */
|
||||
uint64_t packets;
|
||||
} tx;
|
||||
} ftdm_channel_iostats_t;
|
||||
|
||||
/* 2^8 table size, one for each byte (sample) value */
|
||||
#define FTDM_GAINS_TABLE_SIZE 256
|
||||
struct ftdm_channel {
|
||||
|
@ -441,6 +470,7 @@ struct ftdm_channel {
|
|||
int availability_rate;
|
||||
void *user_private;
|
||||
ftdm_timer_id_t hangup_timer;
|
||||
ftdm_channel_iostats_t iostats;
|
||||
#ifdef FTDM_DEBUG_DTMF
|
||||
ftdm_dtmf_debug_t dtmfdbg;
|
||||
#endif
|
||||
|
@ -637,10 +667,21 @@ FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan);
|
|||
|
||||
#define ftdm_channel_lock(chan) ftdm_mutex_lock(chan->mutex)
|
||||
#define ftdm_channel_unlock(chan) ftdm_mutex_unlock(chan->mutex)
|
||||
|
||||
#define ftdm_log_throttle(level, ...) \
|
||||
time_current_throttle_log = ftdm_current_time_in_ms(); \
|
||||
if (time_current_throttle_log - time_last_throttle_log > FTDM_THROTTLE_LOG_INTERVAL) {\
|
||||
ftdm_log(level, __VA_ARGS__); \
|
||||
time_last_throttle_log = time_current_throttle_log; \
|
||||
}
|
||||
|
||||
#define ftdm_log_chan_ex(fchan, file, func, line, level, format, ...) ftdm_log(file, func, line, level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
|
||||
#define ftdm_log_chan(fchan, level, format, ...) ftdm_log(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
|
||||
#define ftdm_log_chan_msg(fchan, level, msg) ftdm_log(level, "[s%dc%d][%d:%d] " msg, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id)
|
||||
|
||||
#define ftdm_log_chan_throttle(fchan, level, format, ...) ftdm_log_throttle(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
|
||||
#define ftdm_log_chan_msg_throttle(fchan, level, format, ...) ftdm_log_throttle(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
|
||||
|
||||
#define ftdm_span_lock(span) ftdm_mutex_lock(span->mutex)
|
||||
#define ftdm_span_unlock(span) ftdm_mutex_unlock(span->mutex)
|
||||
|
||||
|
|
|
@ -181,6 +181,8 @@ typedef enum {
|
|||
* after having called ftdm_send_span_signal(), which with this flag it will just enqueue the signal
|
||||
* for later delivery */
|
||||
FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 10),
|
||||
/* If this flag is set, channel will be moved to proceed state when calls goes to routing */
|
||||
FTDM_SPAN_USE_PROCEED_STATE = (1 << 11),
|
||||
} ftdm_span_flag_t;
|
||||
|
||||
/*! \brief Channel supported features */
|
||||
|
@ -194,6 +196,7 @@ typedef enum {
|
|||
FTDM_CHANNEL_FEATURE_CALLWAITING = (1 << 6), /*!< Channel will allow call waiting (ie: FXS devices) (read/write) */
|
||||
FTDM_CHANNEL_FEATURE_HWEC = (1<<7), /*!< Channel has a hardware echo canceller */
|
||||
FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE = (1<<8), /*!< hardware echo canceller is disabled when there are no calls on this channel */
|
||||
FTDM_CHANNEL_FEATURE_IO_STATS = (1<<9), /*!< Channel supports IO statistics (HDLC channels only) */
|
||||
} ftdm_channel_feature_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -203,6 +206,7 @@ typedef enum {
|
|||
FTDM_CHANNEL_STATE_DIALTONE,
|
||||
FTDM_CHANNEL_STATE_COLLECT,
|
||||
FTDM_CHANNEL_STATE_RING,
|
||||
FTDM_CHANNEL_STATE_RINGING,
|
||||
FTDM_CHANNEL_STATE_BUSY,
|
||||
FTDM_CHANNEL_STATE_ATTN,
|
||||
FTDM_CHANNEL_STATE_GENRING,
|
||||
|
@ -210,6 +214,7 @@ typedef enum {
|
|||
FTDM_CHANNEL_STATE_GET_CALLERID,
|
||||
FTDM_CHANNEL_STATE_CALLWAITING,
|
||||
FTDM_CHANNEL_STATE_RESTART,
|
||||
FTDM_CHANNEL_STATE_PROCEED,
|
||||
FTDM_CHANNEL_STATE_PROGRESS,
|
||||
FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
|
||||
FTDM_CHANNEL_STATE_UP,
|
||||
|
@ -222,8 +227,8 @@ typedef enum {
|
|||
FTDM_CHANNEL_STATE_INVALID
|
||||
} ftdm_channel_state_t;
|
||||
#define CHANNEL_STATE_STRINGS "DOWN", "HOLD", "SUSPENDED", "DIALTONE", "COLLECT", \
|
||||
"RING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \
|
||||
"RESTART", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", \
|
||||
"RING", "RINGING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \
|
||||
"RESTART", "PROCEED", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", \
|
||||
"HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "INVALID"
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t)
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_signal)
|
|||
|
||||
switch(sigmsg->event_id) {
|
||||
case FTDM_SIGEVENT_START:
|
||||
ftdm_channel_call_indicate(sigmsg->channel, FTDM_CHANNEL_INDICATE_RING);
|
||||
ftdm_channel_call_indicate(sigmsg->channel, FTDM_CHANNEL_INDICATE_RINGING);
|
||||
ftdm_log(FTDM_LOG_DEBUG, "launching thread and indicating ring\n");
|
||||
ftdm_thread_create_detached(test_call, sigmsg->channel);
|
||||
break;
|
||||
|
|
|
@ -45,10 +45,14 @@
|
|||
|
||||
#include <signal.h>
|
||||
|
||||
#include "freetdm.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#ifdef __linux__
|
||||
#define __USE_BSD
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "freetdm.h"
|
||||
|
||||
|
||||
/* arbitrary limit for max calls in this sample program */
|
||||
|
@ -338,9 +342,9 @@ int main(int argc, char *argv[])
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[2], "cpe")) {
|
||||
if (!strcmp(argv[2], "cpe")) {
|
||||
sigtype = "pri_cpe";
|
||||
} else if (!strcasecmp(argv[2], "net")) {
|
||||
} else if (!strcmp(argv[2], "net")) {
|
||||
sigtype = "pri_net";
|
||||
} else {
|
||||
fprintf(stderr, "Valid signaling types are cpe and net only\n");
|
||||
|
|
|
@ -135,6 +135,7 @@ struct switch_core_session {
|
|||
switch_mutex_t *frame_read_mutex;
|
||||
|
||||
switch_thread_rwlock_t *rwlock;
|
||||
switch_thread_rwlock_t *io_rwlock;
|
||||
|
||||
void *streams[SWITCH_MAX_STREAMS];
|
||||
int stream_count;
|
||||
|
|
|
@ -354,6 +354,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void);
|
|||
///\ingroup core1
|
||||
///\{
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_io_read_lock(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_io_write_lock(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_io_rwunlock(switch_core_session_t *session);
|
||||
|
||||
#ifdef SWITCH_DEBUG_RWLOCKS
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_perform_read_lock(_In_ switch_core_session_t *session, const char *file, const char *func, int line);
|
||||
#endif
|
||||
|
@ -882,6 +887,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_exec(_In_ switch_core_sessio
|
|||
SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flags(_In_ switch_core_session_t *session,
|
||||
_In_ const char *app, _In_opt_z_ const char *arg, _Out_opt_ int32_t *flags);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_async(switch_core_session_t *session, const char *app, const char *arg);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_get_app_flags(const char *app, int32_t *flags);
|
||||
|
||||
/*!
|
||||
|
|
|
@ -874,6 +874,12 @@ SWITCH_DECLARE(void) switch_ivr_dmachine_set_input_timeout_ms(switch_ivr_dmachin
|
|||
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear_realm(switch_ivr_dmachine_t *dmachine, const char *realm);
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_set_realm(switch_ivr_dmachine_t *dmachine, const char *realm);
|
||||
|
||||
|
||||
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);
|
||||
|
||||
/** @} */
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
|
|
|
@ -3968,6 +3968,47 @@ SWITCH_STANDARD_API(uuid_getvar_function)
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#define FILEMAN_SYNTAX "<uuid> <cmd>:<val>"
|
||||
SWITCH_STANDARD_API(uuid_fileman_function)
|
||||
{
|
||||
switch_core_session_t *psession = NULL;
|
||||
char *mycmd = NULL, *argv[4] = { 0 };
|
||||
int argc = 0;
|
||||
|
||||
if (!zstr(cmd) && (mycmd = strdup(cmd))) {
|
||||
argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
if (argc >= 2 && !zstr(argv[0])) {
|
||||
char *uuid = argv[0];
|
||||
char *cmd = argv[1];
|
||||
|
||||
if ((psession = switch_core_session_locate(uuid))) {
|
||||
switch_channel_t *channel;
|
||||
switch_file_handle_t *fh = NULL;
|
||||
|
||||
channel = switch_core_session_get_channel(psession);
|
||||
|
||||
if (switch_ivr_get_file_handle(psession, &fh) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_ivr_process_fh(psession, cmd, fh);
|
||||
switch_ivr_release_file_handle(psession, &fh);
|
||||
}
|
||||
|
||||
switch_core_session_rwunlock(psession);
|
||||
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR No Such Channel!\n");
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
stream->write_function(stream, "-USAGE: %s\n", GETVAR_SYNTAX);
|
||||
|
||||
done:
|
||||
switch_safe_free(mycmd);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define UUID_SEND_DTMF_SYNTAX "<uuid> <dtmf_data>"
|
||||
SWITCH_STANDARD_API(uuid_send_dtmf_function)
|
||||
{
|
||||
|
@ -4674,6 +4715,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
|||
SWITCH_ADD_API(commands_api_interface, "uuid_display", "change display", uuid_display_function, DISPLAY_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_dump", "uuid_dump", uuid_dump_function, DUMP_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_exists", "see if a uuid exists", uuid_exists_function, EXISTS_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_fileman", "uuid_fileman", uuid_fileman_function, FILEMAN_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_flush_dtmf", "Flush dtmf on a given uuid", uuid_flush_dtmf_function, "<uuid>");
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_getvar", "uuid_getvar", uuid_getvar_function, GETVAR_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_hold", "hold", uuid_hold_function, HOLD_SYNTAX);
|
||||
|
@ -4785,6 +4827,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
|||
switch_console_set_complete("add uuid_display ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_dump ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_exists ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_fileman ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_flush_dtmf ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_getvar ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_hold ::console::list_uuid");
|
||||
|
|
|
@ -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;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue