Merge branch 'master' into ftmod_r2

This commit is contained in:
Arnaldo Pereira committed 2010-11-01 23:11:42 -02:00
commit 039e4297ac
358 files changed
+23197 -3246

No files matched your search

@@ -374,7 +374,7 @@ static ftdm_state_map_t isdn_state_map = {
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
{FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
},
{
ZSD_OUTBOUND,
@@ -424,7 +424,7 @@ static ftdm_state_map_t isdn_state_map = {
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
{FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END},
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END},
},
{
ZSD_INBOUND,
@@ -605,10 +605,9 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
if (call) {
pri_hangup(isdn_data->spri.pri, call, ftdmchan->caller_data.hangup_cause);
pri_destroycall(isdn_data->spri.pri, call);
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
} else {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
}
ftdmchan->call_data = NULL;
}
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
}
break;
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
@@ -617,8 +616,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
{
sig.event_id = FTDM_SIGEVENT_STOP;
status = ftdm_span_send_signal(ftdmchan->span, &sig);
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
/* user moves us to HANGUP and from there we go to DOWN */
}
default:
break;
@@ -641,10 +639,12 @@ static __inline__ void check_state(ftdm_span_t *span)
for(j = 1; j <= span->chan_count; j++) {
if (ftdm_test_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_mutex_lock(span->channels[j]->mutex);
ftdm_channel_lock(span->channels[j]);
ftdm_clear_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE);
state_advance(span->channels[j]);
ftdm_channel_complete_state(span->channels[j]);
ftdm_mutex_unlock(span->channels[j]->mutex);
ftdm_channel_unlock(span->channels[j]);
}
}
}
@@ -682,18 +682,35 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
q931_call *call = NULL;
ftdmchan = span->channels[pevent->hangup.channel];
if (ftdmchan) {
call = (q931_call *) ftdmchan->call_data;
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n", spri->span->span_id, pevent->hangup.channel);
ftdmchan->caller_data.hangup_cause = pevent->hangup.cause;
pri_release(spri->pri, call, 0);
pri_destroycall(spri->pri, call);
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
} else {
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d %s but it's not in use?\n", spri->span->span_id,
pevent->hangup.channel, ftdmchan->chan_id);
if (!ftdmchan) {
ftdm_log(FTDM_LOG_CRIT, "-- Hangup on channel %d:%d %s but it's not in use?\n", spri->span->span_id, pevent->hangup.channel);
return 0;
}
ftdm_channel_lock(ftdmchan);
if (ftdmchan->state >= FTDM_CHANNEL_STATE_TERMINATING) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Ignoring remote hangup in state %s\n", ftdm_channel_state2str(ftdmchan->state));
goto done;
}
if (!ftdmchan->call_data) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Ignoring remote hangup in state %s with no call data\n", ftdm_channel_state2str(ftdmchan->state));
goto done;
}
call = (q931_call *) ftdmchan->call_data;
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n", spri->span->span_id, pevent->hangup.channel);
ftdmchan->caller_data.hangup_cause = pevent->hangup.cause;
pri_release(spri->pri, call, 0);
pri_destroycall(spri->pri, call);
ftdmchan->call_data = NULL;
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
done:
ftdm_channel_unlock(ftdmchan);
return 0;
}
@@ -1087,10 +1104,17 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj)
got_d = 1;
x++;
break;
} else {
ftdm_log(FTDM_LOG_ERROR, "failed to open d-channel #%d %d:%d\n", x, span->channels[i]->span_id, span->channels[i]->chan_id);
}
}
}
}
if (!got_d) {
ftdm_log(FTDM_LOG_ERROR, "Failed to get a D-channel in span %d\n", span->span_id);
break;
}
if (lpwrap_init_pri(&isdn_data->spri,
@@ -1133,7 +1157,9 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj)
}
ftdm_log(FTDM_LOG_CRIT, "PRI down on span %d\n", isdn_data->spri.span->span_id);
isdn_data->spri.dchan->state = FTDM_CHANNEL_STATE_DOWN;
if (isdn_data->spri.dchan) {
isdn_data->spri.dchan->state = FTDM_CHANNEL_STATE_DOWN;
}
if (!down) {
ftdm_set_state_all(span, FTDM_CHANNEL_STATE_RESTART);
@@ -1147,7 +1173,7 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj)
ftdm_sleep(5000);
}
ftdm_log(FTDM_LOG_DEBUG, "PRI thread ended on span %d\n", isdn_data->spri.span->span_id);
ftdm_log(FTDM_LOG_DEBUG, "PRI thread ended on span %d\n", span->span_id);
ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD);
ftdm_clear_flag(isdn_data, FTMOD_LIBPRI_RUNNING);
@@ -177,7 +177,7 @@ int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *
spri->dchan = dchan;
spri->span = span;
if ((spri->pri = pri_new_cb(spri->dchan->sockfd, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))){
if (spri->dchan && (spri->pri = pri_new_cb(spri->dchan->sockfd, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))){
unsigned char buf[4] = { 0 };
size_t buflen = sizeof(buf), len = 0;
pri_set_debug(spri->pri, debug);
@@ -0,0 +1,241 @@
<?xml version="1.0" encoding="UTF-8"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="ftmod_sangoma_isdn"
ProjectGUID="{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}"
RootNamespace="ftmod_sangoma_isdn"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Program Files\libsng_isdn\include&quot;;&quot;C:\Program Files\libsng_isdn\include\sng_isdn&quot;;../../include;&quot;C:\Program Files\Sangoma\include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
MinimalRebuild="true"
ExceptionHandling="0"
BasicRuntimeChecks="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="freetdm.lib libsng_isdn.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="&quot;$(OutDir)&quot;;&quot;C:\Program Files\libsng_isdn\lib&quot;;&quot;C:\Program Files\Sangoma\api\lib\x86&quot;"
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"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
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>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\ftmod_sangoma_isdn.h"
>
</File>
<File
RelativePath=".\ftmod_sangoma_isdn_trace.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<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_sangoma_isdn.c"
>
</File>
<File
RelativePath=".\ftmod_sangoma_isdn_cfg.c"
>
</File>
<File
RelativePath=".\ftmod_sangoma_isdn_cntrl.c"
>
</File>
<File
RelativePath=".\ftmod_sangoma_isdn_stack_cfg.c"
>
</File>
<File
RelativePath=".\ftmod_sangoma_isdn_stack_cntrl.c"
>
</File>
<File
RelativePath=".\ftmod_sangoma_isdn_stack_hndl.c"
>
</File>
<File
RelativePath=".\ftmod_sangoma_isdn_stack_out.c"
>
</File>
<File
RelativePath=".\ftmod_sangoma_isdn_stack_rcv.c"
>
</File>
<File
RelativePath=".\ftmod_sangoma_isdn_support.c"
>
</File>
<File
RelativePath=".\ftmod_sangoma_isdn_trace.c"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -265,10 +265,12 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
}
while (ftdm_running() && !(ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD))) {
/* find out why we returned from the interrupt queue */
ret_status = ftdm_interrupt_multiple_wait(ftdm_sangoma_isdn_int, 2, sleep);
/* Check if there are any timers to process */
ftdm_sched_run(signal_data->sched);
ret_status = ftdm_interrupt_multiple_wait(ftdm_sangoma_isdn_int, 2, sleep);
/* find out why we returned from the interrupt queue */
switch (ret_status) {
case FTDM_SUCCESS: /* there was a state change on the span */
/* process all pending state changes */
@@ -289,13 +291,30 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
/* twiddle */
break;
case FTDM_FAIL:
ftdm_log(FTDM_LOG_ERROR,"ftdm_interrupt_wait returned error!\non span = %s\n", span->name);
ftdm_log(FTDM_LOG_ERROR,"%s:ftdm_interrupt_wait returned error!\n", span->name);
break;
default:
ftdm_log(FTDM_LOG_ERROR,"ftdm_interrupt_wait returned with unknown code on span = %s\n", span->name);
ftdm_log(FTDM_LOG_ERROR,"%s:ftdm_interrupt_wait returned with unknown code\n", span->name);
break;
}
/* Poll for events, e.g HW DTMF */
ret_status = ftdm_span_poll_event(span, 0);
switch(ret_status) {
case FTDM_SUCCESS:
{
ftdm_event_t *event;
while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS);
}
break;
case FTDM_TIMEOUT:
/* No events pending */
break;
default:
ftdm_log(FTDM_LOG_WARNING, "%s:Failed to poll span event\n", span->name);
}
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;
@@ -726,7 +745,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) {
ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name);
@@ -747,9 +766,11 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
}
static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span)
{
{
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
unsigned i;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
ftdm_log(FTDM_LOG_INFO, "Stopping span %s\n", span->name);
/* throw the STOP_THREAD flag to signal monitor thread stop */
@@ -772,8 +793,13 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span)
}
ftdm_iterator_free(chaniter);
ftdm_sched_destroy(&((sngisdn_span_data_t*)span->signal_data)->sched);
ftdm_queue_destroy(&((sngisdn_span_data_t*)span->signal_data)->event_queue);
ftdm_sched_destroy(&signal_data->sched);
ftdm_queue_destroy(&signal_data->event_queue);
for (i = 0 ; i < signal_data->num_local_numbers ; i++) {
if (signal_data->local_numbers[i] != NULL) {
ftdm_safe_free(signal_data->local_numbers[i]);
}
}
ftdm_safe_free(span->signal_data);
ftdm_log(FTDM_LOG_DEBUG, "Finished stopping span %s\n", span->name);
@@ -1003,7 +1029,7 @@ static FIO_IO_LOAD_FUNCTION(ftdm_sangoma_isdn_io_init)
return FTDM_SUCCESS;
}
ftdm_module_t ftdm_module =
EX_DECLARE_DATA ftdm_module_t ftdm_module =
{
"sangoma_isdn", /* char name[256]; */
ftdm_sangoma_isdn_io_init, /* fio_io_load_t */
@@ -38,8 +38,12 @@
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <ctype.h>
#include "private/ftdm_core.h"
@@ -55,6 +59,7 @@
#define NUM_BRI_CHANNELS_PER_SPAN 2
#define SNGISDN_EVENT_QUEUE_SIZE 100
#define SNGISDN_EVENT_POLL_RATE 100
#define SNGISDN_NUM_LOCAL_NUMBERS 8
/* TODO: rename all *_cc_* to *_an_* */
@@ -161,7 +166,7 @@ typedef struct sngisdn_chan_data {
/* Span specific data */
typedef struct sngisdn_span_data {
ftdm_span_t *ftdm_span;
ftdm_span_t *ftdm_span;
uint8_t link_id;
uint8_t switchtype;
uint8_t signalling; /* SNGISDN_SIGNALING_CPE or SNGISDN_SIGNALING_NET */
@@ -175,7 +180,9 @@ typedef struct sngisdn_span_data {
uint8_t setup_arb;
uint8_t facility;
int8_t facility_timeout;
ftdm_sched_t *sched;
uint8_t num_local_numbers;
char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS];
ftdm_sched_t *sched;
ftdm_queue_t *event_queue;
} sngisdn_span_data_t;
@@ -259,16 +266,16 @@ 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 */
uint32_t get_unique_suInstId(uint8_t cc_id);
void clear_call_data(sngisdn_chan_data_t *sngisdn_info);
void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info);
FT_DECLARE_INLINE(uint32_t) get_unique_suInstId(uint8_t cc_id);
FT_DECLARE_INLINE(void) clear_call_data(sngisdn_chan_data_t *sngisdn_info);
FT_DECLARE_INLINE(void) clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info);
void stack_hdr_init(Header *hdr);
void stack_pst_init(Pst *pst);
ftdm_status_t get_ftdmchan_by_spInstId(uint8_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data);
ftdm_status_t get_ftdmchan_by_suInstId(uint8_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data);
ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *ftdmspan, sngisdn_avail_t avail);
FT_DECLARE_INLINE(ftdm_status_t) get_ftdmchan_by_spInstId(uint8_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data);
FT_DECLARE_INLINE(ftdm_status_t) get_ftdmchan_by_suInstId(uint8_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data);
FT_DECLARE_INLINE(ftdm_status_t) sng_isdn_set_avail_rate(ftdm_span_t *ftdmspan, sngisdn_avail_t avail);
/* Outbound Call Control functions */
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan);
@@ -36,9 +36,23 @@
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);
extern ftdm_sngisdn_data_t g_sngisdn_data;
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;
if (signal_data->num_local_numbers >= SNGISDN_NUM_LOCAL_NUMBERS) {
ftdm_log(FTDM_LOG_ERROR, "%s: Maximum number of local-numbers exceeded (max:%d)\n", span->name, SNGISDN_NUM_LOCAL_NUMBERS);
return FTDM_FAIL;
}
signal_data->local_numbers[signal_data->num_local_numbers++] = ftdm_strdup(val);
return FTDM_SUCCESS;
}
ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
{
unsigned i;
@@ -253,6 +267,10 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
ftdm_span_set_bearer_capability(val, &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);
} else if (!strcasecmp(var, "local-number")) {
if (add_local_number(val, span) != FTDM_SUCCESS) {
return FTDM_FAIL;
}
} else if (!strcasecmp(var, "facility-timeout")) {
signal_data->facility_timeout = atoi(val);
if (signal_data->facility_timeout < 0) {
@@ -193,10 +193,12 @@ ftdm_status_t sng_isdn_stack_cfg_phy_gen(void)
ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span)
{
/*local variables*/
L1Mngmt cfg; /*configuration structure*/
Pst pst; /*post structure*/
ftdm_iterator_t *chaniter;
ftdm_iterator_t *curr;
L1Mngmt cfg;
Pst pst;
S32 d_channel_fd = -1;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
/* initalize the post structure */
@@ -219,20 +221,35 @@ ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span)
cfg.hdr.elmId.elmntInst1 = signal_data->link_id;
cfg.t.cfg.s.l1PSAP.span = span->channels[1]->physical_span_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 = (S32) ftdmchan->sockfd;
break;
}
}
ftdm_iterator_free(chaniter);
if(d_channel_fd < 0) {
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;
switch(span->trunk_type) {
case FTDM_TRUNK_E1:
cfg.t.cfg.s.l1PSAP.chan = 16;
cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_PRI;
break;
case FTDM_TRUNK_T1:
case FTDM_TRUNK_J1:
cfg.t.cfg.s.l1PSAP.chan = 24;
cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_PRI;
break;
case FTDM_TRUNK_BRI:
case FTDM_TRUNK_BRI_PTMP:
cfg.t.cfg.s.l1PSAP.chan = 3;
cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_BRI;
break;
default:
@@ -158,7 +158,7 @@ ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span)
ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span)
{
CcMngmt cntrl;;
CcMngmt cntrl;
Pst pst;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
@@ -239,7 +239,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)
{
InMngmt cntrl;;
InMngmt cntrl;
Pst pst;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
@@ -42,8 +42,7 @@ extern ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Displ
/* Remote side transmit a SETUP */
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
unsigned i;
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -54,10 +53,12 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
ConEvnt *conEvnt = &sngisdn_event->event.conEvnt;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_DOWN: /* Proper state to receive a SETUP */
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE) ||
@@ -77,14 +78,39 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
break;
}
sngisdn_info->suInstId = get_unique_suInstId(suId);
sngisdn_info->suInstId = get_unique_suInstId((int8_t) suId);
sngisdn_info->spInstId = spInstId;
if (conEvnt->cdPtyNmb.eh.pres && signal_data->num_local_numbers) {
uint8_t local_number_matched = 0;
for (i = 0 ; i < signal_data->num_local_numbers ; i++) {
if (!strcmp(signal_data->local_numbers[i], (char*)conEvnt->cdPtyNmb.nmbDigits.val)) {
local_number_matched++;
break;
}
}
if (!local_number_matched) {
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SETUP, but local-number %s does not match - ignoring\n", conEvnt->cdPtyNmb.nmbDigits.val);
/* Special case to tell the stack to clear all internal resources about this call. We will no receive any event for this call after sending disconnect request */
ftdmchan->caller_data.hangup_cause = IN_CCNORTTODEST;
ftdm_sched_timer(signal_data->sched, "delayed_disconnect", 1, sngisdn_delayed_disconnect, (void*) sngisdn_info, NULL);
return;
}
}
/* If this is a glared call that was previously saved, we moved
all the info to the current call, so clear the glared saved data */
if (sngisdn_info->glare.spInstId == spInstId) {
clear_call_glare_data(sngisdn_info);
}
}
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
if (signal_data->signalling == SNGISDN_SIGNALING_NET) {
sngisdn_info->ces = ces;
}
}
ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);
g_sngisdn_data.ccs[suId].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info;
@@ -92,11 +118,6 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP &&
signal_data->signalling == SNGISDN_SIGNALING_NET) {
sngisdn_info->ces = ces;
}
/* try to open the channel */
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to open channel");
@@ -109,27 +130,24 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
#if 0
/* Export ftdmchan variables here if we need to */
ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1");
ftdm_channel_add_var(ftdmchan, "isdn_crap", "morecrap");
ftdm_channel_add_var(ftdmchan, "isdn_stuff", "s");
ftdm_channel_add_var(ftdmchan, "isdn_d", "asdsadasdasdsad");
#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);
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) {
ftdmchan->caller_data.bearer_layer1 = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].usrInfoLyr1Prot.val);
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 (signal_data->facility == SNGISDN_OPT_TRUE && conEvnt->facilityStr.eh.pres) {
/* Verify whether the Caller Name will come in a subsequent FACILITY message */
@@ -187,7 +205,7 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_set_flag(sngisdn_info, FLAG_DELAYED_REL);
sngisdn_info->glare.suId = suId;
sngisdn_info->glare.suInstId = get_unique_suInstId(suId);
sngisdn_info->glare.suInstId = get_unique_suInstId((int8_t) suId);
sngisdn_info->glare.spInstId = spInstId;
sngisdn_info->glare.dChan = dChan;
@@ -223,8 +241,6 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
/* Remote side transmit a CONNECT or CONNECT ACK */
void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -232,6 +248,8 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
/* Function does not require any info from conStEvnt struct for now */
/* CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; */
@@ -260,6 +278,10 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
case FTDM_CHANNEL_STATE_DIALING:
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
break;
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
case FTDM_CHANNEL_STATE_HANGUP:
/* Race condition, we just hung up the call - ignore this message */
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
@@ -274,7 +296,7 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
/* do nothing */
break;
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
/* We just hung up an incoming call right after we sent a CONNECT so ignore this message */
/* Race condition, We just hung up an incoming call right after we sent a CONNECT - ignore this message */
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
@@ -291,8 +313,6 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -306,6 +326,8 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
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");
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing %s (suId:%u suInstId:%u spInstId:%u ces:%d)\n",
@@ -423,8 +445,6 @@ sngisdn_process_cnst_ind_end:
void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -433,6 +453,8 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
DiscEvnt *discEvnt = &sngisdn_event->event.discEvnt;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
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");
@@ -480,7 +502,6 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -489,6 +510,8 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
RelEvnt *relEvnt = &sngisdn_event->event.relEvnt;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing RELEASE/RELEASE COMPLETE (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");
@@ -575,7 +598,6 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_dat_ind (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -583,6 +605,8 @@ void sngisdn_process_dat_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
/* Function does not require any info from infoEvnt struct for now */
/* InfoEvnt *infoEvnt = &sngisdn_event->event.infoEvnt; */
@@ -593,7 +617,6 @@ void sngisdn_process_dat_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_sshl_ind (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -601,6 +624,8 @@ void sngisdn_process_sshl_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
/* Function does not require any info from ssHlEvnt struct for now */
/* SsHlEvnt *ssHlEvnt = &sngisdn_event->event.ssHlEvnt; */
@@ -611,14 +636,15 @@ void sngisdn_process_sshl_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_sshl_cfm (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
/* Function does not require any info from ssHlEvnt struct for now */
/* SsHlEvnt *ssHlEvnt = &sngisdn_event->event.ssHlEvnt; */
@@ -629,7 +655,6 @@ void sngisdn_process_sshl_cfm (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_rmrt_ind (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -637,6 +662,8 @@ void sngisdn_process_rmrt_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
/* Function does not require any info from ssHlEvnt struct for now */
/* RmRtEvnt *rmRtEvnt = &sngisdn_event->event.rmRtEvnt; */
@@ -647,7 +674,6 @@ void sngisdn_process_rmrt_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_rmrt_cfm (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -655,6 +681,8 @@ void sngisdn_process_rmrt_cfm (sngisdn_event_data_t *sngisdn_event)
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
/* Function does not require any info from ssHlEvnt struct for now */
/* RmRtEvnt *rmRtEvnt = &sngisdn_event->event.rmRtEvnt; */
@@ -665,7 +693,6 @@ void sngisdn_process_rmrt_cfm (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -673,6 +700,8 @@ void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
/* Function does not require any info from ssHlEvnt struct for now */
/* StaEvnt *staEvnt = &sngisdn_event->event.staEvnt; */
@@ -683,8 +712,6 @@ void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -695,6 +722,8 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
FacEvnt *facEvnt = &sngisdn_event->event.facEvnt;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing FACILITY IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
switch (ftdmchan->state) {
@@ -736,8 +765,6 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -748,6 +775,8 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
uint8_t call_state = 0;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
if (staEvnt->callSte.eh.pres && staEvnt->callSte.callGlblSte.pres) {
call_state = staEvnt->callSte.callGlblSte.val;
}
@@ -923,6 +952,16 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
break;
}
break;
case 12: /* We received a disconnect indication */
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_TERMINATING:
/* We are already waiting for user app to handle the disconnect, do nothing */
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
break;
}
break;
case 22:
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_UP:
@@ -937,6 +976,18 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
//ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
}
break;
case 25: /* Overlap receiving */
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_COLLECT:
/* do nothing */
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
//ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
}
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
//ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
@@ -951,11 +1002,12 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_srv_ind (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
int16_t dChan = sngisdn_event->dChan;
uint8_t ces = sngisdn_event->ces;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
/* Function does not require any info from ssHlEvnt struct for now */
/*Srv *srvEvnt = &sngisdn_event->event.srvEvnt;*/
@@ -966,11 +1018,12 @@ void sngisdn_process_srv_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
int16_t dChan = sngisdn_event->dChan;
uint8_t ces = sngisdn_event->ces;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
/* Function does not require any info from ssHlEvnt struct for now */
/*Srv *srvEvnt = &sngisdn_event->event.srvEvnt;*/
@@ -981,12 +1034,13 @@ void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
int16_t dChan = sngisdn_event->dChan;
uint8_t ces = sngisdn_event->ces;
uint8_t evntType = sngisdn_event->evntType;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
/* Function does not require any info from ssHlEvnt struct for now */
/*Rst *rstEvnt = &sngisdn_event->event.rstEvnt;*/
@@ -998,12 +1052,13 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
int16_t dChan = sngisdn_event->dChan;
uint8_t ces = sngisdn_event->ces;
uint8_t evntType = sngisdn_event->evntType;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
/* Function does not require any info from ssHlEvnt struct for now */
/*Rst *rstEvnt = &sngisdn_event->event.rstEvnt;*/
@@ -143,6 +143,7 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
signal_data->signalling == SNGISDN_SIGNALING_NET) {
sngisdn_info->ces = CES_MNGMNT;
}
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);
@@ -43,11 +43,12 @@ extern void get_memory_info(void);
void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
uint8_t bchan_no = 0;
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Con Ind on unconfigured cc\n");
ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Con Ind on unconfigured dchan\n");
@@ -103,14 +104,15 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co
void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Con Cfm on unconfigured cc\n");
ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Con Cfm on unconfigured dchan\n");
if (get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) != FTDM_SUCCESS) {
if (get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
return;
@@ -146,14 +148,15 @@ void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, Cn
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)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Cnst Ind on unconfigured cc\n");
ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Cnst Ind on unconfigured dchan\n");
if (get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) != FTDM_SUCCESS) {
if (get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
return;
@@ -196,14 +199,15 @@ void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, C
void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_assert(spInstId != 0, "Received DISCONNECT with invalid id");
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -231,12 +235,13 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D
void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
/* It seems that Trillium has a bug where they sometimes send release twice on a call, so do not crash on these for now */
@@ -264,12 +269,13 @@ void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Re
void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -296,12 +302,13 @@ void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, In
void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -329,12 +336,13 @@ void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, S
void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -361,12 +369,13 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S
}
void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -394,12 +403,13 @@ void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, R
void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -427,12 +437,13 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R
void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -460,12 +471,13 @@ void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, St
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)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -493,12 +505,13 @@ void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Fa
void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
!(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -525,11 +538,12 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St
void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
unsigned i;
sngisdn_span_data_t *signal_data;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_log(FTDM_LOG_INFO, "Received SERVICE IND (dChan:%d ces:%u)\n", dChan, ces);
/* Enqueue the event to each span within the dChan */
@@ -554,11 +568,12 @@ 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)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
unsigned i;
sngisdn_span_data_t *signal_data = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_log(FTDM_LOG_INFO, "Received SERVICE CFM (dChan:%d ces:%u)\n", dChan, ces);
/* Enqueue the event to each span within the dChan */
@@ -582,11 +597,12 @@ void sngisdn_rcv_srv_cfm (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces
void sngisdn_rcv_rst_ind (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
unsigned i;
sngisdn_span_data_t *signal_data = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_log(FTDM_LOG_INFO, "Received RESTART IND (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType);
/* Enqueue the event to each span within the dChan */
@@ -612,11 +628,12 @@ void sngisdn_rcv_rst_ind (int16_t suId, Rst *rstEvnt, 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)
{
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
unsigned i;
sngisdn_span_data_t *signal_data;
sngisdn_event_data_t *sngisdn_event = NULL;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_log(FTDM_LOG_INFO, "Received RESTART CFM (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType);
/* Enqueue the event to each span within the dChan */
@@ -706,7 +723,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
ftdm_span_t *ftdmspan;
sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[status->t.usta.suId];
if (!signal_data) {
ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.suId);
ftdm_log(FTDM_LOG_INFO, "Received q931 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.suId);
return;
}
ftdmspan = signal_data->ftdm_span;
@@ -49,7 +49,7 @@ ftdm_status_t sngisdn_check_free_ids(void);
extern ftdm_sngisdn_data_t g_sngisdn_data;
void get_memory_info(void);
void __inline__ clear_call_data(sngisdn_chan_data_t *sngisdn_info)
FT_DECLARE_INLINE(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;
@@ -66,7 +66,7 @@ void __inline__ clear_call_data(sngisdn_chan_data_t *sngisdn_info)
return;
}
void __inline__ clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
FT_DECLARE_INLINE(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,
@@ -91,7 +91,7 @@ void __inline__ clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
}
uint32_t __inline__ get_unique_suInstId(uint8_t cc_id)
FT_DECLARE_INLINE(uint32_t) get_unique_suInstId(uint8_t cc_id)
{
uint32_t suInstId;
ftdm_mutex_lock(g_sngisdn_data.ccs[cc_id].mutex);
@@ -112,7 +112,7 @@ uint32_t __inline__ get_unique_suInstId(uint8_t cc_id)
return 0;
}
ftdm_status_t __inline__ get_ftdmchan_by_suInstId(uint8_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data)
FT_DECLARE_INLINE(ftdm_status_t) get_ftdmchan_by_suInstId(uint8_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data)
{
ftdm_assert_return(g_sngisdn_data.ccs[cc_id].activation_done, FTDM_FAIL, "Trying to find call on unconfigured CC\n");
@@ -123,7 +123,7 @@ ftdm_status_t __inline__ get_ftdmchan_by_suInstId(uint8_t cc_id, uint32_t suInst
return FTDM_SUCCESS;
}
ftdm_status_t __inline__ get_ftdmchan_by_spInstId(uint8_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data)
FT_DECLARE_INLINE(ftdm_status_t) get_ftdmchan_by_spInstId(uint8_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data)
{
ftdm_assert_return(g_sngisdn_data.ccs[cc_id].activation_done, FTDM_FAIL, "Trying to find call on unconfigured CC\n");
@@ -188,11 +188,11 @@ ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPt
}
if (cdPtyNmb->nmbPlanId.pres == PRSNT_NODEF) {
ftdm->cid_num.plan = cdPtyNmb->nmbPlanId.val;
ftdm->dnis.plan = cdPtyNmb->nmbPlanId.val;
}
if (cdPtyNmb->typeNmb0.pres == PRSNT_NODEF) {
ftdm->cid_num.type = cdPtyNmb->typeNmb0.val;
ftdm->dnis.type = cdPtyNmb->typeNmb0.val;
}
if (cdPtyNmb->nmbDigits.pres == PRSNT_NODEF) {
@@ -424,11 +424,15 @@ void sngisdn_delayed_disconnect(void* p_sngisdn_info)
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
ftdm_mutex_lock(ftdmchan->mutex);
if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) {
if (ftdmchan->caller_data.hangup_cause == IN_CCNORTTODEST || ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending delayed DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n",
signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
sngisdn_snd_disconnect(ftdmchan);
if (ftdmchan->caller_data.hangup_cause == IN_CCNORTTODEST) {
ftdm_channel_t *close_chan = ftdmchan;
ftdm_channel_close(&close_chan);
}
}
ftdm_mutex_unlock(ftdmchan->mutex);
@@ -100,7 +100,7 @@ uint8_t get_bits(uint8_t octet, uint8_t bitLo, uint8_t bitHi)
void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len)
{
int str_len;
int i;
uint32_t i;
uint8_t sapi, cr, ea, tei, ns, nr, pf, p, cmd;
uint8_t frame_format = 0;
@@ -649,7 +649,7 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_start, uint32_t index_end)
{
int k;
uint32_t k;
*str_len += sprintf(&str[*str_len], " [ ");
for(k=index_start; k <= index_end; k++) {
if (k && !(k%32)) {
@@ -85,35 +85,35 @@ int ft_to_sngss7_cfg_all(void)
if (ftmod_ss7_mtp1_gen_config()) {
SS7_CRITICAL("MTP1 General configuration FAILED!\n");
SS7_ASSERT
return 1;
} else {
SS7_INFO("MTP1 General configuration DONE\n");
}
if (ftmod_ss7_mtp2_gen_config()) {
SS7_CRITICAL("MTP2 General configuration FAILED!\n");
SS7_ASSERT
return 1;
} else {
SS7_INFO("MTP2 General configuration DONE\n");
}
if (ftmod_ss7_mtp3_gen_config()) {
SS7_CRITICAL("MTP3 General configuration FAILED!\n");
SS7_ASSERT
return 1;
} else {
SS7_INFO("MTP3 General configuration DONE\n");
}
if (ftmod_ss7_isup_gen_config()) {
SS7_CRITICAL("ISUP General configuration FAILED!\n");
SS7_ASSERT
return 1;
} else {
SS7_INFO("ISUP General configuration DONE\n");
}
if (ftmod_ss7_cc_gen_config()) {
SS7_CRITICAL("CC General configuration FAILED!\n");
SS7_ASSERT
return 1;
} else {
SS7_INFO("CC General configuration DONE\n");
}
@@ -131,7 +131,7 @@ int ft_to_sngss7_cfg_all(void)
/* configure mtp1 */
if (ftmod_ss7_mtp1_psap_config(x)) {
SS7_CRITICAL("MTP1 PSAP %d configuration FAILED!\n", x);
SS7_ASSERT;
return 1;;
} else {
SS7_INFO("MTP1 PSAP %d configuration DONE!\n", x);
}
@@ -139,7 +139,7 @@ int ft_to_sngss7_cfg_all(void)
/* configure mtp2 */
if (ftmod_ss7_mtp2_dlsap_config(x)) {
SS7_CRITICAL("MTP2 DLSAP %d configuration FAILED!\n",x);
SS7_ASSERT;
return 1;;
} else {
SS7_INFO("MTP2 DLSAP %d configuration DONE!\n", x);
}
@@ -147,7 +147,7 @@ int ft_to_sngss7_cfg_all(void)
/* configure mtp3 */
if (ftmod_ss7_mtp3_dlsap_config(x)) {
SS7_CRITICAL("MTP3 DLSAP %d configuration FAILED!\n", x);
SS7_ASSERT;
return 1;;
} else {
SS7_INFO("MTP3 DLSAP %d configuration DONE!\n", x);
}
@@ -166,14 +166,14 @@ int ft_to_sngss7_cfg_all(void)
if (ftmod_ss7_mtp3_nsap_config(x)) {
SS7_CRITICAL("MTP3 NSAP %d configuration FAILED!\n", x);
SS7_ASSERT
return 1;
} else {
SS7_INFO("MTP3 NSAP %d configuration DONE!\n", x);
}
if (ftmod_ss7_isup_nsap_config(x)) {
SS7_CRITICAL("ISUP NSAP %d configuration FAILED!\n", x);
SS7_ASSERT
return 1;
} else {
SS7_INFO("ISUP NSAP %d configuration DONE!\n", x);
}
@@ -192,7 +192,7 @@ int ft_to_sngss7_cfg_all(void)
if (ftmod_ss7_mtp3_linkset_config(x)) {
SS7_CRITICAL("MTP3 LINKSET %d configuration FAILED!\n", x);
SS7_ASSERT
return 1;
} else {
SS7_INFO("MTP3 LINKSET %d configuration DONE!\n", x);
}
@@ -211,7 +211,7 @@ int ft_to_sngss7_cfg_all(void)
if (ftmod_ss7_mtp3_route_config(x)) {
SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x);
SS7_ASSERT
return 1;
} else {
SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x);
}
@@ -227,7 +227,7 @@ int ft_to_sngss7_cfg_all(void)
if (ftmod_ss7_mtp3_route_config(0)) {
SS7_CRITICAL("MTP3 ROUTE 0 configuration FAILED!\n");
SS7_ASSERT
return 1;
} else {
SS7_INFO("MTP3 ROUTE 0 configuration DONE!\n");
}
@@ -244,14 +244,14 @@ int ft_to_sngss7_cfg_all(void)
if (ftmod_ss7_isup_isap_config(x)) {
SS7_CRITICAL("ISUP ISAP %d configuration FAILED!\n", x);
SS7_ASSERT
return 1;
} else {
SS7_INFO("ISUP ISAP %d configuration DONE!\n", x);
}
if (ftmod_ss7_cc_isap_config(x)) {
SS7_CRITICAL("CC ISAP %d configuration FAILED!\n", x);
SS7_ASSERT
return 1;
} else {
SS7_INFO("CC ISAP %d configuration DONE!\n", x);
}
@@ -270,9 +270,11 @@ int ft_to_sngss7_cfg_all(void)
if (ftmod_ss7_isup_intf_config(x)) {
SS7_CRITICAL("ISUP INTF %d configuration FAILED!\n", x);
SS7_ASSERT
return 1;
} else {
SS7_INFO("ISUP INTF %d configuration DONE!\n", x);
/* set the interface to paused */
sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[x], SNGSS7_PAUSED);
}
/* set the CONFIGURED flag */
@@ -289,7 +291,7 @@ int ft_to_sngss7_cfg_all(void)
if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == 0) {
if (ftmod_ss7_isup_ckt_config(x)) {
SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x);
SS7_ASSERT
return 1;
} else {
SS7_INFO("ISUP CKT %d configuration DONE!\n", x);
}
@@ -1018,8 +1020,8 @@ int ftmod_ss7_mtp3_route_config(int id)
cfg.t.cfg.s.snRout.slsRange = LSN_ANSI_5BIT_SLS_RANGE; /* max value of SLS for this DPC */
}
cfg.t.cfg.s.snRout.lsetSel = 0x1; /* linkset selection bit in SLS for STP */
cfg.t.cfg.s.snRout.multiMsgPrior = FALSE; /* TRUE if multiple cong priorities of messages */
cfg.t.cfg.s.snRout.rctReq = TRUE; /* route set congestion test required or not */
cfg.t.cfg.s.snRout.multiMsgPrior = TRUE; /* TRUE if multiple cong priorities of messages */
cfg.t.cfg.s.snRout.rctReq = TRUE; /* route set congestion test required or not */
cfg.t.cfg.s.snRout.slsLnk = FALSE;
#ifdef LSNV2
# if (SS7_NTT || defined(TDS_ROLL_UPGRADE_SUPPORT))
@@ -240,9 +240,7 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha
/**********************************************************************/
} else if (!strcasecmp(argv[c], "mem")) {
/**********************************************************************/
/*uint32_t availMem;*/
/*sng_sta_mem(&availMem);*/
sng_isup_reg_info_show();
/**********************************************************************/
} else if (!strcasecmp(argv[c], "stats")) {
/**********************************************************************/
@@ -618,8 +616,8 @@ static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream)
stream->write_function(stream, "Sangoma SS7 CLI usuage:\n\n");
stream->write_function(stream, "Ftmod_sangoma_ss7 general control:\n");
stream->write_function(stream, "ftdm ss7 set ftace X Y\n");
stream->write_function(stream, "ftdm ss7 set mtace X Y\n");
stream->write_function(stream, "ftdm ss7 set ftrace X Y\n");
stream->write_function(stream, "ftdm ss7 set mtrace X Y\n");
stream->write_function(stream, "\n");
stream->write_function(stream, "Ftmod_sangoma_ss7 information:\n");
stream->write_function(stream, "ftdm ss7 show status link X\n");
@@ -1066,7 +1064,7 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span,
/* grab the signaling_status */
ftdm_channel_get_sig_status(ftdmchan, &sigstatus);
stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|sig_status=%s|state=%s|",
stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|sig_status=%4s|state=%s|",
ckt->span,
ckt->chan,
ckt->cic,
@@ -1156,7 +1154,12 @@ static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int c
/* check if there is a pending state change|give it a bit to clear */
if (check_for_state_change(ftdmchan)) {
SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic);
/* check if we need to die */
SS7_ASSERT;
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
/* move to the next channel */
continue;
} else {
/* throw the ckt block flag */
sngss7_set_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX);
@@ -1217,7 +1220,12 @@ static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int c
/* check if there is a pending state change|give it a bit to clear */
if (check_for_state_change(ftdmchan)) {
SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic);
/* check if we need to die */
SS7_ASSERT;
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
/* move to the next channel */
continue;
} else {
/* throw the ckt block flag */
sngss7_set_flag(ss7_info, FLAG_CKT_MN_UNBLK_TX);
@@ -1273,13 +1281,17 @@ static ftdm_status_t handle_status_link(ftdm_stream_handle_t *stream, char *name
(sta.t.ssta.s.snDLSAP.remBlkd) ? "Y":"N",
(sta.t.ssta.s.snDLSAP.locInhbt) ? "Y":"N",
(sta.t.ssta.s.snDLSAP.rmtInhbt) ? "Y":"N");
break;
goto success;
}
/* move to the next link */
x++;
} /* while (id != 0) */
stream->write_function(stream, "Failed to find link=\"%s\"\n", name);
success:
return FTDM_SUCCESS;
}
@@ -1305,13 +1317,17 @@ static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *n
name,
DECODE_LSN_LINKSET_STATUS(sta.t.ssta.s.snLnkSet.state),
sta.t.ssta.s.snLnkSet.nmbActLnks);
break;
goto success;
}
/* move to the next linkset */
x++;
} /* while (id != 0) */
stream->write_function(stream, "Failed to find link=\"%s\"\n", name);
success:
return FTDM_SUCCESS;
}
@@ -1334,13 +1350,16 @@ static ftdm_status_t handle_set_inhibit(ftdm_stream_handle_t *stream, char *name
/* print the new status of the link */
handle_status_link(stream, &name[0]);
break;
goto success;
}
/* move to the next linkset */
x++;
} /* while (id != 0) */
stream->write_function(stream, "Failed to find link=\"%s\"\n", name);
success:
return FTDM_SUCCESS;
}
@@ -1363,13 +1382,16 @@ static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *na
/* print the new status of the link */
handle_status_link(stream, &name[0]);
break;
goto success;
}
/* move to the next linkset */
x++;
} /* while (id != 0) */
stream->write_function(stream, "Failed to find link=\"%s\"\n", name);
success:
return FTDM_SUCCESS;
}
@@ -1432,6 +1454,10 @@ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int c
/* go the next circuit */
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
/* print the status of channels */
handle_show_status(stream, span, chan, verbose);
return FTDM_SUCCESS;
@@ -1466,7 +1492,12 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c
/* check if there is a pending state change|give it a bit to clear */
if (check_for_state_change(ftdmchan)) {
SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
/* check if we need to die */
SS7_ASSERT;
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
/* move to the next channel */
continue;
} else {
/* throw the grp reset flag */
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX);
@@ -1492,6 +1523,24 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
x=1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) {
sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
ftdmchan = sngss7_info->ftdmchan;
sngss7_span = ftdmchan->span->mod_data;
if ((ftdmchan->physical_span_id == span) &&
((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) {
handle_show_status(stream, span, chan, verbose);
}
} /* if ( cic == voice) */
/* go the next circuit */
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
return FTDM_SUCCESS;
}
@@ -1572,6 +1621,25 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c
/* send the circuit group block */
ft_to_sngss7_cgb(main_chan);
x=1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) {
sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
ftdmchan = sngss7_info->ftdmchan;
sngss7_span = ftdmchan->span->mod_data;
if ((ftdmchan->physical_span_id == span) &&
((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) {
handle_show_status(stream, span, chan, verbose);
}
} /* if ( cic == voice) */
/* go the next circuit */
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
return FTDM_SUCCESS;
@@ -1653,6 +1721,25 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c
/* send the circuit group block */
ft_to_sngss7_cgu(main_chan);
x=1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) {
sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
ftdmchan = sngss7_info->ftdmchan;
sngss7_span = ftdmchan->span->mod_data;
if ((ftdmchan->physical_span_id == span) &&
((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) {
handle_show_status(stream, span, chan, verbose);
}
} /* if ( cic == voice) */
/* go the next circuit */
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
return FTDM_SUCCESS;
@@ -75,7 +75,7 @@ int ft_to_sngss7_activate_all(void)
if (ftmod_ss7_enable_isap(x)) {
SS7_CRITICAL("ISAP %d Enable: NOT OK\n", x);
SS7_ASSERT;
return 1;
} else {
SS7_INFO("ISAP %d Enable: OK\n", x);
}
@@ -94,7 +94,7 @@ int ft_to_sngss7_activate_all(void)
if (ftmod_ss7_enable_nsap(x)) {
SS7_CRITICAL("NSAP %d Enable: NOT OK\n", x);
SS7_ASSERT;
return 1;
} else {
SS7_INFO("NSAP %d Enable: OK\n", x);
}
@@ -113,7 +113,7 @@ int ft_to_sngss7_activate_all(void)
if (ftmod_ss7_enable_mtpLinkSet(x)) {
SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
SS7_ASSERT;
return 1;
} else {
SS7_INFO("LinkSet \"%s\" Enable: OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
}
@@ -51,6 +51,8 @@ ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt);
ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
@@ -73,6 +75,7 @@ ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t ci
ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
@@ -208,10 +211,28 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* add any special variables for the dialplan */
sprintf(nadi, "%d", siConEvnt->cgPtyNum.natAddrInd.val);
ftdm_channel_add_var(ftdmchan, "ss7_nadi", nadi);
ftdm_channel_add_var(ftdmchan, "ss7_clg_nadi", nadi);
/* set the state of the channel to collecting...the rest is done by the chan monitor */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
sprintf(nadi, "%d", siConEvnt->cdPtyNum.natAddrInd.val);
ftdm_channel_add_var(ftdmchan, "ss7_cld_nadi", nadi);
/* check if a COT test is requested */
if ((siConEvnt->natConInd.eh.pres) &&
(siConEvnt->natConInd.contChkInd.pres) &&
(siConEvnt->natConInd.contChkInd.val)) {
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Found COT Request\n", sngss7_info->circuit->cic);
/* tell the core to loop the channel */
ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_LOOP, NULL);
/* move to in loop state */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP);
} else {
/* set the state of the channel to collecting...the rest is done by the chan monitor */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
}
} /* if (channel is usable */
@@ -250,6 +271,9 @@ handle_glare:
default: /* should not have gotten an IAM while in this state */
SS7_ERROR_CHAN(ftdmchan, "Got IAM on channel in invalid state(%s)...reset!\n", ftdm_channel_state2str (ftdmchan->state));
/* reset the cic */
sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
/* move the state of the channel to RESTART to force a reset */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
@@ -286,6 +310,7 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/**************************************************************************/
case (ADDRCMPLT):
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ACM\n", sngss7_info->circuit->cic);
switch (ftdmchan->state) {
/**********************************************************************/
case FTDM_CHANNEL_STATE_DIALING:
@@ -294,16 +319,37 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* need to grab the sp instance id */
sngss7_info->spInstId = spInstId;
/* go to PROGRESS */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
break;
if ((siCnStEvnt->optBckCalInd.eh.pres) &&
(siCnStEvnt->optBckCalInd.inbndInfoInd.pres)) {
if (siCnStEvnt->optBckCalInd.inbndInfoInd.val) {
/* go to PROGRESS_MEDIA */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
} else {
/* go to PROGRESS */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
} /* if (inband) */
} else {
/* go to PROGRESS_MEDIA */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
}
break;
/**********************************************************************/
default: /* incorrect state...reset the CIC */
SS7_ERROR_CHAN(ftdmchan, "RX ACM in invalid state :%s...resetting CIC\n",
ftdm_channel_state2str (ftdmchan->state));
/* reset the cic */
sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
/* go to RESTART */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
break;
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
/**********************************************************************/
} /* switch (ftdmchan->state) */
break;
/**************************************************************************/
case (MODIFY):
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY\n", sngss7_info->circuit->cic);
@@ -335,6 +381,34 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/**************************************************************************/
case (SUBSADDR):
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SAM\n", sngss7_info->circuit->cic);
/* check the channel state */
switch (ftdmchan->state) {
/**********************************************************************/
case (FTDM_CHANNEL_STATE_COLLECT):
/* confirm that the event contains the subsquent number field */
if (siCnStEvnt->subNum.eh.pres && siCnStEvnt->subNum.addrSig.pres) {
/* add the digits to the ftdm channel variable */
append_tknStr_from_sngss7(siCnStEvnt->subNum.addrSig,
ftdmchan->caller_data.dnis.digits,
siCnStEvnt->subNum.oddEven);
} else {
SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in SAM!%s\n", " ");
}
/* go to idle so that collect state is processed again */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
break;
/**********************************************************************/
default:
SS7_ERROR_CHAN(ftdmchan, "RX SAM in invalid state :%s...ignoring\n",
ftdm_channel_state2str (ftdmchan->state));
break;
/**********************************************************************/
} /* switch (ftdmchan->state) */
break;
/**************************************************************************/
case (EXIT):
@@ -524,7 +598,7 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* this is a remote hangup request */
sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL);
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
/* move the state of the channel to CANCEL to end the call */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
@@ -539,7 +613,7 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
if (siRelEvnt->causeDgn.causeVal.pres) {
ftdmchan->caller_data.hangup_cause = siRelEvnt->causeDgn.causeVal.val;
} else {
SS7_ERROR("REL does not have a cause code!\n");
SS7_ERROR("REL does not have a cause ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);code!\n");
ftdmchan->caller_data.hangup_cause = 0;
}
@@ -551,6 +625,23 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
break;
/**************************************************************************/
case FTDM_CHANNEL_STATE_IN_LOOP:
/* inform the core to unloop the channel*/
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
/* since we need to acknowledge the hang up set the flag for remote release */
sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL);
/* go to hangup complete to send the RLC */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
/* save the call info for the RLC */
sngss7_info->suInstId = get_unique_id();
sngss7_info->spInstId = spInstId;
break;
/**************************************************************************/
default:
/* throw the reset flag */
@@ -729,6 +820,60 @@ ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t cir
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Call-Suspend msg\n", sngss7_info->circuit->cic);
/* unlock the channel */
ftdm_mutex_unlock(ftdmchan->mutex);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Call-Resume msg\n", sngss7_info->circuit->cic);
/* unlock the channel */
ftdm_mutex_unlock(ftdmchan->mutex);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
{
@@ -757,7 +902,7 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
break;
/**************************************************************************/
case SIT_STA_CONTCHK: /* continuity check */
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx COT start\n", sngss7_info->circuit->cic);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CCR start\n", sngss7_info->circuit->cic);
handle_cot_start(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
break;
/**************************************************************************/
@@ -767,7 +912,7 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
break;
/**************************************************************************/
case SIT_STA_STPCONTIN: /* stop continuity */
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx COT stop\n", sngss7_info->circuit->cic);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CCR stop\n", sngss7_info->circuit->cic);
handle_cot_stop(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
break;
/**************************************************************************/
@@ -928,7 +1073,7 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/**************************************************************************/
case SIT_STA_OVERLOAD: /* Overload */
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Overload\n", sngss7_info->circuit->cic);
SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
handle_olm_msg(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
break;
/**************************************************************************/
case SIT_STA_LMCGBREQ: /* when LM requests ckt grp blocking */
@@ -1029,6 +1174,9 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui
/* extract the affected infId from the circuit structure */
infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId;
/* set the interface to paused */
sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED);
/* go through all the circuits now and find any other circuits on this infId */
i = 1;
@@ -1050,6 +1198,7 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui
/* check if the circuit is fully started */
if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_IN_THREAD)) {
SS7_DEBUG_CHAN(ftdmchan, "Rx PAUSE%s\n", "");
/* set the pause flag on the channel */
sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED);
}
@@ -1081,6 +1230,9 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu
/* extract the affect infId from the circuit structure */
infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId;
/* set the interface to resumed */
sngss7_clear_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED);
/* go through all the circuits now and find any other circuits on this infId */
i = 1;
while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) {
@@ -1101,6 +1253,8 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu
/* only resume if we are paused */
if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) {
SS7_DEBUG_CHAN(ftdmchan, "Rx RESUME%s\n", "");
/* set the resume flag on the channel */
sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME);
@@ -1143,7 +1297,7 @@ ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t ci
/* open the channel if it is not open */
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
SS7_ERROR("Failed to open CIC %d for COT test!\n", sngss7_info->circuit->cic);
SS7_ERROR("Failed to open CIC %d for CCR test!\n", sngss7_info->circuit->cic);
/* KONRAD FIX ME */
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
@@ -1156,15 +1310,6 @@ ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t ci
/* switch to the IN_LOOP state */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP);
/* store the sngss7 ids */
if (suInstId == 0) {
sngss7_info->suInstId = get_unique_id();
} else {
sngss7_info->suInstId = suInstId;
}
sngss7_info->spInstId = spInstId;
sngss7_info->globalFlg = globalFlg;
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
@@ -1208,6 +1353,38 @@ ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit,
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
switch (ftdmchan->state) {
/**************************************************************************/
case (FTDM_CHANNEL_STATE_IN_LOOP):
/* tell the core to stop looping the channel */
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
/* exit out of the LOOP state and go to collect */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
break;
/**************************************************************************/
default:
/* exit out of the LOOP state to the last state */
ftdm_set_state_locked(ftdmchan, ftdmchan->last_state);
break;
/**************************************************************************/
} /* switch (ftdmchan->state) */
if ( (siStaEvnt->contInd.eh.pres > 0) && (siStaEvnt->contInd.contInd.pres > 0)) {
SS7_INFO("Continuity Test result for CIC = %d (span %d, chan %d) is: \"%s\"\n",
g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic,
@@ -1218,13 +1395,13 @@ ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit,
SS7_ERROR("Recieved Continuity report containing no results!\n");
}
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
}
/******************************************************************************/
/******************************************************************************/
ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
{
@@ -1493,7 +1670,7 @@ ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP);
/* go to DOWN */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
/*ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);*/
break;
/**********************************************************************/
@@ -1527,7 +1704,7 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
ftdm_channel_t *ftdmchan = NULL;
sngss7_span_data_t *sngss7_span = NULL;
int range;
int x;
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
@@ -1544,51 +1721,12 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
return FTDM_FAIL;
}
/* loop over the cics starting from circuit until range+1 */
for (x = circuit; x < (circuit + range + 1); x++) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != VOICE) continue;
/* grab the circuit in question */
if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x);
break;
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
/* fill in the span structure for this circuit */
sngss7_span = ftdmchan->span->mod_data;
sngss7_span->rx_grs.circuit = circuit;
sngss7_span->rx_grs.range = range;
/* fill in the span structure for this circuit */
sngss7_span = ftdmchan->span->mod_data;
sngss7_span->rx_grs.circuit = circuit;
sngss7_span->rx_grs.range = range;
SS7_INFO_CHAN(ftdmchan, "Rx GRS (%d:%d)\n",
g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic,
(g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range));
/* flag the channel as having received a reset */
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX);
switch (ftdmchan->state) {
/**************************************************************************/
case FTDM_CHANNEL_STATE_RESTART:
/* go to idle so that we can redo the restart state*/
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
break;
/**************************************************************************/
default:
/* set the state of the channel to restart...the rest is done by the chan monitor */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
/**************************************************************************/
}
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
}
/* the reset will be started in the main thread by "check_if_rx_grs_started" */
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
@@ -1599,10 +1737,16 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_span_data_t *sngss7_span = NULL;
int range;
int x;
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
/* extract the range value from the event structure */
if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) {
@@ -1613,70 +1757,20 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
return FTDM_FAIL;
}
/* go through all the circuits in the range */
for ( x = circuit; x < (circuit + range + 1); x++) {
/* fill in the span structure for this circuit */
sngss7_span = ftdmchan->span->mod_data;
sngss7_span->rx_gra.circuit = circuit;
sngss7_span->rx_gra.range = range;
/* grab the circuit in question */
if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
break;
}
/* check if there is a cause value in the GRA */
if ((siStaEvnt != NULL) &&
(siStaEvnt->causeDgn.eh.pres == PRSNT_NODEF) &&
(siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) {
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
SS7_INFO_CHAN(ftdmchan, "Rx GRA (%d:%d)\n",
g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic,
(g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range));
sngss7_span->rx_gra.cause = siStaEvnt->causeDgn.causeVal.val;
}
switch (ftdmchan->state) {
/**********************************************************************/
case FTDM_CHANNEL_STATE_RESTART:
/* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
/* go to DOWN */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
break;
/**********************************************************************/
case FTDM_CHANNEL_STATE_DOWN:
/* do nothing, just drop the message */
SS7_DEBUG("Receveived GRA in down state, dropping\n");
break;
/**********************************************************************/
case FTDM_CHANNEL_STATE_TERMINATING:
case FTDM_CHANNEL_STATE_HANGUP:
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
/* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
break;
/**********************************************************************/
default:
/* ITU Q764-2.9.5.1.c -> release the circuit */
if ((siStaEvnt != NULL) &&
(siStaEvnt->causeDgn.eh.pres ==PRSNT_NODEF) &&
(siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) {
ftdmchan->caller_data.hangup_cause = siStaEvnt->causeDgn.causeVal.val;
} else {
ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */
}
/* go to terminating to hang up the call */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
break;
/**********************************************************************/
}
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
} /* for (( x = 0; x < (circuit + range); x++) */
/* the reset will be started in the main thread by "check_if_rx_gra_started" */
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
@@ -1759,8 +1853,10 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = NULL;
ftdm_channel_t *ftdmchan = NULL;
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@@ -1769,6 +1865,15 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
return FTDM_FAIL;
}
/* check if we just sent a GRS request...*/
sngss7_span = ftdmchan->span->mod_data;
if (sngss7_span->tx_grs.circuit > 0) {
/* we need to put all circuits on this UCIC */
sngss7_span->ucic.circuit = sngss7_span->tx_grs.circuit;
sngss7_span->ucic.range = sngss7_span->tx_grs.range;
goto done;
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
@@ -1780,7 +1885,7 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
done:
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
}
@@ -2057,6 +2162,30 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
/* handle overload */
SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]Rx Overload\n", sngss7_info->circuit->cic);
sng_isup_reg_info_show();
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
}
/******************************************************************************/
/* For Emacs:
* Local Variables:
@@ -52,7 +52,9 @@ void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiIn
void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt);
void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
void sngss7_ssp_sta_cfm(uint32_t infId);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
@@ -442,7 +444,127 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint
}
/******************************************************************************/
void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_event_data_t *sngss7_event = NULL;
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return;
}
/* initalize the sngss7_event */
sngss7_event = ftdm_malloc(sizeof(*sngss7_event));
if (sngss7_event == NULL) {
SS7_ERROR("Failed to allocate memory for sngss7_event!\n");
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return;
}
memset(sngss7_event, 0x0, sizeof(*sngss7_event));
/* fill in the sngss7_event struct */
sngss7_event->spInstId = spInstId;
sngss7_event->suInstId = suInstId;
sngss7_event->circuit = circuit;
sngss7_event->event_id = SNGSS7_SUSP_IND_EVENT;
if (siSuspEvnt != NULL) {
memcpy(&sngss7_event->event.siSuspEvnt, siSuspEvnt, sizeof(*siSuspEvnt));
}
/* enqueue this event */
ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
}
/******************************************************************************/
void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_event_data_t *sngss7_event = NULL;
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return;
}
/* initalize the sngss7_event */
sngss7_event = ftdm_malloc(sizeof(*sngss7_event));
if (sngss7_event == NULL) {
SS7_ERROR("Failed to allocate memory for sngss7_event!\n");
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return;
}
memset(sngss7_event, 0x0, sizeof(*sngss7_event));
/* fill in the sngss7_event struct */
sngss7_event->spInstId = spInstId;
sngss7_event->suInstId = suInstId;
sngss7_event->circuit = circuit;
sngss7_event->event_id = SNGSS7_RESM_IND_EVENT;
if (siResmEvnt != NULL) {
memcpy(&sngss7_event->event.siResmEvnt, siResmEvnt, sizeof(*siResmEvnt));
}
/* enqueue this event */
ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
}
/******************************************************************************/
void sngss7_ssp_sta_cfm(uint32_t infId)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
#if 0
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_event_data_t *sngss7_event = NULL;
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return;
}
/* initalize the sngss7_event */
sngss7_event = ftdm_malloc(sizeof(*sngss7_event));
if (sngss7_event == NULL) {
SS7_ERROR("Failed to allocate memory for sngss7_event!\n");
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return;
}
memset(sngss7_event, 0x0, sizeof(*sngss7_event));
/* fill in the sngss7_event struct */
sngss7_event->spInstId = spInstId;
sngss7_event->suInstId = suInstId;
sngss7_event->circuit = circuit;
sngss7_event->event_id = SNGSS7_RESM_IND_EVENT;
if (siSuspEvnt != NULL) {
memcpy(&sngss7_event->event.siResmEvnt, siResmEvnt, sizeof(*siResmEvnt));
}
/* enqueue this event */
ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event);
#endif
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
}
/******************************************************************************/
/* For Emacs:
* Local Variables:
@@ -46,7 +46,7 @@ ftdm_sngss7_data_t g_ftdm_sngss7_data;
/* PROTOTYPES *****************************************************************/
static void *ftdm_sangoma_ss7_run (ftdm_thread_t * me, void *obj);
static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan);
void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan);
static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event);
static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span);
@@ -79,7 +79,7 @@ ftdm_state_map_t sangoma_ss7_state_map = {
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_IDLE, FTDM_END},
{FTDM_CHANNEL_STATE_RESTART, FTDM_END}
{FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_COLLECT, FTDM_END}
},
{
ZSD_INBOUND,
@@ -93,14 +93,16 @@ ftdm_state_map_t sangoma_ss7_state_map = {
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_IN_LOOP, FTDM_END},
{FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_DOWN,
FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_COLLECT, FTDM_END},
{FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_RING, FTDM_END}
FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_RING,
FTDM_CHANNEL_STATE_IDLE, FTDM_END}
},
{
ZSD_INBOUND,
@@ -208,7 +210,7 @@ ftdm_state_map_t sangoma_ss7_state_map = {
{FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_TERMINATING,
FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS,
FTDM_CHANNEL_STATE_UP, FTDM_END}
FTDM_CHANNEL_STATE_PROGRESS_MEDIA ,FTDM_CHANNEL_STATE_UP, FTDM_END}
},
{
ZSD_OUTBOUND,
@@ -342,12 +344,26 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
/**********************************************************************/
} /* switch ((ftdm_interrupt_wait(ftdm_sangoma_ss7_int, 100))) */
/* check if there is a GRA to proccess on the span */
if (sngss7_span->rx_gra.range > 0) {
check_if_rx_gra_started(ftdmspan);
} /* if (sngss7->span->rx_gra.range > 0) */
/* check if there is a GRS being processed on the span */
if (sngss7_span->rx_grs.range > 0) {
/* check if the rx_grs has started */
check_if_rx_grs_started(ftdmspan);
/* check if the rx_grs has cleared */
check_if_rx_grs_processed(ftdmspan);
} /* if (sngss7_span->rx_grs.range > 0) */
/* check if there is a UCIC to be processed on the span */
if (sngss7_span->ucic.range > 0) {
/* process the span wide UCIC */
process_span_ucic(ftdmspan);
} /* if (sngss7_span->ucic.range > 0) */
/* check each channel on the span to see if there is an un-procressed SUS/RES flag */
check_for_res_sus_flag(ftdmspan);
} /* master while loop */
@@ -434,6 +450,17 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
handle_sta_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->globalFlg, sngss7_event->evntType, &sngss7_event->event.siStaEvnt);
break;
/**************************************************************************/
case (SNGSS7_SUSP_IND_EVENT):
handle_susp_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siSuspEvnt);
break;
/**************************************************************************/
case (SNGSS7_RESM_IND_EVENT):
handle_resm_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siResmEvnt);
break;
/**************************************************************************/
case (SNGSS7_SSP_STA_CFM_EVENT):
break;
/**************************************************************************/
default:
SS7_ERROR("Unknown Event Id!\n");
break;
@@ -452,9 +479,10 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
}
/******************************************************************************/
static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
{
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
sng_isup_inf_t *isup_intf = NULL;
int i = 0;
ftdm_sigmsg_t sigev;
@@ -500,29 +528,32 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
} else {
SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n",
i,
g_ftdm_sngss7_data.min_digits,
ftdmchan->caller_data.dnis.digits);
/* start ISUP t35 */
if (ftdm_sched_timer (sngss7_info->t35.sched,
"t35",
sngss7_info->t35.beat,
sngss7_info->t35.callback,
&sngss7_info->t35,
&sngss7_info->t35.hb_timer_id)) {
SS7_ERROR ("Unable to schedule timer, hanging up call!\n");
ftdmchan->caller_data.hangup_cause = 41;
/* set the flag to indicate this hangup is started from the local side */
sngss7_set_flag (sngss7_info, FLAG_LOCAL_REL);
/* end the call */
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
} /* if (ftdm_sched_timer(sngss7_info->t35.sched, */
/* if we are coming from idle state then we have already been here once before */
if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) {
SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n",
i,
g_ftdm_sngss7_data.min_digits,
ftdmchan->caller_data.dnis.digits);
/* start ISUP t35 */
if (ftdm_sched_timer (sngss7_info->t35.sched,
"t35",
sngss7_info->t35.beat,
sngss7_info->t35.callback,
&sngss7_info->t35,
&sngss7_info->t35.hb_timer_id)) {
SS7_ERROR ("Unable to schedule timer, hanging up call!\n");
ftdmchan->caller_data.hangup_cause = 41;
/* set the flag to indicate this hangup is started from the local side */
sngss7_set_flag (sngss7_info, FLAG_LOCAL_REL);
/* end the call */
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
} /* if (ftdm_sched_timer(sngss7_info->t35.sched, */
} /* if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) */
} /* checking ST/#digits */
break;
@@ -575,15 +606,16 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
}
/*check if the channel is inbound or outbound */
if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
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_PROGRESS;
ftdm_span_send_signal (ftdmchan->span, &sigev);
/* move to progress media */
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
} else {
/* inbound call so we need to send out ACM */
ft_to_sngss7_acm (ftdmchan);
ft_to_sngss7_acm(ftdmchan);
}
break;
@@ -595,6 +627,13 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
break;
}
if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
/* inform the user there is media avai */
sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
ftdm_span_send_signal (ftdmchan->span, &sigev);
}
/* nothing to do at this time */
break;
/**************************************************************************/
@@ -727,14 +766,19 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/**************************************************************************/
case FTDM_CHANNEL_STATE_DOWN: /*the call is finished and removed */
if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
break;
}
/* check if there is a reset response that needs to be sent */
if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) {
/* send a RSC-RLC */
ft_to_sngss7_rsca (ftdmchan);
/* clear the reset flag */
sngss7_clear_flag (sngss7_info, FLAG_RESET_RX);
}
clear_rx_rsc_flags(sngss7_info);
} /* if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) */
/* check if there was a GRS that needs a GRA */
if ((sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) &&
@@ -750,33 +794,26 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
ft_to_sngss7_gra(ftdmchan);
/* clean out the spans GRS structure */
sngss7_span_data_t *span = ftdmchan->span->mod_data;
span->rx_grs.circuit = 0;
span->rx_grs.range = 0;
clear_rx_grs_data(sngss7_info);
}
/* clear the grp reset flag */
sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX);
sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_DN);
sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
clear_rx_grs_flags(sngss7_info);
}/* if ( sngss7_test_flag ( sngss7_info, FLAG_GRP_RESET_RX ) ) */
/* check if we got the reset response */
if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX_RSP)) {
/* clear the reset flag */
sngss7_clear_flag(sngss7_info, FLAG_RESET_TX_RSP);
sngss7_clear_flag(sngss7_info, FLAG_RESET_SENT);
sngss7_clear_flag(sngss7_info, FLAG_RESET_TX);
}
clear_tx_rsc_flags(sngss7_info);
} /* if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX_RSP)) */
if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) {
/* clear the reset flag */
sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX);
sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_BASE);
sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_SENT);
}
clear_tx_grs_flags(sngss7_info);
/* clean out the spans GRA structure */
clear_rx_gra_data(sngss7_info);
} /* if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) */
/* check if we came from reset (aka we just processed a reset) */
if ((ftdmchan->last_state == FTDM_CHANNEL_STATE_RESTART) ||
@@ -807,7 +844,6 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
} /* if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) */
} /* if !blocked */
} else {
SS7_DEBUG_CHAN(ftdmchan,"Reset flags present (0x%X)\n", sngss7_info->flags);
/* there is still another reset pending so go back to reset*/
@@ -868,6 +904,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/* set the unblk flag */
sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK);
/* clear the block flag */
sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
/* process the flag */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
/* break out of the processing for now */
@@ -930,6 +971,14 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
ftdm_set_state_locked (ftdmchan, ftdmchan->last_state);
break;
/******************************************************************/
case (FTDM_CHANNEL_STATE_IN_LOOP):
/* we screwed up in a COT/CCR, remove the loop */
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
/* go to down */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
break;
/******************************************************************/
default:
/* KONRAD: find out what the cause code should be */
ftdmchan->caller_data.hangup_cause = 41;
@@ -965,6 +1014,7 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/**********************************************************************/
if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) {
SS7_DEBUG_CHAN(ftdmchan, "Processing RESUME%s\n", "");
/* clear the RESUME flag */
sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME);
@@ -990,6 +1040,7 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
} /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) */
if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) {
SS7_DEBUG_CHAN(ftdmchan, "Processing PAUSE%s\n", "");
/* bring the sig status down */
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
@@ -1100,14 +1151,12 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
ftdm_span_send_signal (ftdmchan->span, &sigev);
/* remove any reset flags */
sngss7_clear_flag (sngss7_info, FLAG_GRP_RESET_TX_RSP);
sngss7_clear_flag (sngss7_info, FLAG_GRP_RESET_TX);
sngss7_clear_flag (sngss7_info, FLAG_RESET_TX_RSP);
sngss7_clear_flag (sngss7_info, FLAG_RESET_TX);
sngss7_clear_flag (sngss7_info, FLAG_RESET_SENT);
sngss7_clear_flag (sngss7_info, FLAG_GRP_RESET_RX);
sngss7_clear_flag (sngss7_info, FLAG_RESET_RX);
sngss7_clear_flag (sngss7_info, FLAG_GRP_RESET_BASE);
clear_rx_grs_flags(sngss7_info);
clear_rx_grs_data(sngss7_info);
clear_tx_grs_flags(sngss7_info);
clear_tx_grs_data(sngss7_info);
clear_rx_rsc_flags(sngss7_info);
clear_tx_rsc_flags(sngss7_info);
/* bring the channel down */
goto suspend_goto_last;
@@ -1116,8 +1165,14 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
if (sngss7_test_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK)) {
SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_UNBLK flag %s\n", "");;
/* throw the channel into reset from our side since it is already in reset from the remote side */
sngss7_set_flag (sngss7_info, FLAG_RESET_TX);
/* remove the UCIC block flag */
sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
/* remove the UCIC unblock flag */
sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK);
/* throw the channel into reset to sync states */
sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
/* bring the channel into restart again */
goto suspend_goto_restart;
@@ -1131,11 +1186,15 @@ suspend_goto_restart:
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
/**************************************************************************/
/**************************************************************************/
case FTDM_CHANNEL_STATE_IN_LOOP: /* COT test */
/* send the lpa */
ft_to_sngss7_lpa (ftdmchan);
isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
if (sngss7_test_options(isup_intf, SNGSS7_LPA_FOR_COT)) {
/* send the lpa */
ft_to_sngss7_lpa (ftdmchan);
}
break;
/**************************************************************************/
@@ -1165,9 +1224,10 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call)
/* check if there is a pending state change, give it a bit to clear */
if (check_for_state_change(ftdmchan)) {
SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
ftdm_mutex_unlock(ftdmchan->mutex);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
/* check if we need to die */
SS7_ASSERT;
/* end the request */
goto outgoing_fail;
};
/* check if the channel sig state is UP */
@@ -1278,6 +1338,7 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span)
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = NULL;
sng_isup_inf_t *sngss7_intf = NULL;
int x;
@@ -1290,12 +1351,22 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span)
if (ftdmchan->call_data == NULL) continue;
sngss7_info = ftdmchan->call_data;
sngss7_span = ftdmchan->span->mod_data;
sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
/* throw the pause flag */
sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED);
/* check if the interface is paused or resumed */
if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) {
/* throw the pause flag */
sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME);
sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED);
} else {
/* throw the pause flag */
sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED);
sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME);
}
#if 0
/* throw the grp reset flag */
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX);
@@ -1444,7 +1515,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init)
sngss7_id = 0;
cmbLinkSetId = 1;
cmbLinkSetId = 0;
/* initalize the global gen_config flag */
g_ftdm_sngss7_data.gen_config = 0;
@@ -1471,9 +1542,9 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init)
sng_event.cc.sng_fac_cfm = sngss7_fac_cfm;
sng_event.cc.sng_sta_ind = sngss7_sta_ind;
sng_event.cc.sng_umsg_ind = sngss7_umsg_ind;
sng_event.cc.sng_susp_ind = NULL;
sng_event.cc.sng_resm_ind = NULL;
sng_event.cc.sng_ssp_sta_cfm = NULL;
sng_event.cc.sng_susp_ind = sngss7_susp_ind;
sng_event.cc.sng_resm_ind = sngss7_resm_ind;
sng_event.cc.sng_ssp_sta_cfm = sngss7_ssp_sta_cfm;
sng_event.sm.sng_log = handle_sng_log;
sng_event.sm.sng_mtp1_alarm = handle_sng_mtp1_alarm;
@@ -58,6 +58,8 @@
#define SNGSS7_EVENT_QUEUE_SIZE 100
#define MAX_SIZEOF_SUBADDR_IE 24 /* as per Q931 4.5.9 */
typedef enum {
SNGSS7_CON_IND_EVENT = 0,
SNGSS7_CON_CFM_EVENT,
@@ -68,7 +70,10 @@ typedef enum {
SNGSS7_FAC_IND_EVENT,
SNGSS7_FAC_CFM_EVENT,
SNGSS7_UMSG_IND_EVENT,
SNGSS7_STA_IND_EVENT
SNGSS7_STA_IND_EVENT,
SNGSS7_SUSP_IND_EVENT,
SNGSS7_RESM_IND_EVENT,
SNGSS7_SSP_STA_CFM_EVENT
} sng_event_type_t;
typedef enum {
@@ -79,9 +84,20 @@ typedef enum {
typedef enum {
CONFIGURED = (1 << 0),
ACTIVE = (1 << 1)
ACTIVE = (1 << 1),
SNGSS7_PAUSED = (1 << 7)
} sng_flag_t;
typedef enum {
SNGSS7_LPA_FOR_COT = (1 << 0), /* send LPA when COT arrives */
SNGSS7_ACM_OBCI_BITA = (1 << 10) /* in-band indication */
} sng_intf_options_t;
typedef enum {
SNG_CALLED = 1,
SNG_CALLING = 2
} sng_addr_type_t;
typedef struct sng_mtp_link {
char name[MAX_NAME_LEN];
uint32_t id;
@@ -197,6 +213,7 @@ typedef struct sng_route {
typedef struct sng_isup_intf {
uint32_t id;
char name[MAX_NAME_LEN];
uint32_t options;
uint32_t flags;
uint32_t spc;
uint32_t dpc;
@@ -205,6 +222,8 @@ typedef struct sng_isup_intf {
uint32_t mtpRouteId;
uint32_t ssf;
uint32_t isap;
uint32_t clg_nadi;
uint32_t cld_nadi;
uint16_t t4;
uint32_t t10;
uint32_t t11;
@@ -335,6 +354,7 @@ typedef struct sngss7_group_data {
uint32_t range;
uint8_t status[255];
uint8_t type;
uint8_t cause;
}sngss7_group_data_t;
typedef struct sngss7_chan_data {
@@ -353,11 +373,13 @@ typedef struct sngss7_chan_data {
typedef struct sngss7_span_data {
ftdm_sched_t *sched;
sngss7_group_data_t rx_grs;
sngss7_group_data_t rx_gra;
sngss7_group_data_t tx_grs;
sngss7_group_data_t rx_cgb;
sngss7_group_data_t tx_cgb;
sngss7_group_data_t rx_cgu;
sngss7_group_data_t tx_cgu;
sngss7_group_data_t ucic;
ftdm_queue_t *event_queue;
}sngss7_span_data_t;
@@ -379,6 +401,8 @@ typedef struct sngss7_event_data
SiInfoEvnt siInfoEvnt;
SiFacEvnt siFacEvnt;
SiStaEvnt siStaEvnt;
SiSuspEvnt siSuspEvnt;
SiResmEvnt siResmEvnt;
} event;
} sngss7_event_data_t;
@@ -427,6 +451,10 @@ extern int cmbLinkSetId;
/******************************************************************************/
/* PROTOTYPES *****************************************************************/
/* in ftmod_sangoma_ss7_main.c */
void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan);
/* in ftmod_sangoma_ss7_logger.c */
void handle_sng_log(uint8_t level, char *fmt,...);
void handle_sng_mtp1_alarm(Pst *pst, L1Mngmt *sta);
void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta);
@@ -434,6 +462,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta);
void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta);
void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta);
/* in ftmod_sangoma_ss7_cfg.c */
int ft_to_sngss7_cfg_all(void);
int ftmod_ss7_mtp1_gen_config(void);
int ftmod_ss7_mtp2_gen_config(void);
@@ -452,6 +481,9 @@ int ftmod_ss7_isup_ckt_config(int id);
int ftmod_ss7_isup_isap_config(int id);
int ftmod_ss7_cc_isap_config(int id);
/* in ftmod_sangoma_ss7_cntrl.c */
int ft_to_sngss7_activate_all(void);
int ftmod_ss7_inhibit_mtplink(uint32_t id);
int ftmod_ss7_uninhibit_mtplink(uint32_t id);
int ftmod_ss7_activate_mtplink(uint32_t id);
@@ -463,11 +495,12 @@ int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id);
int ftmod_ss7_lpo_mtplink(uint32_t id);
int ftmod_ss7_lpr_mtplink(uint32_t id);
/* in ftmod_sangoma_ss7_sta.c */
int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm);
int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm);
int ft_to_sngss7_activate_all(void);
/* in ftmod_sangoma_ss7_out.c */
void ft_to_sngss7_iam(ftdm_channel_t *ftdmchan);
void ft_to_sngss7_acm(ftdm_channel_t *ftdmchan);
void ft_to_sngss7_anm(ftdm_channel_t *ftdmchan);
@@ -487,6 +520,7 @@ void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan);
/* in ftmod_sangoma_ss7_in.c */
void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
@@ -498,7 +532,11 @@ void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint
void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt);
void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
void sngss7_ssp_sta_cfm(uint32_t infId);
/* in ftmod_sangoma_ss7_handle.c */
ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType);
ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
@@ -508,6 +546,8 @@ ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt);
ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
@@ -529,25 +569,46 @@ ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t ci
ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
/* in ftmod_sangoma_ss7_xml.c */
int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span);
/* in ftmod_sangoma_ss7_cli.c */
ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data);
/* in ftmod_sangoma_ss7_support.c */
uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
int check_for_state_change(ftdm_channel_t *ftdmchan);
int check_cics_in_range(sngss7_chan_data_t *sngss7_info);
int check_for_reset(sngss7_chan_data_t *sngss7_info);
ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan);
unsigned long get_unique_id(void);
int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span);
void handle_isup_t35(void *userdata);
ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data);
ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan);
ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan);
ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan);
ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan);
ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan);
ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info);
ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type);
ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type);
/* in ftmod_sangoma_ss7_timers.c */
void handle_isup_t35(void *userdata);
/******************************************************************************/
/* MACROS *********************************************************************/
@@ -678,7 +739,19 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan);
#define sngss7_clear_flag(obj, flag) ((obj)->flags &= ~(flag))
#define sngss7_set_flag(obj, flag) ((obj)->flags |= (flag))
# define SS7_ASSERT *(int*)0=0;
#define sngss7_test_options(obj, option) ((obj)->options & option)
#define sngss7_clear_options(obj, option) ((obj)->options &= ~(option))
#define sngss7_set_options(obj, option) ((obj)->options |= (option))
#ifdef SS7_PRODUCTION
# define SS7_ASSERT \
SS7_INFO_CHAN(ftdmchan,"Production Mode, continuing%s\n", "");
#else
# define SS7_ASSERT \
SS7_ERROR_CHAN(ftdmchan, "Debugging Mode, ending%s\n", ""); \
*(int*)0=0;
#endif
/******************************************************************************/
/******************************************************************************/
@@ -74,7 +74,11 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
const char *nadi = NULL;
const char *clg_nadi = NULL;
const char *cld_nadi = NULL;
const char *clg_subAddr = NULL;
const char *cld_subAddr = NULL;
char subAddrIE[MAX_SIZEOF_SUBADDR_IE];
SiConEvnt iam;
sngss7_info->suInstId = get_unique_id ();
@@ -183,15 +187,104 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum);
/* check if the user would like a custom NADI value for the calling Pty Num */
nadi = ftdm_channel_get_var(ftdmchan, "ss7_nadi");
if ((nadi != NULL) && (*nadi)) {
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied NADI value \"%s\"\n", nadi);
iam.cgPtyNum.natAddrInd.val = atoi(nadi);
clg_nadi = ftdm_channel_get_var(ftdmchan, "ss7_clg_nadi");
if ((clg_nadi != NULL) && (*clg_nadi)) {
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling NADI value \"%s\"\n", clg_nadi);
iam.cgPtyNum.natAddrInd.val = atoi(clg_nadi);
} else {
SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found, using \"3\" %s\n", " ");
iam.cgPtyNum.natAddrInd.val = 0x03;
iam.cgPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].clg_nadi;
SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLG, using \"%d\"\n", iam.cgPtyNum.natAddrInd.val);
}
cld_nadi = ftdm_channel_get_var(ftdmchan, "ss7_cld_nadi");
if ((cld_nadi != NULL) && (*cld_nadi)) {
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called NADI value \"%s\"\n", cld_nadi);
iam.cdPtyNum.natAddrInd.val = atoi(cld_nadi);
} else {
iam.cdPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].cld_nadi;
SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLD, using \"%d\"\n", iam.cdPtyNum.natAddrInd.val);
}
/* check if the user would like us to send a clg_sub-address */
clg_subAddr = ftdm_channel_get_var(ftdmchan, "ss7_clg_subaddr");
if ((clg_subAddr != NULL) && (*clg_subAddr)) {
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling Sub-Address value \"%s\"\n", clg_subAddr);
/* clean out the subAddrIE */
memset(subAddrIE, 0x0, sizeof(subAddrIE));
/* check the first character in the sub-address to see what type of encoding to use */
switch (clg_subAddr[0]) {
case '0': /* NSAP */
encode_subAddrIE_nsap(&clg_subAddr[1], subAddrIE, SNG_CALLING);
break;
case '1': /* national variant */
encode_subAddrIE_nat(&clg_subAddr[1], subAddrIE, SNG_CALLING);
break;
default:
SS7_ERROR_CHAN(ftdmchan,"Invalid Calling Sub-Address encoding requested: %c\n", clg_subAddr[0]);
break;
} /* switch (cld_subAddr[0]) */
/* if subaddIE is still empty don't copy it in */
if (subAddrIE[0] != '0') {
/* check if the clg_subAddr has already been added */
if (iam.accTrnspt.eh.pres == PRSNT_NODEF) {
/* append the subAddrIE */
memcpy(&iam.accTrnspt.infoElmts.val[iam.accTrnspt.infoElmts.len], subAddrIE, (subAddrIE[1] + 2));
iam.accTrnspt.infoElmts.len = iam.accTrnspt.infoElmts.len +subAddrIE[1] + 2;
} else {
/* fill in from the beginning */
iam.accTrnspt.eh.pres = PRSNT_NODEF;
iam.accTrnspt.infoElmts.pres = PRSNT_NODEF;
memcpy(iam.accTrnspt.infoElmts.val, subAddrIE, (subAddrIE[1] + 2));
iam.accTrnspt.infoElmts.len = subAddrIE[1] + 2;
} /* if (iam.accTrnspt.eh.pres */
} /* if (subAddrIE[0] != '0') */
}
/* check if the user would like us to send a cld_sub-address */
cld_subAddr = ftdm_channel_get_var(ftdmchan, "ss7_cld_subaddr");
if ((cld_subAddr != NULL) && (*cld_subAddr)) {
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called Sub-Address value \"%s\"\n", cld_subAddr);
/* clean out the subAddrIE */
memset(subAddrIE, 0x0, sizeof(subAddrIE));
/* check the first character in the sub-address to see what type of encoding to use */
switch (cld_subAddr[0]) {
case '0': /* NSAP */
encode_subAddrIE_nsap(&cld_subAddr[1], subAddrIE, SNG_CALLED);
break;
case '1': /* national variant */
encode_subAddrIE_nat(&cld_subAddr[1], subAddrIE, SNG_CALLED);
break;
default:
SS7_ERROR_CHAN(ftdmchan,"Invalid Called Sub-Address encoding requested: %c\n", cld_subAddr[0]);
break;
} /* switch (cld_subAddr[0]) */
/* if subaddIE is still empty don't copy it in */
if (subAddrIE[0] != '0') {
/* check if the cld_subAddr has already been added */
if (iam.accTrnspt.eh.pres == PRSNT_NODEF) {
/* append the subAddrIE */
memcpy(&iam.accTrnspt.infoElmts.val[iam.accTrnspt.infoElmts.len], subAddrIE, (subAddrIE[1] + 2));
iam.accTrnspt.infoElmts.len = iam.accTrnspt.infoElmts.len +subAddrIE[1] + 2;
} else {
/* fill in from the beginning */
iam.accTrnspt.eh.pres = PRSNT_NODEF;
iam.accTrnspt.infoElmts.pres = PRSNT_NODEF;
memcpy(iam.accTrnspt.infoElmts.val, subAddrIE, (subAddrIE[1] + 2));
iam.accTrnspt.infoElmts.len = subAddrIE[1] + 2;
} /* if (iam.accTrnspt.eh.pres */
} /* if (subAddrIE[0] != '0') */
} /* if ((cld_subAddr != NULL) && (*cld_subAddr)) */
sng_cc_con_request (sngss7_info->spId,
sngss7_info->suInstId,
sngss7_info->spInstId,
@@ -199,10 +292,12 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
&iam,
0);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\", cld = \"%s\"\n",
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d)\n",
sngss7_info->circuit->cic,
ftdmchan->caller_data.cid_num.digits,
ftdmchan->caller_data.dnis.digits);
iam.cgPtyNum.natAddrInd.val,
ftdmchan->caller_data.dnis.digits,
iam.cdPtyNum.natAddrInd.val);
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
return;
@@ -213,7 +308,8 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
{
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
sng_isup_inf_t *isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
SiCnStEvnt acm;
memset (&acm, 0x0, sizeof (acm));
@@ -242,7 +338,19 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
acm.bckCallInd.echoCtrlDevInd.val = 0x1; /* ec device present */
acm.bckCallInd.sccpMethInd.pres = PRSNT_NODEF;
acm.bckCallInd.sccpMethInd.val = SCCPMTH_NOIND;
/* fill in any optional parameters */
if (sngss7_test_options(isup_intf, SNGSS7_ACM_OBCI_BITA)) {
SS7_DEBUG_CHAN(ftdmchan, "Found ACM_OBCI_BITA flag:0x%X\n", isup_intf->options);
acm.optBckCalInd.eh.pres = PRSNT_NODEF;
acm.optBckCalInd.inbndInfoInd.pres = PRSNT_NODEF;
acm.optBckCalInd.inbndInfoInd.val = 0x1;
acm.optBckCalInd.caFwdMayOcc.pres = PRSNT_DEF;
acm.optBckCalInd.simpleSegmInd.pres = PRSNT_DEF;
acm.optBckCalInd.mlppUserInd.pres = PRSNT_DEF;
acm.optBckCalInd.usrNetIneractInd.pres = PRSNT_DEF;
} /* if (sngss7_test_options(isup_intf, SNGSS7_ACM_OBCI_BITA)) */
/* send the ACM request to LibSngSS7 */
sng_cc_con_status (1,
sngss7_info->suInstId,
@@ -50,27 +50,41 @@ int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm);
int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm)
{
SnMngmt sta;
Pst pst;
memset(&sta, 0x0, sizeof(sta));
/* initalize the post structure */
smPstInit(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTSN;
sta.hdr.elmId.elmnt = STDLSAP;
sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id;
return(sng_sta_mtp3(&sta, cfm));
return(sng_sta_mtp3(&pst, &sta, cfm));
}
/******************************************************************************/
int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm)
{
SnMngmt sta;
Pst pst;
memset(&sta, 0x0, sizeof(sta));
/* initalize the post structure */
smPstInit(&pst);
/* insert the destination Entity */
pst.dstEnt = ENTSN;
sta.hdr.elmId.elmnt = STLNKSET;
sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id;
sta.hdr.elmId.elmntInst2 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].links[0];
return(sng_sta_mtp3(&sta, cfm));
return(sng_sta_mtp3(&pst, &sta, cfm));
}
/******************************************************************************/
@@ -44,6 +44,7 @@ uint32_t sngss7_id;
/* PROTOTYPES *****************************************************************/
uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
@@ -57,8 +58,23 @@ unsigned long get_unique_id(void);
ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan);
ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan);
ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan);
ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan);
ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan);
ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan);
ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info);
ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type);
ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
@@ -152,8 +168,8 @@ uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum)
} else {
/* keep the odd flag down */
odd = 0;
/* throw the flag */
flag = 1;
/* break right away since we don't need to write the digits */
break;
}
/* push the digits into the trillium structure */
@@ -254,14 +270,14 @@ uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum)
upper = (atoi(&tmp[0])) << 4;
} else {
/* there is no upper ... fill in ST */
upper = 0xF;
/* throw the odd flag */
odd = 1;
upper = 0xF0;
/* keep the odd flag down */
odd = 0;
/* throw the end flag */
flag = 1;
} /* if (tmp != '\0') */
} else {
/* keep the odd flag down */
/* throw the odd flag */
odd = 1;
/* need to add the ST */
lower = 0xF;
@@ -328,6 +344,49 @@ uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
return 0;
}
/******************************************************************************/
uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
{
int i = 0;
int j = 0;
/* check if the token string is present */
if (str.pres == 1) {
/* find the length of the digits so far */
j = strlen(ftdm);
/* confirm that we found an acceptable length */
if ( j > 25 ) {
SS7_ERROR("string length exceeds maxium value...aborting append!\n");
return 1;
} /* if ( j > 25 ) */
/* copy in digits */
for (i = 0; i < str.len; i++) {
/* convert 4 bit integer to char and copy into lower nibblet*/
sprintf(&ftdm[j], "%X", (str.val[i] & 0x0F));
/* move along */
j++;
/* convert 4 bit integer to char and copy into upper nibblet */
sprintf(&ftdm[j], "%X", ((str.val[i] & 0xF0) >> 4));
/* move along */
j++;
} /* for (i = 0; i < str.len; i++) */
/* if the odd flag is up the last digit is a fake "0" */
if ((oddEven.pres == 1) && (oddEven.val == 1)) {
ftdm[j-1] = '\0';
} else {
ftdm[j] = '\0';
} /* if ((oddEven.pres == 1) && (oddEven.val == 1)) */
} else {
SS7_ERROR("Asked to copy tknStr that is not present!\n");
return 1;
} /* if (str.pres == 1) */
return 0;
}
/******************************************************************************/
int check_for_state_change(ftdm_channel_t *ftdmchan)
{
@@ -445,6 +504,68 @@ unsigned long get_unique_id(void)
return(sngss7_id);
}
/******************************************************************************/
ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan)
{
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
int i;
for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
continue;
}
/* check if the GRP_RESET_RX flag is already up */
if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) {
/* we have already processed this channel...move along */
continue;
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
/* clear up any pending state changes */
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_sangoma_ss7_process_state_change (ftdmchan);
}
SS7_INFO_CHAN(ftdmchan, "Rx GRS (%d:%d)\n",
g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic,
(g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic + sngss7_span->rx_grs.range));
/* flag the channel as having received a reset */
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX);
switch (ftdmchan->state) {
/**************************************************************************/
case FTDM_CHANNEL_STATE_RESTART:
/* go to idle so that we can redo the restart state*/
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
break;
/**************************************************************************/
default:
/* set the state of the channel to restart...the rest is done by the chan monitor */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
/**************************************************************************/
} /* switch (ftdmchan->state) */
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
} /* for (chans in GRS */
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan)
{
@@ -456,7 +577,7 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan)
int bit = 0;
ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id);
ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %s...checking circuits\n", ftdmspan->name);
/* check all the circuits in the range to see if they are done resetting */
for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
@@ -493,7 +614,10 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan)
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i);
/* check if we need to die */
SS7_ASSERT;
/* move along */
continue;
}
/* throw the GRP reset flag complete flag */
@@ -534,6 +658,91 @@ GRS_UNLOCK_ALL:
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan)
{
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
int i;
for (i = sngss7_span->rx_gra.circuit; i < (sngss7_span->rx_gra.circuit + sngss7_span->rx_gra.range + 1); i++) {
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
continue;
}
/* check if the channel is already procoessing the GRA */
if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) {
/* move along */
continue;
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
/* clear up any pending state changes */
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_sangoma_ss7_process_state_change (ftdmchan);
}
SS7_INFO_CHAN(ftdmchan, "Rx GRA (%d:%d)\n",
g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_gra.circuit].cic,
(g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_gra.circuit].cic + sngss7_span->rx_gra.range));
switch (ftdmchan->state) {
/**********************************************************************/
case FTDM_CHANNEL_STATE_RESTART:
/* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
/* go to DOWN */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
break;
/**********************************************************************/
case FTDM_CHANNEL_STATE_DOWN:
/* do nothing, just drop the message */
SS7_DEBUG("Receveived GRA in down state, dropping\n");
break;
/**********************************************************************/
case FTDM_CHANNEL_STATE_TERMINATING:
case FTDM_CHANNEL_STATE_HANGUP:
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
/* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
break;
/**********************************************************************/
default:
/* ITU Q764-2.9.5.1.c -> release the circuit */
if (sngss7_span->rx_gra.cause != 0) {
ftdmchan->caller_data.hangup_cause = sngss7_span->rx_gra.cause;
} else {
ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */
}
/* go to terminating to hang up the call */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
break;
/**********************************************************************/
}
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
} /* for ( circuits in request */
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan)
{
@@ -564,6 +773,11 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan)
/* if we have the PAUSED flag and the sig status is still UP */
if ((sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) &&
(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) {
/* clear up any pending state changes */
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_sangoma_ss7_process_state_change (ftdmchan);
}
/* throw the channel into SUSPENDED to process the flag */
/* after doing this once the sig status will be down */
@@ -573,6 +787,13 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan)
/* if the RESUME flag is up go to SUSPENDED to process the flag */
/* after doing this the flag will be cleared */
if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) {
/* clear up any pending state changes */
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_sangoma_ss7_process_state_change (ftdmchan);
}
/* got SUSPENDED state to clear the flag */
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
}
@@ -588,7 +809,336 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan)
}
/******************************************************************************/
ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan)
{
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
int i;
for (i = sngss7_span->ucic.circuit; i < (sngss7_span->ucic.circuit + sngss7_span->ucic.range + 1); i++) {
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
continue;
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UCIC\n", sngss7_info->circuit->cic);
/* clear up any pending state changes */
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_sangoma_ss7_process_state_change (ftdmchan);
}
/* throw the ckt block flag */
sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
/* set the channel to suspended state */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
}
/* clear out the ucic data since we're done with it */
memset(&sngss7_span->ucic, 0x0, sizeof(sngss7_group_data_t));
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info)
{
/* clear all the flags related to an incoming GRS */
sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX);
sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_DN);
sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info)
{
ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data;
/* clear the rx_grs data fields */
memset(&sngss7_span->rx_grs, 0x0, sizeof(sngss7_group_data_t));
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info)
{
ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data;
/* clear the rx_grs data fields */
memset(&sngss7_span->rx_gra, 0x0, sizeof(sngss7_group_data_t));
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info)
{
/* clear all the flags related to an outgoing GRS */
sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_BASE);
sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX);
sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_SENT);
sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info)
{
ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data;
/* clear the rx_grs data fields */
memset(&sngss7_span->tx_grs, 0x0, sizeof(sngss7_group_data_t));
return FTDM_SUCCESS;
}
/******************************************************************************/
/******************************************************************************/
ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info)
{
/* clear all the flags related to an incoming RSC */
sngss7_clear_flag(sngss7_info, FLAG_RESET_RX);
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info)
{
/* clear all the flags related to an outgoing RSC */
sngss7_clear_flag(sngss7_info, FLAG_RESET_TX);
sngss7_clear_flag(sngss7_info, FLAG_RESET_SENT);
sngss7_clear_flag(sngss7_info, FLAG_RESET_TX_RSP);
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type)
{
/* Q931 4.5.9
* 8 7 6 5 4 3 2 1 (octet)
*
* 0 1 1 1 0 0 0 1 (spare 8) ( IE id 1-7)
* X X X X X X X X (length of IE contents)
* 1 0 0 0 Z 0 0 0 (ext 8) (NSAP type 5-7) (odd/even 4) (spare 1-3)
* X X X X X X X X (sub address encoded in ia5)
*/
int x = 0;
int p = 0;
int len = 0;
char tmp[2];
/* initalize the second element of tmp to \0 so that atoi doesn't go to far */
tmp[1]='\0';
/* set octet 1 aka IE id */
p = 0;
switch(type) {
/**************************************************************************/
case SNG_CALLED: /* called party sub address */
subAddrIE[p] = 0x71;
break;
/**************************************************************************/
case SNG_CALLING: /* calling party sub address */
subAddrIE[p] = 0x6d;
break;
/**************************************************************************/
default: /* not good */
SS7_ERROR("Sub-Address type is invalid: %d\n", type);
return FTDM_FAIL;
break;
/**************************************************************************/
} /* switch(type) */
/* set octet 3 aka type and o/e */
p = 2;
subAddrIE[p] = 0x80;
/* set the subAddrIE pointer octet 4 */
p = 3;
/* loop through all digits in subAddr and insert them into subAddrIE */
while (subAddr[x] != '\0') {
/* grab a character */
tmp[0] = subAddr[x];
/* confirm it is a digit */
if (!isdigit(tmp[0])) {
/* move to the next character in subAddr */
x++;
/* restart the loop */
continue;
}
/* convert the character to IA5 encoding and write into subAddrIE */
subAddrIE[p] = atoi(&tmp[0]); /* lower nibble is the digit */
subAddrIE[p] |= 0x3 << 4; /* upper nibble is 0x3 */
/* increment address length counter */
len++;
/* increment the subAddrIE pointer */
p++;
/* move to the next character in subAddr */
x++;
} /* while (subAddr[x] != '\0') */
/* set octet 2 aka length of subaddr */
p = 1;
subAddrIE[p] = len + 1;
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type)
{
/* Q931 4.5.9
* 8 7 6 5 4 3 2 1 (octet)
*
* 0 1 1 1 0 0 0 1 (spare 8) ( IE id 1-7)
* X X X X X X X X (length of IE contents)
* 1 0 0 0 Z 0 0 0 (ext 8) (NSAP type 5-7) (odd/even 4) (spare 1-3)
* X X X X X X X X (sub address encoded in ia5)
*/
int x = 0;
int p = 0;
int len = 0;
char tmp[2];
int flag = 0;
int odd = 0;
uint8_t lower = 0x0;
uint8_t upper = 0x0;
/* initalize the second element of tmp to \0 so that atoi doesn't go to far */
tmp[1]='\0';
/* set octet 1 aka IE id */
p = 0;
switch(type) {
/**************************************************************************/
case SNG_CALLED: /* called party sub address */
subAddrIE[p] = 0x71;
break;
/**************************************************************************/
case SNG_CALLING: /* calling party sub address */
subAddrIE[p] = 0x6d;
break;
/**************************************************************************/
default: /* not good */
SS7_ERROR("Sub-Address type is invalid: %d\n", type);
return FTDM_FAIL;
break;
/**************************************************************************/
} /* switch(type) */
/* set the subAddrIE pointer octet 4 */
p = 3;
/* loop through all digits in subAddr and insert them into subAddrIE */
while (1) {
/* grab a character */
tmp[0] = subAddr[x];
/* confirm it is a hex digit */
while ((!isxdigit(tmp[0])) && (tmp[0] != '\0')) {
/* move to the next character in subAddr */
x++;
tmp[0] = subAddr[x];
}
/* check if tmp is null or a digit */
if (tmp[0] != '\0') {
/* push it into the lower nibble using strtol to allow a-f chars */
lower = strtol(&tmp[0], (char **)NULL, 16);
/* move to the next digit */
x++;
/* grab a digit from the ftdm digits */
tmp[0] = subAddr[x];
/* check if the digit is a hex digit and that is not null */
while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) {
x++;
tmp[0] = subAddr[x];
} /* while(!(isdigit(tmp))) */
/* check if tmp is null or a digit */
if (tmp[0] != '\0') {
/* push the digit into the upper nibble using strtol to allow a-f chars */
upper = (strtol(&tmp[0], (char **)NULL, 16)) << 4;
} else {
/* there is no upper ... fill in spare */
upper = 0x00;
/* throw the odd flag since we need to buffer */
odd = 1;
/* throw the end flag */
flag = 1;
} /* if (tmp != '\0') */
} else {
/* keep the odd flag down */
odd = 0;
/* throw the flag */
flag = 1;
/* bounce out right away */
break;
}
/* fill in the octet */
subAddrIE[p] = upper | lower;
/* increment address length counter */
len++;
/* if the flag is we're through all the digits */
if (flag) break;
/* increment the subAddrIE pointer */
p++;
/* move to the next character in subAddr */
x++;
} /* while (subAddr[x] != '\0') */
/* set octet 2 aka length of subaddr */
p = 1;
subAddrIE[p] = len + 1;
/* set octet 3 aka type and o/e */
p = 2;
subAddrIE[p] = 0xa0 | (odd << 3);
return FTDM_SUCCESS;
}
/******************************************************************************/
/* For Emacs:
@@ -47,6 +47,23 @@ typedef struct sng_timeslot
int hole;
}sng_timeslot_t;
typedef struct sng_isupCkt
{
ftdm_span_t *span;
uint32_t cicbase;
uint32_t typeCntrl;
char ch_map[MAX_CIC_MAP_LENGTH];
uint32_t isupInf;
uint32_t t3;
uint32_t t12;
uint32_t t13;
uint32_t t14;
uint32_t t15;
uint32_t t16;
uint32_t t17;
uint32_t tval;
} sng_isupCkt_t;
int cmbLinkSetId;
/******************************************************************************/
@@ -77,7 +94,7 @@ static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap);
static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, int ssf);
static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl, int isup_id, ftdm_span_t *span);
static int ftmod_ss7_fill_in_circuits(sng_isupCkt_t *isupCkt);
static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot);
/******************************************************************************/
@@ -91,9 +108,10 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
const char *val = NULL;
ftdm_conf_node_t *ptr = NULL;
sng_route_t self_route;
char ch_map[MAX_CIC_MAP_LENGTH];
int typeCntrl = 0;
int cicbase = 0;
sng_isupCkt_t isupCkt;
/* clean out the isup ckt */
memset(&isupCkt, 0x0, sizeof(sng_isupCkt_t));
/* clean out the self route */
memset(&self_route, 0x0, sizeof(sng_route_t));
@@ -124,24 +142,24 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
if (!strcasecmp(var, "ch_map")) {
/**********************************************************************/
strcpy(ch_map, val);
SS7_DEBUG("\tFound channel map \"%s\"\n", ch_map);
strcpy(isupCkt.ch_map, val);
SS7_DEBUG("\tFound channel map \"%s\"\n", isupCkt.ch_map);
/**********************************************************************/
} else if (!strcasecmp(var, "typeCntrl")) {
if (!strcasecmp(val, "bothway")) {
typeCntrl = BOTHWAY;
isupCkt.typeCntrl = BOTHWAY;
SS7_DEBUG("\tFound control type \"bothway\"\n");
} else if (!strcasecmp(val, "incoming")) {
typeCntrl = INCOMING;
isupCkt.typeCntrl = INCOMING;
SS7_DEBUG("\tFound control type \"incoming\"\n");
} else if (!strcasecmp(val, "outgoing")) {
typeCntrl = OUTGOING;
isupCkt.typeCntrl = OUTGOING;
SS7_DEBUG("\tFound control type \"outgoing\"\n");
} else if (!strcasecmp(val, "controlled")) {
typeCntrl = CONTROLLED;
isupCkt.typeCntrl = CONTROLLED;
SS7_DEBUG("\tFound control type \"controlled\"\n");
} else if (!strcasecmp(val, "controlling")) {
typeCntrl = CONTROLLING;
isupCkt.typeCntrl = CONTROLLING;
SS7_DEBUG("\tFound control type \"controlling\"\n");
} else {
SS7_ERROR("Found invalid circuit control type \"%s\"!", val);
@@ -149,8 +167,8 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
}
/**********************************************************************/
} else if (!strcasecmp(var, "cicbase")) {
cicbase = atoi(val);
SS7_DEBUG("\tFound cicbase = %d\n", cicbase);
isupCkt.cicbase = atoi(val);
SS7_DEBUG("\tFound cicbase = %d\n", isupCkt.cicbase);
/**********************************************************************/
} else if (!strcasecmp(var, "dialplan")) {
/* do i give a shit about this??? */
@@ -169,7 +187,41 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
/* move on to the next one */
x++;
}
SS7_DEBUG("\tFound isup_interface = %s\n",g_ftdm_sngss7_data.cfg.isupIntf[x].name );
isupCkt.isupInf = x;
SS7_DEBUG("\tFound isup_interface = %s\n",g_ftdm_sngss7_data.cfg.isupIntf[x].name);
/**********************************************************************/
} else if (!strcasecmp(var, "isup.t3")) {
isupCkt.t3 = atoi(val);
SS7_DEBUG("\tFound isup t3 = \"%d\"\n", isupCkt.t3);
/**********************************************************************/
} else if (!strcasecmp(var, "isup.t12")) {
isupCkt.t12 = atoi(val);
SS7_DEBUG("\tFound isup t12 = \"%d\"\n", isupCkt.t12);
/**********************************************************************/
} else if (!strcasecmp(var, "isup.t13")) {
isupCkt.t13 = atoi(val);
SS7_DEBUG("\tFound isup t13 = \"%d\"\n", isupCkt.t13);
/**********************************************************************/
} else if (!strcasecmp(var, "isup.t14")) {
isupCkt.t14 = atoi(val);
SS7_DEBUG("\tFound isup t14 = \"%d\"\n", isupCkt.t14);
/**********************************************************************/
} else if (!strcasecmp(var, "isup.t15")) {
isupCkt.t15 = atoi(val);
SS7_DEBUG("\tFound isup t15 = \"%d\"\n", isupCkt.t15);
/**********************************************************************/
} else if (!strcasecmp(var, "isup.t16")) {
isupCkt.t16 = atoi(val);
SS7_DEBUG("\tFound isup t16 = \"%d\"\n", isupCkt.t16);
/**********************************************************************/
} else if (!strcasecmp(var, "isup.t17")) {
isupCkt.t17 = atoi(val);
SS7_DEBUG("\tFound isup t17 = \"%d\"\n", isupCkt.t17);
/**********************************************************************/
} else if (!strcasecmp(var, "isup.tval")) {
isupCkt.tval = atoi(val);
SS7_DEBUG("\tFound isup tval = \"%d\"\n", isupCkt.tval);
/**********************************************************************/
} else {
SS7_ERROR("Unknown parameter found =\"%s\"...ignoring it!\n", var);
@@ -192,10 +244,11 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
}
/* fill the pointer to span into isupCkt */
isupCkt.span = span;
/* setup the circuits structure */
if(ftmod_ss7_fill_in_circuits(ch_map, cicbase, typeCntrl,
g_ftdm_sngss7_data.cfg.isupIntf[x].id, span)) {
if(ftmod_ss7_fill_in_circuits(&isupCkt)) {
SS7_ERROR("Failed to fill in circuits structure!\n");
goto ftmod_ss7_parse_xml_error;
}
@@ -573,6 +626,10 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *
mtpLink->mtp3.ssf = SSF_NAT;
} else if (!strcasecmp(parm->val, "int")) {
mtpLink->mtp3.ssf = SSF_INTL;
} else if (!strcasecmp(parm->val, "spare")) {
mtpLink->mtp3.ssf = SSF_SPARE;
} else if (!strcasecmp(parm->val, "res")) {
mtpLink->mtp3.ssf = SSF_RES;
} else {
SS7_ERROR("\tFound an invalid ssf of \"%s\"!\n", parm->val);
return FTDM_FAIL;
@@ -582,6 +639,130 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *
mtpLink->mtp3.slc = atoi(parm->val);
SS7_DEBUG("\tFound mtpLink->slc = \"%d\"\n",mtpLink->mtp3.slc);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp2.t1")) {
mtpLink->mtp2.t1 = atoi(parm->val);
SS7_DEBUG("\tFound mtp2 t1 = \"%d\"\n",mtpLink->mtp2.t1);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp2.t2")) {
mtpLink->mtp2.t2 = atoi(parm->val);
SS7_DEBUG("\tFound mtp2 t2 = \"%d\"\n",mtpLink->mtp2.t2);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp2.t3")) {
mtpLink->mtp2.t3 = atoi(parm->val);
SS7_DEBUG("\tFound mtp2 t3 = \"%d\"\n",mtpLink->mtp2.t3);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp2.t4n")) {
mtpLink->mtp2.t4n = atoi(parm->val);
SS7_DEBUG("\tFound mtp2 t4n = \"%d\"\n",mtpLink->mtp2.t4n);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp2.t4e")) {
mtpLink->mtp2.t4e = atoi(parm->val);
SS7_DEBUG("\tFound mtp2 t4e = \"%d\"\n",mtpLink->mtp2.t4e);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp2.t5")) {
mtpLink->mtp2.t5 = atoi(parm->val);
SS7_DEBUG("\tFound mtp2 t5 = \"%d\"\n",mtpLink->mtp2.t5);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp2.t6")) {
mtpLink->mtp2.t6 = atoi(parm->val);
SS7_DEBUG("\tFound mtp2 t6 = \"%d\"\n",mtpLink->mtp2.t6);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp2.t7")) {
mtpLink->mtp2.t7 = atoi(parm->val);
SS7_DEBUG("\tFound mtp2 t7 = \"%d\"\n",mtpLink->mtp2.t7);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t1")) {
mtpLink->mtp3.t1 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t1 = \"%d\"\n",mtpLink->mtp3.t1);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t2")) {
mtpLink->mtp3.t2 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t2 = \"%d\"\n",mtpLink->mtp3.t2);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t3")) {
mtpLink->mtp3.t3 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t3 = \"%d\"\n",mtpLink->mtp3.t3);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t4")) {
mtpLink->mtp3.t4 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t4 = \"%d\"\n",mtpLink->mtp3.t4);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t5")) {
mtpLink->mtp3.t5 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t5 = \"%d\"\n",mtpLink->mtp3.t5);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t7")) {
mtpLink->mtp3.t7 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t7 = \"%d\"\n",mtpLink->mtp3.t7);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t12")) {
mtpLink->mtp3.t12 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t12 = \"%d\"\n",mtpLink->mtp3.t12);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t13")) {
mtpLink->mtp3.t13 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t13 = \"%d\"\n",mtpLink->mtp3.t13);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t14")) {
mtpLink->mtp3.t14 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t14 = \"%d\"\n",mtpLink->mtp3.t14);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t17")) {
mtpLink->mtp3.t17 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t17 = \"%d\"\n",mtpLink->mtp3.t17);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t22")) {
mtpLink->mtp3.t22 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t22 = \"%d\"\n",mtpLink->mtp3.t22);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t23")) {
mtpLink->mtp3.t23 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t23 = \"%d\"\n",mtpLink->mtp3.t23);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t24")) {
mtpLink->mtp3.t24 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t24 = \"%d\"\n",mtpLink->mtp3.t24);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t31")) {
mtpLink->mtp3.t31 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t31 = \"%d\"\n",mtpLink->mtp3.t31);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t32")) {
mtpLink->mtp3.t32 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t32 = \"%d\"\n",mtpLink->mtp3.t32);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t33")) {
mtpLink->mtp3.t33 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t33 = \"%d\"\n",mtpLink->mtp3.t33);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t34")) {
mtpLink->mtp3.t34 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t34 = \"%d\"\n",mtpLink->mtp3.t34);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t35")) {
mtpLink->mtp3.t35 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t35 = \"%d\"\n",mtpLink->mtp3.t35);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t36")) {
mtpLink->mtp3.t36 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t36 = \"%d\"\n",mtpLink->mtp3.t36);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t37")) {
mtpLink->mtp3.t37 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t37 = \"%d\"\n",mtpLink->mtp3.t37);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.tcraft")) {
mtpLink->mtp3.tcraft = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 tcraft = \"%d\"\n",mtpLink->mtp3.tcraft);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.tflc")) {
mtpLink->mtp3.tflc = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 tflc = \"%d\"\n",mtpLink->mtp3.tflc);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.tbnd")) {
mtpLink->mtp3.tbnd = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 tbnd = \"%d\"\n",mtpLink->mtp3.tbnd);
/**********************************************************************/
} else {
SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val);
return FTDM_FAIL;
@@ -697,6 +878,50 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route)
return FTDM_FAIL;
}
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t6")) {
mtpRoute.t6 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t6 = \"%d\"\n",mtpRoute.t6);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t8")) {
mtpRoute.t8 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t8 = \"%d\"\n",mtpRoute.t8);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t10")) {
mtpRoute.t10 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t10 = \"%d\"\n",mtpRoute.t10);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t11")) {
mtpRoute.t11 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t11 = \"%d\"\n",mtpRoute.t11);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t15")) {
mtpRoute.t15 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t15 = \"%d\"\n",mtpRoute.t15);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t16")) {
mtpRoute.t16 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t16 = \"%d\"\n",mtpRoute.t16);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t18")) {
mtpRoute.t18 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t18 = \"%d\"\n",mtpRoute.t18);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t19")) {
mtpRoute.t19 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t19 = \"%d\"\n",mtpRoute.t19);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t21")) {
mtpRoute.t21 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t21 = \"%d\"\n",mtpRoute.t21);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t25")) {
mtpRoute.t25 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t25 = \"%d\"\n",mtpRoute.t25);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp3.t26")) {
mtpRoute.t26 = atoi(parm->val);
SS7_DEBUG("\tFound mtp3 t26 = \"%d\"\n",mtpRoute.t26);
/**********************************************************************/
} else {
SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val);
return FTDM_FAIL;
@@ -755,6 +980,8 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
int num_parms = isup_interface->n_parameters;
int i;
int linkSetId;
int flag_cld_nadi = 0;
int flag_clg_nadi = 0;
memset(&sng_isup, 0x0, sizeof(sng_isup));
memset(&sng_isap, 0x0, sizeof(sng_isap));
@@ -827,6 +1054,12 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
} else if (!strcasecmp(parm->val, "int")) {
sng_isup.ssf = SSF_INTL;
sng_isap.ssf = SSF_INTL;
} else if (!strcasecmp(parm->val, "spare")) {
sng_isup.ssf = SSF_SPARE;
sng_isap.ssf = SSF_SPARE;
} else if (!strcasecmp(parm->val, "res")) {
sng_isup.ssf = SSF_RES;
sng_isap.ssf = SSF_RES;
} else {
SS7_ERROR("\tFound an invalid ssf of \"%s\"!\n", parm->val);
return FTDM_FAIL;
@@ -840,6 +1073,216 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
SS7_DEBUG("\tFound license file = %s\n", g_ftdm_sngss7_data.cfg.license);
SS7_DEBUG("\tFound signature file = %s\n", g_ftdm_sngss7_data.cfg.signature);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t1")) {
sng_isap.t1 = atoi(parm->val);
SS7_DEBUG("\tFound isup t1 = \"%d\"\n",sng_isap.t1);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t2")) {
sng_isap.t2 = atoi(parm->val);
SS7_DEBUG("\tFound isup t2 = \"%d\"\n",sng_isap.t2);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t4")) {
sng_isup.t4 = atoi(parm->val);
SS7_DEBUG("\tFound isup t4 = \"%d\"\n",sng_isup.t4);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t5")) {
sng_isap.t5 = atoi(parm->val);
SS7_DEBUG("\tFound isup t5 = \"%d\"\n",sng_isap.t5);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t6")) {
sng_isap.t6 = atoi(parm->val);
SS7_DEBUG("\tFound isup t6 = \"%d\"\n",sng_isap.t6);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t7")) {
sng_isap.t7 = atoi(parm->val);
SS7_DEBUG("\tFound isup t7 = \"%d\"\n",sng_isap.t7);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t8")) {
sng_isap.t8 = atoi(parm->val);
SS7_DEBUG("\tFound isup t8 = \"%d\"\n",sng_isap.t8);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t9")) {
sng_isap.t9 = atoi(parm->val);
SS7_DEBUG("\tFound isup t9 = \"%d\"\n",sng_isap.t9);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t10")) {
sng_isup.t10 = atoi(parm->val);
SS7_DEBUG("\tFound isup t10 = \"%d\"\n",sng_isup.t10);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t11")) {
sng_isup.t11 = atoi(parm->val);
SS7_DEBUG("\tFound isup t11 = \"%d\"\n",sng_isup.t11);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t18")) {
sng_isup.t18 = atoi(parm->val);
SS7_DEBUG("\tFound isup t18 = \"%d\"\n",sng_isup.t18);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t19")) {
sng_isup.t19 = atoi(parm->val);
SS7_DEBUG("\tFound isup t19 = \"%d\"\n",sng_isup.t19);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t20")) {
sng_isup.t20 = atoi(parm->val);
SS7_DEBUG("\tFound isup t20 = \"%d\"\n",sng_isup.t20);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t21")) {
sng_isup.t21 = atoi(parm->val);
SS7_DEBUG("\tFound isup t21 = \"%d\"\n",sng_isup.t21);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t22")) {
sng_isup.t22 = atoi(parm->val);
SS7_DEBUG("\tFound isup t22 = \"%d\"\n",sng_isup.t22);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t23")) {
sng_isup.t23 = atoi(parm->val);
SS7_DEBUG("\tFound isup t23 = \"%d\"\n",sng_isup.t23);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t24")) {
sng_isup.t24 = atoi(parm->val);
SS7_DEBUG("\tFound isup t24 = \"%d\"\n",sng_isup.t24);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t25")) {
sng_isup.t25 = atoi(parm->val);
SS7_DEBUG("\tFound isup t25 = \"%d\"\n",sng_isup.t25);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t26")) {
sng_isup.t26 = atoi(parm->val);
SS7_DEBUG("\tFound isup t26 = \"%d\"\n",sng_isup.t26);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t28")) {
sng_isup.t28 = atoi(parm->val);
SS7_DEBUG("\tFound isup t28 = \"%d\"\n",sng_isup.t28);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t29")) {
sng_isup.t29 = atoi(parm->val);
SS7_DEBUG("\tFound isup t29 = \"%d\"\n",sng_isup.t29);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t30")) {
sng_isup.t30 = atoi(parm->val);
SS7_DEBUG("\tFound isup t30 = \"%d\"\n",sng_isup.t30);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t31")) {
sng_isap.t31 = atoi(parm->val);
SS7_DEBUG("\tFound isup t31 = \"%d\"\n",sng_isap.t31);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t32")) {
sng_isup.t32 = atoi(parm->val);
SS7_DEBUG("\tFound isup t32 = \"%d\"\n",sng_isup.t32);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t33")) {
sng_isap.t33 = atoi(parm->val);
SS7_DEBUG("\tFound isup t33 = \"%d\"\n",sng_isap.t33);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t34")) {
sng_isap.t34 = atoi(parm->val);
SS7_DEBUG("\tFound isup t34 = \"%d\"\n",sng_isap.t34);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t35")) {
sng_isup.t35 = atoi(parm->val);
SS7_DEBUG("\tFound isup t35 = \"%d\"\n",sng_isup.t35);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t36")) {
sng_isap.t36 = atoi(parm->val);
SS7_DEBUG("\tFound isup t36 = \"%d\"\n",sng_isap.t36);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t37")) {
sng_isup.t37 = atoi(parm->val);
SS7_DEBUG("\tFound isup t37 = \"%d\"\n",sng_isup.t37);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t38")) {
sng_isup.t38 = atoi(parm->val);
SS7_DEBUG("\tFound isup t38 = \"%d\"\n",sng_isup.t38);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t39")) {
sng_isup.t39 = atoi(parm->val);
SS7_DEBUG("\tFound isup t39 = \"%d\"\n",sng_isup.t39);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.tccr")) {
sng_isap.tccr = atoi(parm->val);
SS7_DEBUG("\tFound isup tccr = \"%d\"\n",sng_isap.tccr);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.tccrt")) {
sng_isap.tccrt = atoi(parm->val);
SS7_DEBUG("\tFound isup tccrt = \"%d\"\n",sng_isap.tccrt);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.tex")) {
sng_isap.tex = atoi(parm->val);
SS7_DEBUG("\tFound isup tex = \"%d\"\n",sng_isap.tex);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.tect")) {
sng_isap.tect = atoi(parm->val);
SS7_DEBUG("\tFound isup tect = \"%d\"\n",sng_isap.tect);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.tcrm")) {
sng_isap.tcrm = atoi(parm->val);
SS7_DEBUG("\tFound isup tcrm = \"%d\"\n",sng_isap.tcrm);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.tcra")) {
sng_isap.tcra = atoi(parm->val);
SS7_DEBUG("\tFound isup tcra = \"%d\"\n",sng_isap.tcra);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.tfgr")) {
sng_isup.tfgr = atoi(parm->val);
SS7_DEBUG("\tFound isup tfgr = \"%d\"\n",sng_isup.tfgr);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.trelrsp")) {
sng_isap.trelrsp = atoi(parm->val);
SS7_DEBUG("\tFound isup trelrsp = \"%d\"\n",sng_isap.trelrsp);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.tfnlrelrsp")) {
sng_isap.tfnlrelrsp = atoi(parm->val);
SS7_DEBUG("\tFound isup tfnlrelrsp = \"%d\"\n",sng_isap.tfnlrelrsp);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.tfnlrelrsp")) {
sng_isap.tfnlrelrsp = atoi(parm->val);
SS7_DEBUG("\tFound isup tfnlrelrsp = \"%d\"\n",sng_isap.tfnlrelrsp);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.tpause")) {
sng_isup.tpause = atoi(parm->val);
SS7_DEBUG("\tFound isup tpause = \"%d\"\n",sng_isup.tpause);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.tstaenq")) {
sng_isup.tstaenq = atoi(parm->val);
SS7_DEBUG("\tFound isup tstaenq = \"%d\"\n",sng_isup.tstaenq);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "clg_nadi")) {
/**********************************************************************/
/* throw the flag so that we know we got this optional parameter */
flag_clg_nadi = 1;
sng_isup.clg_nadi = atoi(parm->val);
SS7_DEBUG("\tFound default CLG_NADI value = %d\n", sng_isup.clg_nadi);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "cld_nadi")) {
/**********************************************************************/
/* throw the flag so that we know we got this optional parameter */
flag_cld_nadi = 1;
sng_isup.cld_nadi = atoi(parm->val);
SS7_DEBUG("\tFound default CLD_NADI value = %d\n", sng_isup.cld_nadi);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "obci_bita")) {
/**********************************************************************/
if (*parm->val == '1') {
sngss7_set_options(&sng_isup, SNGSS7_ACM_OBCI_BITA);
SS7_DEBUG("\tFound Optional Backwards Indicator: Bit A (early media) enable option\n");
} else if (*parm->val == '0') {
sngss7_clear_options(&sng_isup, SNGSS7_ACM_OBCI_BITA);
SS7_DEBUG("\tFound Optional Backwards Indicator: Bit A (early media) disable option\n");
} else {
SS7_DEBUG("\tInvalid value for \"obci_bita\" option\n");
}
/**********************************************************************/
} else if (!strcasecmp(parm->var, "lpa_on_cot")) {
/**********************************************************************/
if (*parm->val == '1') {
sngss7_set_options(&sng_isup, SNGSS7_LPA_FOR_COT);
SS7_DEBUG("\tFound Tx LPA on COT enable option\n");
} else if (*parm->val == '0') {
sngss7_clear_options(&sng_isup, SNGSS7_LPA_FOR_COT);
SS7_DEBUG("\tFound Tx LPA on COT disable option\n");
} else {
SS7_DEBUG("\tInvalid value for \"lpa_on_cot\" option\n");
}
/**********************************************************************/
} else {
SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val);
return FTDM_FAIL;
@@ -850,6 +1293,17 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
parm = parm + 1;
}
/* check if the user filled in a nadi value by looking at flag */
if (!flag_cld_nadi) {
/* default the nadi value to national */
sng_isup.cld_nadi = 0x03;
}
if (!flag_clg_nadi) {
/* default the nadi value to national */
sng_isup.clg_nadi = 0x03;
}
/* trickle down the SPC to all sub entities */
linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].linkSetId;
@@ -1249,7 +1703,9 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup)
g_ftdm_sngss7_data.cfg.isupIntf[i].switchType = sng_isup->switchType;
g_ftdm_sngss7_data.cfg.isupIntf[i].ssf = sng_isup->ssf;
g_ftdm_sngss7_data.cfg.isupIntf[i].isap = sng_isup->isap;
g_ftdm_sngss7_data.cfg.isupIntf[i].cld_nadi = sng_isup->cld_nadi;
g_ftdm_sngss7_data.cfg.isupIntf[i].clg_nadi = sng_isup->clg_nadi;
g_ftdm_sngss7_data.cfg.isupIntf[i].options = sng_isup->options;
if (sng_isup->t4 != 0) {
g_ftdm_sngss7_data.cfg.isupIntf[i].t4 = sng_isup->t4;
} else {
@@ -1544,7 +2000,7 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i
}
/******************************************************************************/
static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl, int isup_id, ftdm_span_t *span)
static int ftmod_ss7_fill_in_circuits(sng_isupCkt_t *isupCkt)
{
sngss7_chan_data_t *ss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
@@ -1555,10 +2011,10 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
count = 1;
while (ch_map[0] != '\0') {
while (isupCkt->ch_map[0] != '\0') {
/* pull out the next timeslot */
if (ftmod_ss7_next_timeslot(ch_map, &timeslot)) {
if (ftmod_ss7_next_timeslot(isupCkt->ch_map, &timeslot)) {
SS7_ERROR("Failed to parse the channel map!\n");
return FTDM_FAIL;
}
@@ -1568,10 +2024,10 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
x = 1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
if ((g_ftdm_sngss7_data.cfg.isupCkt[x].chan == count) &&
(g_ftdm_sngss7_data.cfg.isupCkt[x].span == span->channels[1]->physical_span_id)) {
(g_ftdm_sngss7_data.cfg.isupCkt[x].span == isupCkt->span->channels[1]->physical_span_id)) {
SS7_DEVEL_DEBUG("Circuit for span=%d, chan=%d is already exists...id=%d\n",
span->channels[1]->physical_span_id,
isupCkt->span->channels[1]->physical_span_id,
count,
x);
@@ -1585,7 +2041,7 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
/* check why we exited the while loop */
if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) {
SS7_DEVEL_DEBUG("Circuit for span=%d, chan=%d is new...id=%d\n",
span->channels[1]->physical_span_id,
isupCkt->span->channels[1]->physical_span_id,
count,
x);
@@ -1596,7 +2052,7 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
/* circuit is new so fill in the needed information */
g_ftdm_sngss7_data.cfg.isupCkt[x].id = x;
g_ftdm_sngss7_data.cfg.isupCkt[x].span = span->channels[1]->physical_span_id;
g_ftdm_sngss7_data.cfg.isupCkt[x].span = isupCkt->span->channels[1]->physical_span_id;
g_ftdm_sngss7_data.cfg.isupCkt[x].chan = count;
if (timeslot.siglink) {
g_ftdm_sngss7_data.cfg.isupCkt[x].type = SIG;
@@ -1605,22 +2061,14 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
}
if (timeslot.channel) {
g_ftdm_sngss7_data.cfg.isupCkt[x].cic = cicbase;
cicbase++;
g_ftdm_sngss7_data.cfg.isupCkt[x].cic = isupCkt->cicbase;
isupCkt->cicbase++;
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].cic = 0;
}
g_ftdm_sngss7_data.cfg.isupCkt[x].infId = isup_id;
g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = typeCntrl;
g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200;
g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = 300;
g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = 3000;
g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = 300;
g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = 3000;
g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = 300;
g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = 3000;
g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10;
g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = g_ftdm_sngss7_data.cfg.isupIntf[isup_id].ssf;
g_ftdm_sngss7_data.cfg.isupCkt[x].infId = isupCkt->isupInf;
g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = isupCkt->typeCntrl;
g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = g_ftdm_sngss7_data.cfg.isupIntf[isupCkt->isupInf].ssf;
g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info;
} /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) */
@@ -1631,26 +2079,26 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
} else { /* if ((timeslot.siglink) || (timeslot.gap)) */
/* find the ftdm the channel structure for this channel*/
i = 1;
while (span->channels[i] != NULL) {
if (span->channels[i]->physical_chan_id == timeslot.channel) {
while (isupCkt->span->channels[i] != NULL) {
if (isupCkt->span->channels[i]->physical_chan_id == timeslot.channel) {
break;
}
i++;
} /* while (span->channels[i] != NULL) */
if (span->channels[i] == NULL) {
if (isupCkt->span->channels[i] == NULL) {
/* we weren't able to find the channel in the ftdm channels */
SS7_ERROR("Unable to find the requested channel %d in the FreeTDM channels!\n", timeslot.channel);
return FTDM_FAIL;
} else {
ftdmchan = span->channels[i];
ftdmchan = isupCkt->span->channels[i];
}
/* try to find a match for the physical span and chan */
x = 1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
if ((g_ftdm_sngss7_data.cfg.isupCkt[x].chan == ftdmchan->physical_chan_id)
&& (g_ftdm_sngss7_data.cfg.isupCkt[x].span == ftdmchan->physical_span_id)) {
if ((g_ftdm_sngss7_data.cfg.isupCkt[x].chan == ftdmchan->physical_chan_id) &&
(g_ftdm_sngss7_data.cfg.isupCkt[x].span == ftdmchan->physical_span_id)) {
/* we have a match so this circuit already exists in the structure */
break;
@@ -1673,33 +2121,65 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
ftdmchan->call_data = ss7_info;
/* prepare the timer structures */
ss7_info->t35.sched = ((sngss7_span_data_t *)span->mod_data)->sched;
ss7_info->t35.sched = ((sngss7_span_data_t *)isupCkt->span->mod_data)->sched;
ss7_info->t35.counter = 1;
ss7_info->t35.beat = g_ftdm_sngss7_data.cfg.isupIntf[isup_id].t35*100; /* beat is in ms, t35 is in 100ms */
ss7_info->t35.beat = g_ftdm_sngss7_data.cfg.isupIntf[isupCkt->isupInf].t35*100; /* beat is in ms, t35 is in 100ms */
ss7_info->t35.callback = handle_isup_t35;
ss7_info->t35.sngss7_info = ss7_info;
/* circuit is new so fill in the needed information */
g_ftdm_sngss7_data.cfg.isupCkt[x].id = x;
g_ftdm_sngss7_data.cfg.isupCkt[x].id = x;
g_ftdm_sngss7_data.cfg.isupCkt[x].span = ftdmchan->physical_span_id;
g_ftdm_sngss7_data.cfg.isupCkt[x].chan = ftdmchan->physical_chan_id;
g_ftdm_sngss7_data.cfg.isupCkt[x].type = VOICE;
g_ftdm_sngss7_data.cfg.isupCkt[x].cic = cicbase;
g_ftdm_sngss7_data.cfg.isupCkt[x].infId = isup_id;
g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = typeCntrl;
g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200;
g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = 300;
g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = 3000;
g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = 300;
g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = 3000;
g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = 300;
g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = 3000;
g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10;
g_ftdm_sngss7_data.cfg.isupCkt[x].cic = isupCkt->cicbase;
g_ftdm_sngss7_data.cfg.isupCkt[x].infId = isupCkt->isupInf;
g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = isupCkt->typeCntrl;
if (isupCkt->t3 == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200;
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = isupCkt->t3;
}
if (isupCkt->t12 == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = 300;
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = isupCkt->t12;
}
if (isupCkt->t13 == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = 3000;
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = isupCkt->t13;
}
if (isupCkt->t14 == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = 300;
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = isupCkt->t14;
}
if (isupCkt->t15 == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = 3000;
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = isupCkt->t15;
}
if (isupCkt->t16 == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = 300;
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = isupCkt->t16;
}
if (isupCkt->t17 == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = 3000;
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = isupCkt->t17;
}
if (isupCkt->tval == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10;
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].tval = isupCkt->tval;
}
g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info;
g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = g_ftdm_sngss7_data.cfg.isupIntf[isup_id].ssf;
g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = g_ftdm_sngss7_data.cfg.isupIntf[isupCkt->isupInf].ssf;
/* increment the cicbase */
cicbase++;
isupCkt->cicbase++;
} else { /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) */
SS7_DEBUG("Circuit for span=%d, chan=%d is new...id=%d\n",
ftdmchan->physical_span_id,
@@ -1745,12 +2225,12 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
/******************************************************************************/
static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot)
{
int i;
int x;
int lower;
int upper;
char tmp[5]; /*KONRAD FIX ME*/
char new_ch_map[MAX_CIC_LENGTH];
int i;
int x;
int lower;
int upper;
char tmp[5]; /*KONRAD FIX ME*/
char new_ch_map[MAX_CIC_LENGTH];
memset(&tmp[0], '\0', sizeof(tmp));
memset(&new_ch_map[0], '\0', sizeof(new_ch_map));
@@ -280,6 +280,25 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start
ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_DTMF_DETECT);
dtmf = "hardware";
}
err = sangoma_tdm_get_hw_ec(chan->sockfd, &tdm_api);
if (err > 0) {
ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_HWEC);
}
#ifdef WP_API_FEATURE_HWEC_PERSIST
err = sangoma_tdm_get_hwec_persist_status(chan->sockfd, &tdm_api);
if (err == 0) {
ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE);
}
#else
if (span->trunk_type == FTDM_TRUNK_BRI || span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
ftdm_log(FTDM_LOG_WARNING, "WP_API_FEATURE_HWEC_PERSIST feature is not supported \
with your version of libsangoma, you should update your Wanpipe drivers\n");
}
#endif
}
#ifdef LIBSANGOMA_VERSION
@@ -598,18 +617,33 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
break;
case FTDM_COMMAND_ENABLE_ECHOCANCEL:
{
#ifdef WP_API_FEATURE_EC_CHAN_STAT
err=sangoma_tdm_get_hwec_chan_status(ftdmchan->sockfd, &tdm_api);
if (err > 0) {
/* Hardware echo canceller already enabled */
err = 0;
break;
}
#endif
err=sangoma_tdm_enable_hwec(ftdmchan->sockfd, &tdm_api);
if (err) {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Enable Failed");
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Enable Failed");
return FTDM_FAIL;
}
}
break;
case FTDM_COMMAND_DISABLE_ECHOCANCEL:
{
#ifdef WP_API_FEATURE_EC_CHAN_STAT
err=sangoma_tdm_get_hwec_chan_status(ftdmchan->sockfd, &tdm_api);
if (!err) {
/* Hardware echo canceller already disabled */
break;
}
#endif
err=sangoma_tdm_disable_hwec(ftdmchan->sockfd, &tdm_api);
if (err) {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Disable Failed");
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Disable Failed");
return FTDM_FAIL;
}
}
+5 -3
View File
@@ -170,8 +170,8 @@ static const char *chanpath = NULL;
static const char dahdi_ctlpath[] = "/dev/dahdi/ctl";
static const char dahdi_chanpath[] = "/dev/dahdi/channel";
static const char zt_ctlpath[] = "/dev/ftdm/ctl";
static const char zt_chanpath[] = "/dev/ftdm/channel";
static const char zt_ctlpath[] = "/dev/zap/ctl";
static const char zt_chanpath[] = "/dev/zap/channel";
static ftdm_socket_t CONTROL_FD = ZT_INVALID_SOCKET;
@@ -974,7 +974,7 @@ FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event)
*/
FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
{
uint32_t i, event_id = 0;
uint32_t i, event_id = FTDM_OOB_INVALID;
zt_event_t zt_event_id = 0;
for(i = 1; i <= span->chan_count; i++) {
@@ -1022,6 +1022,8 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
event_id = FTDM_OOB_OFFHOOK;
} else if (span->channels[i]->type == FTDM_CHAN_TYPE_FXO) {
event_id = FTDM_OOB_RING_START;
} else {
event_id = FTDM_OOB_NOOP;
}
}
break;